# 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.59 -> 1.988 # drivers/net/8139too.c 1.48 -> 1.49 # drivers/acpi/include/acglobal.h 1.18 -> 1.19 include/acpi/acglobal.h (moved) # arch/i386/kernel/process.c 1.43 -> 1.44 # arch/sparc/Kconfig 1.7 -> 1.8 # drivers/hotplug/cpqphp_core.c 1.12 -> 1.14 # fs/nfs/read.c 1.29 -> 1.30 # drivers/s390/cio/Makefile 1.6 -> 1.7 # fs/binfmt_flat.c 1.1 -> 1.2 # fs/jfs/inode.c 1.26 -> 1.28 # arch/arm/kernel/irq.c 1.23 -> 1.24 # drivers/usb/media/Makefile 1.8 -> 1.9 # drivers/acorn/scsi/oak.c 1.14 -> 1.15 # drivers/hotplug/ibmphp_pci.c 1.3 -> 1.5 # arch/ppc64/kernel/signal.c 1.22 -> 1.25 # drivers/acpi/include/acpixf.h 1.15 -> 1.16 include/acpi/acpixf.h (moved) # drivers/scsi/megaraid.c 1.30 -> 1.34 # arch/m68k/sun3/Makefile 1.6 -> 1.7 # arch/mips64/mm/Makefile 1.5 -> 1.6 # sound/pci/emu10k1/emu10k1.c 1.8 -> 1.10 # include/linux/isdnif.h 1.12 -> 1.13 # include/asm-alpha/pci.h 1.9 -> 1.10 # drivers/scsi/aic7xxx/aic79xx_core.c 1.6 -> 1.10 # include/linux/acpi.h 1.19 -> 1.22 # arch/arm/mach-sa1100/sa1111-pcibuf.c 1.8 -> 1.9 arch/arm/common/sa1111-pcibuf.c (moved) # arch/sparc64/kernel/signal32.c 1.24 -> 1.26 # drivers/block/paride/Kconfig 1.1 -> 1.2 # include/net/route.h 1.17 -> 1.19 # sound/sound_firmware.c 1.4 -> 1.6 # drivers/pnp/isapnp/Makefile 1.5 -> 1.6 # arch/ppc64/lib/Makefile 1.7 -> 1.8 # arch/um/kernel/tt/syscall_kern.c 1.3 -> 1.4 # arch/mips/baget/time.c 1.2 -> 1.3 # drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped 1.3 -> 1.4 # drivers/usb/media/Kconfig 1.2 -> 1.3 # include/asm-mips64/topology.h 1.2 -> 1.3 # arch/sh/kernel/time.c 1.5 -> 1.6 # arch/ppc/boot/simple/Makefile 1.12 -> 1.13 # drivers/input/joystick/Kconfig 1.1 -> 1.2 # sound/core/seq/oss/seq_oss_midi.c 1.5 -> 1.6 # drivers/scsi/ips.c 1.38 -> 1.43 # drivers/net/pcmcia/Makefile 1.12 -> 1.13 # drivers/pnp/Makefile 1.10 -> 1.11 # drivers/scsi/sim710.scr 1.2 -> (deleted) # include/asm-arm/arch-ebsa110/param.h 1.2 -> 1.3 # include/asm-ia64/topology.h 1.5 -> 1.6 # drivers/scsi/scsi_error.c 1.27 -> 1.33 # fs/sysfs/Makefile 1.3 -> 1.4 # drivers/input/gameport/Makefile 1.4 -> 1.5 # arch/arm/kernel/via82c505.c 1.8 -> 1.9 arch/arm/common/via82c505.c (moved) # Documentation/tipar.txt 1.1 -> 1.2 # drivers/net/skfp/smtdef.c 1.1 -> 1.2 # arch/s390/kernel/time.c 1.10 -> 1.11 # sound/i2c/cs8427.c 1.4 -> 1.5 # sound/core/seq/seq_midi_event.c 1.7 -> 1.8 # drivers/media/video/bt856.c 1.6 -> 1.7 # drivers/acpi/include/acutils.h 1.22 -> 1.23 include/acpi/acutils.h (moved) # arch/ia64/kernel/palinfo.c 1.9 -> 1.10 # crypto/digest.c 1.11 -> 1.12 # arch/um/drivers/daemon_kern.c 1.2 -> 1.3 # sound/pci/emu10k1/emupcm.c 1.9 -> 1.11 # arch/mips/philips/nino/time.c 1.1 -> 1.2 # include/linux/mmzone.h 1.35 -> 1.36 # drivers/scsi/aic7xxx/aic79xx_osm.c 1.11 -> 1.17 # fs/nfsd/nfssvc.c 1.30 -> 1.32 # sound/drivers/opl3/Makefile 1.10 -> 1.11 # net/lapb/Makefile 1.4 -> 1.5 # arch/um/kernel/tt/include/tt.h 1.1 -> 1.2 # arch/um/drivers/mcast_kern.c 1.3 -> 1.4 # include/asm-parisc/bitops.h 1.2 -> 1.3 # include/asm-s390/kmap_types.h 1.3 -> 1.4 # sound/pci/korg1212/korg1212.c 1.14 -> 1.16 # kernel/ksyms.c 1.178 -> 1.181 # drivers/net/e1000/e1000.h 1.22 -> 1.23 # include/asm-ppc64/unistd.h 1.15 -> 1.16 # drivers/char/n_tty.c 1.9 -> 1.10 # drivers/acorn/scsi/Makefile 1.7 -> 1.8 # drivers/sgi/char/Makefile 1.5 -> 1.6 # net/irda/ircomm/Kconfig 1.1 -> 1.2 # arch/mips/Makefile 1.12 -> 1.13 # arch/m68k/math-emu/fp_decode.h 1.2 -> 1.3 # arch/ppc64/kernel/entry.S 1.16 -> 1.19 # drivers/acpi/include/acpiosxf.h 1.18 -> 1.20 include/acpi/acpiosxf.h (moved) # drivers/ieee1394/Kconfig 1.2 -> 1.3 # drivers/mtd/nand/Makefile 1.5 -> 1.6 # crypto/internal.h 1.13 -> 1.14 # include/asm-x86_64/signal.h 1.4 -> 1.5 # arch/um/sys-i386/util/mk_thread_kern.c 1.2 -> 1.3 # drivers/char/ip2/i2ellis.c 1.3 -> 1.4 # net/rxrpc/krxiod.c 1.2 -> 1.3 # mm/fremap.c 1.2 -> 1.3 # drivers/i2c/Makefile 1.7 -> 1.8 # arch/arm/kernel/signal.c 1.18 -> 1.19 # drivers/usb/serial/ipaq.h 1.5 -> 1.6 # arch/um/drivers/chan_user.c 1.4 -> 1.5 # arch/um/sys-i386/sigcontext.c 1.2 -> 1.3 # drivers/input/gameport/Kconfig 1.1 -> 1.2 # sound/ppc/tumbler.c 1.8 -> 1.9 # include/asm-arm/bug.h 1.1 -> 1.2 # arch/arm/mm/proc-arm920.S 1.16 -> 1.17 # drivers/net/tulip/de4x5.c 1.20 -> 1.21 # arch/ia64/ia32/ia32_signal.c 1.10 -> 1.14 # drivers/scsi/pci2220i.c 1.13 -> 1.15 # arch/um/drivers/mconsole_kern.c 1.5 -> 1.6 # include/linux/jiffies.h 1.3 -> 1.5 # Documentation/modules.txt 1.3 -> 1.4 # sound/synth/Makefile 1.11 -> 1.12 # fs/fat/Makefile 1.5 -> 1.6 # drivers/parport/Makefile 1.6 -> 1.7 # arch/i386/kernel/cpu/mtrr/Makefile 1.2 -> 1.3 # fs/xfs/xfs_buf_item.c 1.6 -> 1.7 # fs/lockd/clntproc.c 1.7 -> 1.8 # drivers/char/Kconfig 1.6 -> 1.8 # include/asm-i386/edd.h 1.3 -> 1.4 # drivers/video/Kconfig 1.11 -> 1.12 # Documentation/DocBook/journal-api.tmpl 1.4 -> 1.5 # include/linux/buffer_head.h 1.36 -> 1.37 # drivers/net/e1000/Makefile 1.7 -> 1.8 # drivers/scsi/eata_dma.c 1.7 -> 1.9 # include/asm-arm/arch-sa1100/ide.h 1.5 -> 1.6 # net/ax25/Makefile 1.5 -> 1.6 # drivers/net/appletalk/Makefile 1.4 -> 1.5 # arch/um/kernel/tt/tracer.c 1.2 -> 1.3 # Documentation/sound/alsa/CMIPCI.txt 1.1 -> 1.3 # drivers/net/3c509.c 1.29 -> 1.30 # fs/xfs/pagebuf/page_buf.c 1.35 -> 1.37 # net/sunrpc/auth_gss/gss_krb5_crypto.c 1.1 -> 1.2 # drivers/mtd/devices/blkmtd.c 1.23 -> 1.24 # arch/ia64/Makefile 1.32 -> 1.37 # drivers/atm/Makefile 1.15 -> 1.16 # arch/arm/mach-adifcc/Makefile 1.4 -> 1.5 # drivers/media/video/saa7185.c 1.8 -> 1.9 # fs/freevxfs/vxfs_fshead.c 1.6 -> 1.7 # arch/ia64/kernel/efi.c 1.17 -> 1.19 # drivers/message/i2o/Kconfig 1.1 -> 1.2 # drivers/scsi/53c7,8xx.c 1.14 -> (deleted) # include/linux/mm.h 1.105 -> 1.107 # drivers/acpi/button.c 1.15 -> 1.16 # arch/um/os-Linux/drivers/ethertap_kern.c 1.2 -> 1.3 # fs/jfs/jfs_btree.h 1.3 -> 1.4 # include/asm-generic/vmlinux.lds.h 1.4 -> 1.7 # drivers/scsi/fcal.c 1.8 -> 1.9 # sound/pci/ice1712/ice1712.h 1.5 -> 1.6 # arch/um/kernel/ksyms.c 1.6 -> 1.8 # drivers/scsi/scsiiom.c 1.2 -> 1.3 # drivers/net/skfp/pcmplc.c 1.2 -> 1.3 # Documentation/arm/SA1100/CERF 1.1 -> 1.2 # net/sunrpc/Makefile 1.9 -> 1.10 # drivers/scsi/hosts.c 1.45 -> 1.51 # arch/i386/kernel/apm.c 1.42 -> 1.43 # lib/Makefile 1.17 -> 1.18 # sound/isa/gus/gus_mixer.c 1.5 -> 1.6 # include/sound/gus.h 1.2 -> 1.3 # arch/ppc/Makefile 1.34 -> 1.36 # fs/devfs/Makefile 1.4 -> 1.5 # net/Kconfig 1.6 -> 1.7 # arch/um/drivers/xterm.c 1.4.1.1 -> 1.11 # arch/ppc/lib/Makefile 1.10 -> 1.11 # net/sctp/input.c 1.14 -> 1.15 # drivers/net/skfp/skfddi.c 1.9 -> 1.10 # sound/core/hwdep.c 1.7 -> 1.10 # sound/core/memory.c 1.15 -> 1.16 # include/asm-um/processor-i386.h 1.1 -> 1.2 # include/asm-i386/pgalloc.h 1.18 -> 1.19 # fs/proc/Makefile 1.5 -> 1.6 # drivers/scsi/cpqfcTSinit.c 1.25.1.1 -> 1.30 # drivers/usb/class/Kconfig 1.5 -> 1.6 # drivers/scsi/aic7xxx/aic7xxx_pci.c 1.8 -> 1.9 # drivers/acpi/toshiba_acpi.c 1.4 -> 1.5 # arch/um/drivers/port_kern.c 1.7.1.1 -> 1.15 # fs/xfs/xfs_trans_buf.c 1.5 -> 1.6 # drivers/acpi/fan.c 1.9 -> 1.10 # net/irda/ircomm/Makefile 1.6 -> 1.7 # drivers/input/serio/Makefile 1.6 -> 1.7 # arch/um/kernel/trap_kern.c 1.5 -> 1.7 # drivers/scsi/aic7xxx/aiclib.h 1.4 -> 1.5 # sound/core/oss/Makefile 1.5 -> 1.6 # drivers/net/hamradio/Kconfig 1.2 -> 1.3 # arch/um/kernel/skas/sys-i386/sigcontext.c 1.1 -> 1.2 # fs/nfs/mount_clnt.c 1.6 -> 1.7 # arch/ppc/syslib/Makefile 1.3 -> 1.4 # drivers/net/pcmcia/aironet4500_cs.c 1.11 -> 1.12 # arch/um/kernel/tt/tlb.c 1.3 -> 1.4 # arch/i386/kernel/irq.c 1.24 -> 1.25 # mm/page_alloc.c 1.145 -> 1.148 # mm/readahead.c 1.26 -> 1.28 # fs/ext2/inode.c 1.60 -> 1.61 # drivers/scsi/aic7xxx/aic7xxx_osm.c 1.11 -> 1.16 # drivers/acpi/include/acexcep.h 1.12 -> 1.13 include/acpi/acexcep.h (moved) # drivers/scsi/scsi_proc.c 1.12 -> 1.16 # fs/jfs/jfs_inode.c 1.5 -> 1.6 # include/asm-ppc64/processor.h 1.22 -> 1.23 # sound/core/seq/oss/seq_oss_init.c 1.4 -> 1.5 # include/asm-um/current.h 1.1 -> 1.3 # include/linux/times.h 1.2 -> 1.3 # arch/ia64/ia32/ia32_support.c 1.5 -> 1.6 # arch/alpha/kernel/alpha_ksyms.c 1.30 -> 1.31 # sound/pci/cs46xx/cs46xx_lib.c 1.19 -> 1.23 # drivers/video/vesafb.c 1.28 -> 1.29 # include/asm-ia64/spinlock.h 1.5 -> 1.6 # include/asm-ppc/signal.h 1.4 -> 1.5 # drivers/net/hamradio/Makefile 1.6 -> 1.7 # include/linux/ext3_jbd.h 1.7 -> 1.8 # drivers/usb/host/ohci-hcd.c 1.35 -> 1.36 # arch/sparc/kernel/sparc_ksyms.c 1.12 -> 1.13 # fs/ext3/Makefile 1.7 -> 1.8 # fs/lockd/Makefile 1.3 -> 1.4 # arch/arm/mach-shark/Makefile 1.7 -> 1.8 # drivers/char/drm/i830_dma.c 1.9 -> 1.10 # arch/alpha/kernel/core_marvel.c 1.4 -> 1.6 # Documentation/sound/alsa/ALSA-Configuration.txt 1.1 -> 1.3 # drivers/acorn/scsi/cumana_1.c 1.13 -> 1.14 # drivers/net/pcmcia/nmclan_cs.c 1.9 -> 1.10 # sound/drivers/opl3/opl3_oss.c 1.4 -> 1.5 # drivers/acpi/include/acstruct.h 1.12 -> 1.13 include/acpi/acstruct.h (moved) # drivers/usb/image/Kconfig 1.2 -> 1.3 # sound/isa/gus/gus_main.c 1.7 -> 1.8 # include/linux/init_task.h 1.20 -> 1.21 # drivers/net/tokenring/tmsisa.c 1.6 -> 1.7 # arch/um/drivers/null.c 1.2 -> 1.3 # sound/drivers/serial-u16550.c 1.11 -> 1.12 # include/asm-generic/topology.h 1.3 -> 1.4 # include/linux/sched.h 1.121 -> 1.127 # kernel/fork.c 1.100 -> 1.104 # include/linux/ptrace.h 1.5 -> 1.7 # drivers/net/Space.c 1.15 -> 1.16 # drivers/block/ll_rw_blk.c 1.147 -> 1.149 # arch/i386/kernel/vm86.c 1.18 -> 1.19 # fs/jffs2/os-linux.h 1.8 -> 1.9 # kernel/sys.c 1.38 -> 1.40 # drivers/input/Kconfig 1.3 -> 1.4 # Makefile 1.357 -> 1.369 # sound/pci/cmipci.c 1.16 -> 1.19 # arch/um/drivers/slirp_user.c 1.1 -> 1.2 # drivers/net/wireless/airo.c 1.30 -> 1.31 # arch/um/include/sysdep-i386/frame.h 1.1 -> 1.2 # drivers/video/Makefile 1.70 -> 1.71 # drivers/acpi/include/acnamesp.h 1.16 -> 1.17 include/acpi/acnamesp.h (moved) # include/asm-ia64/unistd.h 1.22 -> 1.23 # net/wanrouter/Makefile 1.5 -> 1.6 # arch/i386/mach-voyager/Makefile 1.2 -> 1.3 # include/asm-ppc64/thread_info.h 1.6 -> 1.7 # drivers/md/Kconfig 1.1 -> 1.2 # drivers/media/video/bt819.c 1.5 -> 1.6 # drivers/net/wan/lmc/lmc_ioctl.h 1.2 -> 1.3 # include/asm-ia64/mmu_context.h 1.10 -> 1.12 # include/net/tcp.h 1.27 -> 1.29 # drivers/acpi/include/acresrc.h 1.10 -> 1.11 include/acpi/acresrc.h (moved) # drivers/acpi/hardware/hwtimer.c 1.11 -> 1.12 # drivers/acpi/include/acobject.h 1.15 -> 1.16 include/acpi/acobject.h (moved) # arch/um/os-Linux/process.c 1.4 -> 1.5 # net/rxrpc/krxtimod.c 1.2 -> 1.3 # fs/befs/ChangeLog 1.1 -> 1.2 # drivers/s390/net/lcs.c 1.8 -> 1.9 # sound/isa/cs423x/cs4236.c 1.11 -> 1.12 # drivers/char/ftape/Kconfig 1.1 -> 1.2 # sound/core/seq/seq_clientmgr.c 1.12 -> 1.14 # include/asm-ia64/signal.h 1.7 -> 1.8 # drivers/net/lasi_82596.c 1.16 -> 1.17 # drivers/ieee1394/sbp2.c 1.20 -> 1.22 # arch/um/include/user_util.h 1.9 -> 1.11 # fs/dcache.c 1.37 -> 1.38 # sound/pci/ac97/ak4531_codec.c 1.3 -> 1.5 # mm/vmscan.c 1.143 -> 1.146 # arch/ia64/kernel/setup.c 1.34 -> 1.36 # net/atm/Makefile 1.6 -> 1.7 # sound/oss/ac97_codec.c 1.12 -> 1.13 # arch/um/kernel/tt/gdb.c 1.2 -> 1.5 # sound/pci/rme9652/hammerfall_mem.c 1.9 -> 1.11 # arch/um/drivers/mmapper_kern.c 1.2 -> 1.3 # fs/proc/proc_misc.c 1.62 -> 1.64 # arch/um/kernel/ptrace.c 1.5.1.1 -> 1.11 # sound/core/ioctl32/ioctl32.c 1.13 -> 1.16 # drivers/s390/char/sclp_tty.c 1.3 -> 1.4 # arch/ppc64/Makefile 1.21 -> 1.22 # sound/isa/cmi8330.c 1.8 -> 1.12 # arch/sparc/Makefile 1.17 -> 1.19 # arch/ia64/sn/kernel/Makefile 1.9 -> 1.10 # drivers/block/cpqarray.c 1.68 -> 1.69 # arch/um/kernel/skas/include/ptrace-skas.h 1.1 -> 1.2 # drivers/acorn/scsi/scsi.h 1.2 -> 1.3 # arch/um/include/sysdep-i386/syscalls.h 1.1 -> 1.2 # arch/x86_64/kernel/apic.c 1.8 -> 1.9 # drivers/acpi/include/amlresrc.h 1.6 -> (deleted) # drivers/acpi/include/actbl1.h 1.9 -> 1.10 include/acpi/actbl1.h (moved) # drivers/i2c/i2c-core.c 1.14 -> 1.15 # sound/isa/gus/gus_reset.c 1.3 -> 1.4 # arch/ia64/hp/common/sba_iommu.c 1.9 -> 1.10 # fs/xfs/xfs_dquot_item.c 1.1 -> 1.2 # drivers/net/wan/lmc/lmc_ver.h 1.2 -> 1.3 # arch/i386/Kconfig 1.34 -> 1.36 # include/asm-parisc/module.h 1.2 -> 1.3 # sound/core/rawmidi.c 1.19 -> 1.22 # drivers/block/floppy.c 1.65 -> 1.67 # drivers/media/dvb/frontends/Kconfig 1.2 -> 1.3 # drivers/sbus/char/aurora.c 1.17 -> 1.18 # arch/ia64/kernel/ivt.S 1.11 -> 1.13 # arch/um/util/mk_task_kern.c 1.1 -> 1.2 # drivers/base/node.c 1.7 -> 1.8 # drivers/parisc/Makefile 1.2 -> 1.3 # include/linux/elf.h 1.17 -> 1.18 # drivers/scsi/53c700.c 1.22 -> 1.24 # sound/core/control.c 1.15 -> 1.18 # drivers/net/tokenring/Makefile 1.7 -> 1.8 # drivers/usb/serial/Makefile 1.16 -> 1.17 # drivers/hotplug/ibmphp_ebda.c 1.7 -> 1.9 # arch/um/include/sysdep-i386/ptrace.h 1.2 -> 1.5 # net/bridge/br.c 1.8 -> 1.9 # net/ipv4/netfilter/ip_nat_helper.c 1.9 -> 1.10 # drivers/acpi/include/acdebug.h 1.15 -> 1.17 include/acpi/acdebug.h (moved) # arch/um/sys-i386/Makefile 1.8.1.1 -> 1.15 # fs/jfs/jfs_imap.c 1.18 -> 1.19 # arch/x86_64/lib/Makefile 1.9 -> 1.10 # sound/isa/opti9xx/opti92x-ad1848.c 1.9 -> 1.10 # fs/jbd/journal.c 1.23 -> 1.25 # include/asm-sparc64/unistd.h 1.18 -> 1.19 # include/asm-i386/signal.h 1.4 -> 1.5 # Documentation/isdn/HiSax.cert 1.2 -> 1.3 # include/asm-i386/topology.h 1.4 -> 1.5 # arch/i386/kernel/traps.c 1.42 -> 1.43 # net/bluetooth/Makefile 1.12 -> 1.13 # arch/um/kernel/user_util.c 1.3 -> 1.6 # drivers/net/hamradio/6pack.c 1.9 -> 1.10 # arch/alpha/kernel/setup.c 1.27 -> 1.30 # drivers/parisc/ccio-dma.c 1.8 -> 1.10 # drivers/scsi/g_NCR5380.c 1.12 -> 1.13 # arch/i386/kernel/Makefile 1.32 -> 1.33 # fs/nls/Makefile 1.6 -> 1.7 # include/asm-m68k/signal.h 1.3 -> 1.4 # include/asm-mips/isadep.h 1.2 -> 1.3 # include/linux/signal.h 1.6 -> 1.7 # sound/core/init.c 1.11 -> 1.15 # fs/stat.c 1.16 -> 1.17 # include/asm-um/processor-generic.h 1.4 -> 1.6 # drivers/usb/Kconfig 1.1 -> 1.2 # arch/arm/mach-sa1100/leds.c 1.9 -> 1.10 # drivers/video/skeletonfb.c 1.20 -> 1.22 # drivers/net/tg3.h 1.20 -> 1.23 # arch/sparc64/kernel/Makefile 1.18 -> 1.19 # drivers/isdn/hisax/isdnl2.c 1.10 -> 1.11 # arch/s390/Makefile 1.20 -> 1.22 # arch/i386/kernel/acpi_wakeup.S 1.10 -> 1.11 # arch/arm/mach-arc/Makefile 1.5 -> 1.6 # arch/um/include/time_user.h 1.3 -> 1.4 # fs/xfs/xfs_vfsops.c 1.23 -> 1.24 # drivers/scsi/scsi_sysfs.c 1.5 -> 1.6 # arch/mips64/mips-boards/generic/time.c 1.3 -> 1.4 # fs/autofs/waitq.c 1.5 -> 1.7 # arch/um/include/sysdep-i386/frame_kern.h 1.2 -> 1.3 # net/irda/irlan/Kconfig 1.1 -> 1.2 # kernel/Makefile 1.25 -> 1.26 # arch/um/kernel/time.c 1.4 -> 1.6 # Documentation/kbuild/00-INDEX 1.2 -> 1.3 # drivers/telephony/Kconfig 1.1 -> 1.2 # Documentation/kbuild/bug-list.txt 1.1 -> (deleted) # fs/ioctl.c 1.7 -> 1.8 # net/sctp/Kconfig 1.1 -> 1.2 # arch/alpha/kernel/proto.h 1.10 -> 1.13 # arch/parisc/kernel/entry.S 1.8 -> 1.9 # arch/parisc/kernel/signal32.c 1.2 -> 1.3 # security/dummy.c 1.14 -> 1.19 # drivers/i2c/Kconfig 1.3 -> 1.5 # sound/core/seq/seq_device.c 1.7 -> 1.9 # sound/isa/cs423x/cs4231_lib.c 1.10 -> 1.12 # arch/cris/drivers/Kconfig 1.1 -> 1.2 # arch/ia64/kernel/time.c 1.11 -> 1.13 # include/sound/pcm_params.h 1.5 -> 1.6 # sound/oss/dmasound/Makefile 1.5 -> 1.6 # arch/um/include/os.h 1.2 -> 1.3 # arch/arm/kernel/plx90x0.c 1.4 -> 1.5 arch/arm/common/plx90x0.c (moved) # include/linux/xfrm.h 1.2 -> 1.3 # include/asm-sparc/kmap_types.h 1.11 -> 1.12 # drivers/acpi/include/platform/acenv.h 1.13 -> 1.14 include/acpi/platform/acenv.h (moved) # drivers/isdn/hisax/l3ni1.c 1.8 -> 1.9 # net/ipv4/netfilter/Makefile 1.16 -> 1.17 # drivers/scsi/aacraid/aacraid.h 1.3 -> 1.4 # include/linux/blkdev.h 1.94 -> 1.97 # kernel/time.c 1.8 -> 1.9 # drivers/block/Kconfig 1.1 -> 1.2 # drivers/acpi/tables/tbinstal.c 1.15 -> 1.16 # arch/um/kernel/smp.c 1.5 -> 1.6 # drivers/block/nbd.c 1.47 -> 1.49 # drivers/usb/serial/safe_serial.c 1.12 -> 1.13 # drivers/input/joystick/iforce/Kconfig 1.1 -> 1.2 # include/asm-ia64/sn/sv.h 1.2 -> 1.3 # drivers/char/rio/cmdpkt.h 1.1 -> 1.2 # drivers/parisc/ccio-rm-dma.c 1.5 -> 1.6 # drivers/video/console/Kconfig 1.15 -> 1.16 # drivers/scsi/ips.h 1.18 -> 1.22 # drivers/net/e1000/e1000_osdep.h 1.9 -> 1.10 # net/rxrpc/krxsecd.c 1.3 -> 1.4 # sound/pci/ice1712/ews.c 1.6 -> 1.7 # drivers/net/pcmcia/3c574_cs.c 1.12 -> 1.13 # net/ipv4/devinet.c 1.11 -> 1.12 # include/asm-ia64/asmmacro.h 1.3 -> 1.9 # drivers/net/rrunner.c 1.12 -> 1.13 # include/asm-ppc64/compat.h 1.5 -> 1.6 # fs/mpage.c 1.37 -> 1.39 # arch/ppc64/kernel/init_task.c 1.3 -> 1.4 # drivers/usb/core/message.c 1.18 -> 1.20 # include/asm-sparc/smp.h 1.4 -> 1.5 # drivers/net/wireless/Kconfig 1.2 -> 1.3 # arch/ia64/kernel/smpboot.c 1.24 -> 1.27 # drivers/scsi/NCR5380.c 1.11 -> 1.13 # arch/um/drivers/stdio_console.c 1.6 -> 1.7 # arch/m68k/kernel/time.c 1.5 -> 1.6 # drivers/mtd/maps/sa1100-flash.c 1.4 -> 1.5 # drivers/char/ftape/lowlevel/fdc-io.c 1.6 -> 1.7 # drivers/net/wan/Kconfig 1.2 -> 1.3 # arch/ia64/sn/io/Makefile 1.8 -> 1.9 # arch/arm/mach-tbox/Makefile 1.4 -> 1.5 # arch/um/kernel/tt/include/mode_kern.h 1.3 -> 1.5 # arch/um/kernel/skas/process_kern.c 1.2 -> 1.3 # drivers/media/Kconfig 1.2 -> 1.3 # drivers/net/wan/dscc4.c 1.31 -> 1.32 # kernel/suspend.c 1.30 -> 1.33 # drivers/scsi/scsi.h 1.54 -> 1.60 # include/linux/gfp.h 1.10 -> 1.11 # include/asm-sparc64/signal.h 1.4 -> 1.6 # arch/v850/kernel/rte_mb_a_pci.c 1.2 -> 1.3 # fs/jfs/jfs_metapage.c 1.21 -> 1.22 # include/linux/fs.h 1.213 -> 1.217 # drivers/video/sa1100fb.c 1.23 -> 1.24 # drivers/usb/misc/atmsar.c 1.3 -> 1.6 # arch/ia64/kernel/entry.S 1.29 -> 1.30 # drivers/usb/storage/usb.c 1.51 -> 1.56 # arch/i386/mm/Makefile 1.8 -> 1.9 # drivers/scsi/ini9100u.c 1.10 -> 1.12 # drivers/atm/lanai.c 1.6 -> 1.7 # fs/jfs/jfs_mount.c 1.12 -> 1.13 # arch/mips64/Makefile 1.14 -> 1.15 # fs/jfs/jfs_debug.h 1.4 -> 1.5 # arch/ia64/dig/setup.c 1.6 -> 1.7 # include/asm-alpha/topology.h 1.4 -> 1.6 # drivers/tc/Makefile 1.7 -> 1.8 # include/sound/emu10k1.h 1.9 -> 1.11 # arch/i386/kernel/entry.S 1.53 -> 1.54 # drivers/net/tokenring/Kconfig 1.3 -> 1.4 # Documentation/networking/bonding.txt 1.5 -> 1.6 # drivers/mtd/chips/Makefile 1.5 -> 1.6 # drivers/video/matrox/Makefile 1.7 -> 1.8 # net/rxrpc/internal.h 1.2 -> 1.3 # sound/core/seq/seq_queue.h 1.8 -> 1.9 # include/sound/ak4531_codec.h 1.1 -> 1.2 # include/asm-m68k/mac_psc.h 1.2 -> 1.3 # drivers/net/skfp/ecm.c 1.1 -> 1.2 # drivers/usb/image/scanner.c 1.45 -> 1.48 # arch/ppc64/defconfig 1.22 -> 1.24 # include/asm-arm/arch-ebsa110/time.h 1.5 -> 1.6 # include/asm-i386/node.h 1.2 -> 1.3 # drivers/isdn/eicon/eicon.h 1.9 -> 1.10 # arch/ia64/mm/extable.c 1.4 -> 1.6 # drivers/char/n_hdlc.c 1.9 -> 1.10 # Documentation/scsi/aic7xxx.txt 1.5 -> 1.6 # include/linux/crypto.h 1.24 -> 1.25 # Documentation/sparc/sbus_drivers.txt 1.1 -> 1.2 # arch/m68knommu/kernel/Makefile 1.3 -> 1.4 # Documentation/filesystems/proc.txt 1.11 -> 1.12 # drivers/acpi/include/actables.h 1.13 -> 1.14 include/acpi/actables.h (moved) # include/asm-arm/mach/irq.h 1.5 -> 1.6 # net/ipv6/netfilter/ip6_queue.c 1.4 -> 1.5 # sound/core/oss/pcm_plugin.c 1.4 -> 1.5 # arch/alpha/kernel/smp.c 1.30 -> 1.31 # net/irda/iriap.c 1.11 -> 1.12 # include/net/xfrm.h 1.11 -> 1.12 # drivers/net/Makefile 1.51 -> 1.53 # sound/oss/Makefile 1.20 -> 1.21 # kernel/timer.c 1.38 -> 1.40 # sound/pci/via82xx.c 1.20 -> 1.24 # drivers/net/wireless/airo_cs.c 1.5 -> 1.6 # arch/ppc/platforms/pmac_time.c 1.10 -> 1.11 # include/asm-sparc/delay.h 1.1 -> 1.2 # arch/alpha/kernel/core_titan.c 1.12 -> 1.13 # drivers/md/md.c 1.133 -> 1.134 # arch/mips64/Kconfig 1.8 -> 1.9 # arch/x86_64/ia32/Makefile 1.10 -> 1.11 # drivers/scsi/ncr53c8xx.c 1.19 -> 1.20 # sound/Makefile 1.14 -> 1.15 # arch/um/kernel/skas/include/skas.h 1.2 -> 1.3 # drivers/scsi/advansys.c 1.23 -> 1.26 # drivers/net/e100/e100.h 1.20 -> 1.21 # drivers/char/ftape/lowlevel/Makefile 1.6 -> 1.7 # drivers/scsi/inia100.c 1.16 -> 1.18 # kernel/kmod.c 1.18 -> 1.20 # drivers/net/wireless/orinoco.h 1.10 -> 1.11 # arch/ppc/ocp/Makefile 1.1 -> 1.2 # fs/jbd/transaction.c 1.23 -> 1.25 # sound/usb/usbmixer.c 1.10 -> 1.11 # fs/exportfs/Makefile 1.3 -> 1.4 # Documentation/usb/hiddev.txt 1.3 -> 1.4 # drivers/scsi/u14-34f.c 1.19 -> 1.22 # arch/ppc64/kernel/rtasd.c 1.7 -> 1.8 # arch/parisc/kernel/Makefile 1.8 -> 1.9 # include/sound/sndmagic.h 1.8 -> 1.10 # sound/isa/cs423x/cs4236_lib.c 1.4 -> 1.5 # arch/um/drivers/harddog_user.c 1.1 -> 1.2 # include/asm-ia64/uaccess.h 1.5 -> 1.8 # drivers/scsi/hosts.h 1.48 -> 1.52 # drivers/char/agp/Makefile 1.14 -> 1.15 # arch/mips/dec/Makefile 1.8 -> 1.9 # include/sound/cs46xx.h 1.10 -> 1.11 # arch/um/kernel/tt/uaccess_user.c 1.2 -> 1.3 # drivers/net/wan/lmc/lmc_main.c 1.10 -> 1.11 # drivers/base/cpu.c 1.5 -> 1.6 # drivers/isdn/i4l/Makefile 1.12 -> 1.13 # include/sound/ad1848.h 1.2 -> 1.4 # arch/cris/kernel/ptrace.c 1.9 -> 1.10 # drivers/zorro/Makefile 1.8 -> 1.9 # drivers/isdn/eicon/Makefile 1.6 -> 1.7 # net/ipv4/tcp_ipv4.c 1.40 -> 1.43 # fs/reiserfs/inode.c 1.71 -> 1.72 # include/asm-mips/signal.h 1.1 -> 1.2 # arch/i386/kernel/io_apic.c 1.40 -> 1.41 # drivers/hotplug/acpiphp_glue.c 1.4 -> 1.5 # drivers/usb/core/hcd.h 1.22 -> 1.23 # include/asm-sparc64/elf.h 1.12 -> 1.13 # fs/char_dev.c 1.6 -> 1.7 # include/asm-v850/pci.h 1.1 -> 1.2 # arch/parisc/kernel/sys_parisc32.c 1.5 -> 1.7 # include/asm-arm/io.h 1.14 -> 1.15 # sound/core/pcm_native.c 1.22 -> 1.26 # drivers/usb/media/vicam.c 1.29 -> 1.30 # sound/isa/ad1848/Makefile 1.7 -> 1.8 # sound/pci/ice1712/ice1712.c 1.6 -> 1.8 # sound/pci/rme9652/hdsp.c 1.10 -> 1.13 # include/asm-alpha/core_irongate.h 1.3 -> 1.4 # mm/filemap.c 1.173 -> 1.176 # arch/i386/kernel/edd.c 1.10.1.2 -> 1.15 # drivers/scsi/aic7xxx/Kconfig.aic7xxx 1.8 -> 1.9 # drivers/scsi/pluto.c 1.8 -> 1.9 # drivers/acpi/acpi_ksyms.c 1.19 -> 1.20 # sound/synth/emux/emux_oss.c 1.4 -> 1.5 # fs/namei.c 1.63 -> 1.64 # arch/um/kernel/frame.c 1.3 -> 1.5 # sound/isa/sb/emu8000.c 1.8 -> 1.9 # net/decnet/dn_nsp_in.c 1.6 -> 1.7 # arch/um/include/umid.h 1.1 -> 1.2 # arch/um/kernel/skas/mem_user.c 1.1 -> 1.2 # arch/mips/au1000/common/time.c 1.2 -> 1.3 # drivers/hotplug/cpqphp_ctrl.c 1.6 -> 1.8 # drivers/pci/pci.h 1.1 -> 1.2 # arch/i386/Makefile 1.41 -> 1.43 # net/socket.c 1.41 -> 1.42 # include/asm-ia64/processor.h 1.29 -> 1.30 # sound/pci/Kconfig 1.2 -> 1.4 # arch/um/include/frame.h 1.2 -> 1.3 # sound/pci/emu10k1/emuproc.c 1.6 -> 1.7 # Documentation/usb/silverlink.txt 1.1 -> 1.2 # drivers/char/synclink.c 1.23 -> 1.24 # drivers/acpi/include/acoutput.h 1.13 -> 1.14 include/acpi/acoutput.h (moved) # sound/pci/rme96.c 1.13 -> 1.15 # security/capability.c 1.11 -> 1.14 # arch/um/include/kern_util.h 1.6 -> 1.7 # arch/sparc/kernel/sys_sparc.c 1.7 -> 1.8 # drivers/scsi/aic7xxx/aic7xxx_osm.h 1.23 -> 1.28 # drivers/media/video/Makefile 1.16 -> 1.17 # arch/um/drivers/tty.c 1.2 -> 1.3 # drivers/isdn/sc/Kconfig 1.1 -> 1.2 # fs/ncpfs/sock.c 1.12 -> 1.13 # drivers/net/e1000/e1000_main.c 1.43 -> 1.46 # arch/arm/Makefile 1.32 -> 1.35 # arch/mips64/sgi-ip27/ip27-timer.c 1.4 -> 1.5 # include/sound/version.h 1.43 -> 1.50 # sound/pci/ac97/ac97_codec.c 1.22 -> 1.26 # drivers/hotplug/pci_hotplug.h 1.4 -> 1.7 # drivers/scsi/53c8xx_d.h_shipped 1.2 -> (deleted) # include/linux/sysfs.h 1.22 -> 1.23 # include/asm-sparc64/ide.h 1.13 -> 1.14 # sound/drivers/mpu401/mpu401_uart.c 1.10 -> 1.12 # fs/partitions/ldm.c 1.10 -> 1.11 # drivers/fc4/Kconfig 1.1 -> 1.2 # arch/i386/kernel/dmi_scan.c 1.25 -> 1.26 # fs/exec.c 1.63 -> 1.69 # init/do_mounts.c 1.33 -> 1.34 # fs/ext2/balloc.c 1.24 -> 1.26 # arch/mips64/kernel/Makefile 1.7 -> 1.8 # drivers/mtd/mtdblock.c 1.35 -> 1.36 # drivers/scsi/nsp32.c 1.4 -> 1.6 # fs/binfmt_som.c 1.2 -> 1.3 # drivers/net/e100/e100_proc.c 1.12 -> (deleted) # sound/core/seq/seq_instr.c 1.3 -> 1.4 # drivers/char/rio/riotty.c 1.3 -> 1.4 # drivers/acorn/scsi/fas216.c 1.12 -> 1.14 # include/asm-parisc/dma-mapping.h 1.2 -> 1.3 # net/sunrpc/clnt.c 1.29 -> 1.30 # drivers/usb/storage/transport.c 1.61 -> 1.62 # sound/pci/ice1712/Makefile 1.3 -> 1.4 # drivers/scsi/aacraid/linit.c 1.7 -> 1.8 # arch/alpha/kernel/sys_nautilus.c 1.9 -> 1.10 # include/asm-v850/signal.h 1.1 -> 1.2 # arch/ia64/kernel/perfmon_generic.h 1.1 -> 1.3 # drivers/net/pcmcia/xirc2ps_cs.c 1.12 -> 1.13 # drivers/net/pcmcia/ray_cs.c 1.13 -> 1.14 # drivers/char/ftape/zftape/zftape-init.c 1.15 -> 1.16 # sound/isa/wavefront/wavefront_synth.c 1.9 -> 1.11 # fs/eventpoll.c 1.12 -> 1.13 # arch/s390x/kernel/Makefile 1.14 -> 1.15 # drivers/s390/net/Makefile 1.9 -> 1.10 # Documentation/filesystems/ext3.txt 1.1 -> 1.2 # arch/ia64/kernel/entry.h 1.4 -> 1.5 # arch/parisc/kernel/irq.c 1.8 -> 1.10 # arch/um/drivers/slip_kern.c 1.3 -> 1.4 # drivers/char/nvram.c 1.15 -> 1.16 # drivers/acpi/tables.c 1.10 -> 1.11 # arch/ia64/kernel/irq_ia64.c 1.10 -> 1.11 # drivers/isdn/hisax/Makefile 1.21 -> 1.22 # drivers/usb/image/scanner.h 1.26 -> 1.28 # drivers/usb/storage/transport.h 1.18 -> 1.19 # drivers/serial/uart00.c 1.10 -> 1.11 # arch/m68k/mac/via.c 1.3 -> 1.4 # kernel/signal.c 1.57 -> 1.65 # arch/um/drivers/daemon_user.c 1.1 -> 1.3 # arch/sh/kernel/io.c 1.2 -> 1.3 # arch/parisc/kernel/time.c 1.4 -> 1.5 # arch/um/kernel/mem.c 1.7.2.1 -> 1.12 # drivers/acpi/acpi_bus.h 1.12 -> 1.14 include/acpi/acpi_bus.h (moved) # drivers/message/fusion/mptscsih.c 1.16 -> 1.18 # drivers/char/rtc.c 1.19 -> 1.21 # sound/pci/emu10k1/Makefile 1.5 -> 1.8 # arch/m68k/sun3x/Makefile 1.5 -> 1.6 # drivers/char/keyboard.c 1.23 -> 1.24 # drivers/scsi/atp870u.c 1.15 -> 1.17 # scripts/Makefile.modver 1.6 -> 1.11 # fs/afs/internal.h 1.2 -> 1.3 # drivers/bluetooth/Kconfig 1.1 -> 1.2 # drivers/scsi/sim710_d.h_shipped 1.3 -> (deleted) # drivers/scsi/aic7xxx/scsi_iu.h 1.1 -> 1.2 # net/netsyms.c 1.44 -> 1.46 # drivers/usb/serial/usb-serial.c 1.69 -> 1.70 # include/linux/pci_ids.h 1.78 -> 1.80 # drivers/acpi/scan.c 1.13 -> 1.14 # drivers/isdn/hisax/l3dss1.c 1.8 -> 1.9 # sound/synth/emux/emux_seq.c 1.5 -> 1.7 # drivers/scsi/aic7xxx_old.c 1.38 -> 1.42 # fs/partitions/Makefile 1.9 -> 1.10 # net/802/Makefile 1.10 -> 1.11 # sound/core/seq/oss/Makefile 1.7 -> 1.8 # sound/core/pcm_lib.c 1.12 -> 1.15 # arch/sparc/kernel/sys_sunos.c 1.20 -> 1.22 # drivers/hotplug/Kconfig 1.5 -> 1.6 # drivers/sbus/char/bbc_envctrl.c 1.2 -> 1.3 # arch/mips/ite-boards/generic/time.c 1.3 -> 1.4 # sound/pci/trident/trident_synth.c 1.3 -> 1.4 # include/asm-ia64/system.h 1.28 -> 1.31 # drivers/acpi/ac.c 1.12 -> 1.13 # include/asm-ppc/system.h 1.15 -> 1.16 # sound/core/ioctl32/ioctl32.h 1.7 -> 1.8 # include/asm-ia64/tlb.h 1.12 -> 1.13 # sound/isa/sb/Makefile 1.10 -> 1.13 # arch/mips/kernel/Makefile 1.9 -> 1.10 # sound/usb/usbquirks.h 1.7 -> 1.10 # sound/isa/es18xx.c 1.11 -> 1.13 # arch/arm/kernel/traps.c 1.21 -> 1.22 # arch/um/include/mconsole.h 1.2 -> 1.3 # sound/isa/gus/gus_pcm.c 1.6 -> 1.7 # include/asm-ppc64/signal.h 1.2 -> 1.3 # drivers/isdn/hysdn/hysdn_boot.c 1.5 -> 1.6 # arch/alpha/kernel/Makefile 1.21 -> 1.23 # drivers/char/agp/agp.h 1.37 -> 1.38 # arch/ia64/mm/init.c 1.30 -> 1.32 # drivers/acpi/utilities/utcopy.c 1.19 -> 1.20 # net/Makefile 1.18 -> 1.19 # arch/ppc/amiga/Makefile 1.8 -> 1.9 # arch/sparc64/kernel/systbls.S 1.28 -> 1.29 # sound/isa/ad1816a/Makefile 1.4 -> 1.5 # drivers/mtd/Makefile 1.9 -> 1.10 # arch/um/kernel/skas/include/uaccess.h 1.4 -> 1.5 # drivers/input/misc/Kconfig 1.2 -> 1.3 # arch/um/kernel/tt/mem.c 1.1 -> 1.2 # Documentation/networking/ip-sysctl.txt 1.13 -> 1.14 # sound/isa/gus/gus_mem.c 1.3 -> 1.5 # include/linux/usb.h 1.67 -> 1.68 # arch/um/kernel/irq_user.c 1.7 -> 1.9 # drivers/net/sis900.c 1.29 -> 1.30 # sound/isa/sb/sb_mixer.c 1.7 -> 1.9 # drivers/hotplug/cpci_hotplug_core.c 1.2 -> 1.3 # arch/um/kernel/skas/trap_user.c 1.2 -> 1.4 # arch/mips/kernel/time.c 1.6 -> 1.7 # arch/ia64/hp/zx1/hpzx1_misc.c 1.12 -> 1.13 # drivers/scsi/aacraid/aachba.c 1.6 -> 1.9 # drivers/usb/storage/protocol.h 1.4 -> 1.5 # sound/core/seq/instr/ainstr_fm.c 1.2 -> 1.3 # arch/sparc/math-emu/math.c 1.1 -> 1.2 # arch/i386/kernel/cpu/cpufreq/Makefile 1.3 -> 1.4 # include/asm-ppc64/ppc32.h 1.10 -> 1.11 # include/asm-generic/rtc.h 1.2 -> 1.3 # drivers/input/mouse/rpcmouse.c 1.11 -> 1.12 # sound/isa/sb/sb8_main.c 1.3 -> 1.4 # drivers/usb/misc/atmsar.h 1.2 -> 1.3 # fs/super.c 1.93 -> 1.95 # sound/pci/rme9652/rme9652.c 1.13 -> 1.15 # arch/ia64/hp/sim/simscsi.c 1.10 -> 1.11 # drivers/atm/Kconfig 1.1 -> 1.3 # net/sunrpc/auth_gss/Makefile 1.2 -> 1.3 # drivers/net/appletalk/Kconfig 1.2 -> 1.3 # drivers/acpi/include/actbl71.h 1.9 -> 1.10 include/acpi/actbl71.h (moved) # fs/jbd/Makefile 1.3 -> 1.4 # fs/binfmt_elf.c 1.34 -> 1.37 # arch/um/uml.lds.S 1.9.1.2 -> 1.16 # arch/i386/kernel/signal.c 1.26 -> 1.27 # mm/memory.c 1.107 -> 1.111 # drivers/net/irda/Makefile 1.13 -> 1.14 # include/sound/sb.h 1.4 -> 1.6 # drivers/isdn/hardware/avm/Makefile 1.4 -> 1.5 # arch/s390x/kernel/signal32.c 1.12 -> 1.13 # drivers/scsi/sg.c 1.45 -> 1.47 # drivers/scsi/aic7xxx/aic7xxx_core.c 1.17 -> 1.20 # drivers/usb/serial/pl2303.c 1.33 -> 1.34 # fs/jfs/super.c 1.32 -> 1.33 # arch/v850/Kconfig 1.5 -> 1.6 # drivers/cdrom/Makefile 1.4 -> 1.5 # drivers/s390/char/Makefile 1.11 -> 1.12 # arch/ia64/kernel/ia64_ksyms.c 1.18 -> 1.19 # fs/xfs/xfs_trans.c 1.2 -> 1.4 # arch/sparc64/kernel/winfixup.S 1.3 -> 1.4 # drivers/net/e1000/e1000_ethtool.c 1.17 -> 1.19 # drivers/video/console/Makefile 1.14 -> 1.15 # arch/sparc/kernel/entry.S 1.8 -> 1.10 # drivers/char/ip2/i2os.h 1.1 -> 1.2 # drivers/ide/Kconfig 1.5 -> 1.7 # drivers/fc4/Makefile 1.5 -> 1.6 # arch/um/kernel/trap_user.c 1.8 -> 1.9 # drivers/net/pcmcia/com20020_cs.c 1.5 -> 1.6 # arch/ppc/kernel/pci.c 1.21 -> 1.22 # fs/afs/cmservice.c 1.2 -> 1.3 # drivers/net/acenic.c 1.25 -> 1.26 # arch/ppc64/kernel/rtas-proc.c 1.3 -> 1.4 # drivers/net/e100/e100_main.c 1.37 -> 1.41 # include/linux/pci.h 1.60 -> 1.61 # drivers/scsi/aic7xxx/aic79xx_inline.h 1.3 -> 1.5 # sound/isa/sb/sb16_main.c 1.7 -> 1.9 # arch/um/drivers/net_kern.c 1.8 -> 1.9 # arch/ia64/kernel/mca.c 1.16 -> 1.17 # drivers/isdn/capi/Makefile 1.10 -> 1.11 # arch/ia64/kernel/iosapic.c 1.16 -> 1.18 # drivers/scsi/osst.c 1.38 -> 1.39 # arch/i386/kernel/setup.c 1.65 -> 1.67 # arch/ia64/kernel/process.c 1.21 -> 1.25 # arch/alpha/kernel/signal.c 1.14 -> 1.15 # include/asm-arm/signal.h 1.4 -> 1.5 # arch/mips/Kconfig 1.7 -> 1.8 # include/sound/pcm.h 1.9 -> 1.11 # drivers/scsi/gdth_proc.c 1.7 -> 1.11 # include/asm-sparc64/mman.h 1.3 -> 1.4 # drivers/input/touchscreen/Kconfig 1.1 -> 1.2 # net/ipv4/fib_hash.c 1.9 -> 1.10 # arch/um/drivers/ubd_kern.c 1.19.1.1 -> 1.26 # arch/um/kernel/helper.c 1.3.1.1 -> 1.8 # sound/synth/emux/Makefile 1.6 -> 1.9 # drivers/scsi/AM53C974.c 1.8 -> 1.10 # sound/i2c/tea6330t.c 1.4 -> 1.5 # include/sound/cs46xx_dsp_scb_types.h 1.1 -> 1.2 # arch/ia64/lib/memcpy_mck.S 1.2 -> 1.3 # arch/ia64/lib/memset.S 1.5 -> 1.6 # arch/um/Kconfig 1.3.1.1 -> 1.8 # drivers/serial/Makefile 1.12 -> 1.13 # arch/arm/mach-ebsa110/Makefile 1.5 -> 1.7 # arch/arm/mach-footbridge/Makefile 1.8 -> 1.9 # fs/jfs/jfs_xtree.c 1.7 -> 1.8 # arch/ia64/hp/sim/simserial.c 1.9 -> 1.10 # arch/ia64/kernel/acpi.c 1.24 -> 1.27 # drivers/mtd/maps/elan-104nc.c 1.3 -> 1.4 # include/linux/sdla_x25.h 1.2 -> 1.3 # arch/i386/kernel/time.c 1.24 -> 1.26 # arch/arm/mach-rpc/Makefile 1.4 -> 1.5 # include/linux/hugetlb.h 1.6 -> 1.10 # arch/um/kernel/skas/include/mode_kern.h 1.3 -> 1.5 # include/asm-ia64/kmap_types.h 1.3 -> 1.4 # include/asm-ppc64/kmap_types.h 1.3 -> 1.4 # arch/ia64/kernel/machvec.c 1.2 -> 1.3 # include/linux/spinlock.h 1.20 -> 1.21 # drivers/scsi/scsi_syms.c 1.24 -> 1.26 # drivers/media/video/zr36120.c 1.16 -> 1.17 # drivers/ide/pci/sis5513.c 1.9 -> 1.10 # drivers/usb/storage/isd200.c 1.26 -> 1.27 # sound/core/seq/instr/ainstr_iw.c 1.2 -> 1.3 # drivers/usb/storage/scsiglue.c 1.33.1.2 -> 1.37 # drivers/scsi/scsi_lib.c 1.61 -> 1.68 # scripts/Makefile.lib 1.10 -> 1.13 # arch/sparc64/kernel/time.c 1.19 -> 1.20 # sound/core/ioctl32/rawmidi32.c 1.7 -> 1.8 # sound/pci/ice1712/amp.c 1.1 -> 1.3 # sound/i2c/l3/uda1341.c 1.4 -> 1.5 # drivers/net/skfp/cfm.c 1.1 -> 1.2 # arch/x86_64/kernel/mtrr/Makefile 1.1 -> 1.2 # drivers/scsi/sim710.h 1.8 -> (deleted) # drivers/base/fs/Makefile 1.7 -> 1.8 # drivers/pnp/Kconfig 1.2 -> 1.3 # drivers/acpi/include/actbl.h 1.10 -> 1.12 include/acpi/actbl.h (moved) # drivers/acpi/include/acpi.h 1.6 -> 1.7 include/acpi/acpi.h (moved) # net/netlink/af_netlink.c 1.15 -> 1.16 # arch/um/drivers/ssl.c 1.6 -> 1.7 # include/asm-alpha/elf.h 1.2 -> 1.3 # include/asm-i386/mmzone.h 1.6 -> 1.7 # arch/um/os-Linux/drivers/ethertap_user.c 1.1 -> 1.2 # drivers/ide/Makefile 1.8 -> 1.9 # arch/mips64/sgi-ip22/ip22-timer.c 1.3 -> 1.4 # drivers/eisa/Makefile 1.1 -> 1.2 # drivers/usb/core/usb.c 1.113 -> 1.114 # fs/jfs/jfs_logmgr.c 1.41 -> 1.43 # include/asm-sparc/ide.h 1.12 -> 1.13 # drivers/scsi/scsi.c 1.82 -> 1.90 # arch/s390x/Makefile 1.20 -> 1.22 # arch/ppc64/kernel/traps.c 1.11 -> 1.12 # arch/um/sys-i386/fault.c 1.1 -> 1.2 # include/asm-alpha/signal.h 1.4 -> 1.5 # arch/alpha/kernel/time.c 1.12 -> 1.14 # arch/ppc64/kernel/head.S 1.19 -> 1.22 # net/irda/Kconfig 1.1 -> 1.2 # drivers/i2c/i2c-proc.c 1.13 -> 1.14 # arch/ia64/mm/hugetlbpage.c 1.4 -> 1.7 # arch/arm/mach-pxa/Makefile 1.5 -> 1.6 # fs/jfs/jfs_umount.c 1.8 -> 1.9 # arch/um/kernel/tt/Makefile 1.10 -> 1.12 # arch/ia64/tools/Makefile 1.11 -> 1.12 # drivers/acorn/scsi/acornscsi.c 1.22 -> 1.23 # drivers/acorn/scsi/arxescsi.c 1.14 -> 1.16 # crypto/cipher.c 1.10 -> 1.11 # drivers/acpi/power.c 1.13 -> 1.14 # Documentation/sysctl/kernel.txt 1.5 -> 1.6 # sound/pci/emu10k1/emufx.c 1.14 -> 1.15 # include/asm-ppc64/uaccess.h 1.4 -> 1.5 # drivers/scsi/pcmcia/qlogic_stub.c 1.9 -> 1.11 # arch/x86_64/mm/hugetlbpage.c 1.2 -> 1.5 # drivers/mca/Makefile 1.5 -> 1.6 # drivers/s390/char/sclp_tty.h 1.2 -> 1.3 # sound/isa/gus/gus_synth.c 1.4 -> 1.5 # drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped 1.3 -> 1.4 # drivers/scsi/aic7xxx/aiclib.c 1.2 -> 1.3 # arch/um/kernel/process_kern.c 1.13 -> 1.15 # drivers/net/pcmcia/ibmtr_cs.c 1.9 -> 1.10 # arch/um/drivers/mcast_user.c 1.1 -> 1.2 # drivers/net/sk98lin/skgeinit.c 1.3 -> 1.4 # mm/oom_kill.c 1.18 -> 1.19 # include/sound/ac97_codec.h 1.13 -> 1.14 # arch/arm/mm/proc-arm926.S 1.13 -> 1.14 # drivers/scsi/aic7xxx/aic7xxx.h 1.7 -> 1.8 # drivers/acpi/resources/rscalc.c 1.13 -> 1.14 # arch/arm/Kconfig 1.7 -> 1.8 # arch/m68k/atari/hades-pci.c 1.5 -> 1.6 # net/bluetooth/rfcomm/Kconfig 1.1 -> 1.2 # arch/sparc/kernel/pcic.c 1.16 -> 1.17 # include/sound/timer.h 1.2 -> 1.4 # arch/m68k/math-emu/fp_scan.S 1.2 -> 1.3 # drivers/input/serio/Kconfig 1.5 -> 1.6 # arch/arm/kernel/setup.c 1.27 -> 1.28 # include/asm-ia64/intrinsics.h 1.1 -> 1.3 # fs/xfs/support/move.c 1.3 -> 1.4 # include/asm-m68knommu/signal.h 1.1 -> 1.2 # sound/isa/gus/interwave.c 1.8 -> 1.9 # drivers/usb/storage/scsiglue.h 1.4 -> 1.5 # include/asm-i386/apicdef.h 1.6 -> 1.7 # drivers/net/mac8390.c 1.9 -> 1.10 # drivers/usb/serial/pl2303.h 1.6 -> 1.7 # arch/um/kernel/skas/tlb.c 1.2 -> 1.5 # net/sunrpc/sched.c 1.20 -> 1.21 # include/linux/apm_bios.h 1.6 -> 1.7 # drivers/acpi/include/acmacros.h 1.18 -> 1.19 include/acpi/acmacros.h (moved) # drivers/acpi/ec.c 1.18 -> 1.19 # mm/mremap.c 1.27 -> 1.28 # arch/ppc64/Kconfig 1.9 -> 1.11 # kernel/acct.c 1.16 -> 1.17 # arch/um/kernel/tempfile.c 1.3 -> 1.4 # arch/um/kernel/skas/include/mode.h 1.1 -> 1.2 # drivers/scsi/eata_generic.h 1.3 -> 1.4 # drivers/i2c/chips/Kconfig 1.3 -> 1.4 # include/linux/sysctl.h 1.38 -> 1.39 # drivers/md/Makefile 1.10 -> 1.11 # sound/core/ioctl32/timer32.c 1.7 -> 1.8 # arch/ia64/ia32/ia32_entry.S 1.15 -> 1.18 # drivers/net/tg3.c 1.42 -> 1.58 # include/asm-sh/signal.h 1.2 -> 1.3 # include/asm-i386/memblk.h 1.2 -> 1.3 # drivers/net/pcmcia/axnet_cs.c 1.7 -> 1.8 # sound/i2c/Makefile 1.8 -> 1.9 # arch/arm/mach-clps7500/Makefile 1.4 -> 1.5 # sound/pci/ice1712/ak4524.c 1.6 -> 1.7 # include/sound/mixer_oss.h 1.5 -> 1.6 # net/ipv6/tcp_ipv6.c 1.32 -> 1.36 # drivers/net/arlan.h 1.3 -> 1.4 # arch/um/kernel/signal_kern.c 1.5.1.1 -> 1.12 # include/asm-ia64/perfmon.h 1.9 -> 1.11 # fs/Kconfig 1.17 -> 1.18 # arch/ia64/kernel/sys_ia64.c 1.18 -> 1.20 # arch/sparc64/kernel/signal.c 1.22 -> 1.24 # arch/um/drivers/Makefile 1.9 -> 1.10 # drivers/telephony/Makefile 1.4 -> 1.5 # arch/arm/mach-anakin/Makefile 1.4 -> 1.5 # include/asm-um/page.h 1.3 -> 1.4 # arch/um/kernel/tt/trap_user.c 1.1 -> 1.2 # net/ipv4/xfrm_user.c 1.6 -> 1.8 # drivers/fc4/fc.c 1.10 -> 1.11 # arch/sparc/kernel/time.c 1.11 -> 1.12 # fs/direct-io.c 1.26 -> 1.27 # drivers/pci/proc.c 1.23 -> 1.24 # drivers/char/agp/Kconfig 1.7 -> 1.8 # fs/buffer.c 1.179 -> 1.182 # arch/ia64/kernel/signal.c 1.18 -> 1.19 # fs/Makefile 1.55 -> 1.56 # drivers/media/radio/Makefile 1.8 -> 1.9 # drivers/net/wan/Makefile 1.14 -> 1.15 # drivers/block/loop.c 1.78 -> 1.80 # drivers/usb/core/hcd.c 1.52 -> 1.54 # drivers/usb/input/hid-core.c 1.46 -> 1.47 # include/sound/trident.h 1.4 -> 1.5 # net/ipv4/esp.c 1.7 -> 1.12 # fs/jffs/intrep.c 1.19 -> 1.21 # drivers/pcmcia/sa1100_trizeps.c 1.3 -> 1.4 # drivers/acpi/include/acevents.h 1.11 -> 1.12 include/acpi/acevents.h (moved) # drivers/acpi/include/actypes.h 1.19 -> 1.20 include/acpi/actypes.h (moved) # arch/ppc64/kernel/htab.c 1.28 -> 1.29 # arch/um/include/mode.h 1.1 -> 1.2 # drivers/net/sk98lin/skvpd.c 1.3 -> 1.4 # drivers/net/declance.c 1.12 -> 1.13 # net/ipv6/netfilter/Makefile 1.9 -> 1.10 # arch/cris/kernel/Makefile 1.12 -> 1.13 # arch/arm/mach-ebsa110/time.c 1.2 -> (deleted) # fs/afs/kafstimod.c 1.2 -> 1.3 # drivers/scsi/pcmcia/fdomain_stub.c 1.9 -> 1.11 # arch/m68k/Kconfig 1.8 -> 1.9 # drivers/char/tty_io.c 1.55 -> 1.56 # arch/sh/kernel/Makefile 1.9 -> 1.10 # include/sound/cs46xx_dsp_spos.h 1.7 -> 1.8 # include/asm-sparc/signal.h 1.2 -> 1.3 # drivers/mtd/chips/jedec.c 1.5 -> 1.6 # arch/ppc64/kernel/process.c 1.25 -> 1.26 # fs/proc/array.c 1.38 -> 1.41 # drivers/acpi/include/achware.h 1.10 -> 1.11 include/acpi/achware.h (moved) # fs/jfs/jfs_txnmgr.c 1.34 -> 1.37 # include/asm-arm/arch-rpc/io.h 1.5 -> 1.6 # sound/i2c/l3/Makefile 1.3 -> 1.4 # sound/pci/maestro3.c 1.13 -> 1.15 # MAINTAINERS 1.116 -> 1.117 # arch/parisc/Kconfig 1.9 -> 1.10 # sound/pci/intel8x0.c 1.21 -> 1.25 # arch/um/kernel/tt/ptproxy/proxy.c 1.4 -> 1.5 # sound/isa/es1688/es1688_lib.c 1.6 -> 1.7 # drivers/isdn/hardware/eicon/diva_didd.c 1.2 -> 1.3 # include/asm-um/ptrace-i386.h 1.1 -> 1.2 # include/asm-generic/rmap.h 1.3 -> 1.4 # arch/sparc64/math-emu/math.c 1.7 -> 1.8 # drivers/scsi/scsi_debug.c 1.25.1.1 -> 1.28 # drivers/acpi/include/actbl2.h 1.13 -> 1.14 include/acpi/actbl2.h (moved) # arch/sparc64/kernel/sys_sunos32.c 1.25 -> 1.27 # arch/ia64/ia32/sys_ia32.c 1.36 -> 1.42 # sound/core/ioctl32/pcm32.c 1.9 -> 1.10 # drivers/scsi/aic7xxx/aic79xx_osm.h 1.11 -> 1.16 # drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped 1.9 -> 1.10 # drivers/acpi/include/aclocal.h 1.23 -> 1.24 include/acpi/aclocal.h (moved) # sound/pci/rme9652/Makefile 1.5 -> 1.6 # sound/core/device.c 1.8 -> 1.10 # arch/um/kernel/skas/syscall_kern.c 1.1 -> 1.2 # include/asm-s390x/signal.h 1.4 -> 1.5 # mm/mmap.c 1.63 -> 1.69 # arch/um/Makefile 1.16.1.1 -> 1.25 # net/bridge/netfilter/Makefile 1.2 -> 1.3 # net/rxrpc/Makefile 1.3 -> 1.4 # sound/pci/ac97/Makefile 1.10 -> 1.11 # arch/mips/mm/Makefile 1.6 -> 1.7 # sound/usb/usbaudio.h 1.9 -> 1.12 # drivers/media/radio/Kconfig 1.1 -> 1.2 # arch/ia64/hp/sim/simeth.c 1.3 -> 1.4 # arch/alpha/Makefile 1.21 -> 1.23 # include/asm-sparc64/compat.h 1.6 -> 1.7 # drivers/scsi/gdth.c 1.17 -> 1.20 # sound/core/timer.c 1.12 -> 1.14 # sound/drivers/opl3/opl3_seq.c 1.8 -> 1.9 # arch/um/drivers/port_user.c 1.3.1.1 -> 1.9 # mm/highmem.c 1.39 -> 1.40 # arch/s390x/kernel/signal.c 1.15 -> 1.16 # arch/um/kernel/time_kern.c 1.5 -> 1.8 # arch/um/include/irq_user.h 1.2 -> 1.3 # net/unix/af_unix.c 1.34 -> 1.35 # scripts/ver_linux 1.7 -> 1.8 # fs/read_write.c 1.25 -> 1.28 # include/linux/time.h 1.7 -> 1.8 # mm/Makefile 1.21 -> 1.23 # fs/lockd/svc.c 1.18 -> 1.19 # net/sched/sch_htb.c 1.5 -> 1.6 # arch/um/os-Linux/drivers/tuntap_kern.c 1.2 -> 1.3 # Documentation/filesystems/jfs.txt 1.3 -> 1.4 # drivers/scsi/53c8xx_u.h_shipped 1.2 -> (deleted) # arch/sparc64/kernel/sys_sparc32.c 1.59 -> 1.61 # net/irda/irnet/Kconfig 1.1 -> 1.2 # arch/um/drivers/harddog_kern.c 1.2 -> 1.3 # drivers/net/arlan.c 1.10 -> 1.12 # drivers/usb/class/cdc-acm.c 1.31 -> 1.33 # sound/isa/wavefront/wavefront_fx.c 1.6 -> 1.8 # drivers/hotplug/cpci_hotplug_pci.c 1.3 -> 1.5 # sound/pci/trident/trident_main.c 1.9 -> 1.13 # sound/isa/ad1816a/ad1816a_lib.c 1.6 -> 1.7 # arch/m68knommu/kernel/signal.c 1.3 -> 1.4 # drivers/scsi/ide-scsi.c 1.21 -> 1.23 # arch/v850/kernel/time.c 1.2 -> 1.3 # arch/um/kernel/tt/include/mode.h 1.1 -> 1.2 # include/asm-i386/unistd.h 1.22 -> 1.23 # sound/core/oss/mixer_oss.c 1.13 -> 1.15 # drivers/usb/storage/usb.h 1.23 -> 1.25 # drivers/scsi/eata_pio.c 1.10 -> 1.12 # arch/um/kernel/tt/include/uaccess.h 1.2 -> 1.3 # arch/mips/mips-boards/generic/time.c 1.4 -> 1.5 # arch/sh/Makefile 1.13 -> 1.15 # drivers/acorn/scsi/powertec.c 1.19 -> 1.21 # drivers/acpi/include/acparser.h 1.13 -> 1.14 include/acpi/acparser.h (moved) # drivers/scsi/sr_ioctl.c 1.27 -> 1.29 # net/appletalk/Makefile 1.6 -> 1.7 # fs/namespace.c 1.33 -> 1.34 # drivers/scsi/pcmcia/Kconfig 1.2 -> 1.3 # net/8021q/vlan.h 1.2 -> 1.3 # drivers/acpi/include/amlcode.h 1.14 -> 1.15 include/acpi/amlcode.h (moved) # drivers/usb/host/ohci-mem.c 1.13 -> 1.14 # drivers/usb/host/ehci-hcd.c 1.42 -> 1.43 # fs/ext2/super.c 1.43 -> 1.44 # arch/um/kernel/tt/syscall_user.c 1.1 -> 1.2 # include/asm-arm/module.h 1.3 -> 1.4 # fs/smbfs/smbiod.c 1.5 -> 1.6 # arch/um/defconfig 1.6 -> 1.7 # include/sound/asound.h 1.10 -> 1.12 # include/asm-ia64/ptrace.h 1.5 -> 1.8 # include/asm-um/module.h 1.1 -> 1.2 # drivers/net/tulip/de4x5.h 1.4 -> 1.5 # drivers/char/watchdog/Kconfig 1.3 -> 1.5 # drivers/message/fusion/Makefile 1.11 -> 1.12 # arch/ia64/sn/io/sn1/pcibr.c 1.11 -> 1.12 # drivers/scsi/pci2000.c 1.10 -> 1.12 # arch/m68knommu/kernel/time.c 1.1 -> 1.2 # sound/isa/gus/gus_mem_proc.c 1.5 -> 1.6 # fs/ext3/inode.c 1.58 -> 1.59 # arch/sparc64/mm/hugetlbpage.c 1.3 -> 1.5 # lib/zlib_deflate/Makefile 1.3 -> 1.4 # drivers/hotplug/pci_hotplug_util.c 1.6 -> (deleted) # arch/ia64/kernel/head.S 1.7 -> 1.8 # drivers/scsi/sym53c8xx.c 1.21 -> 1.23 # include/asm-i386/cpu.h 1.2 -> 1.3 # drivers/net/irda/irport.c 1.12 -> 1.13 # arch/cris/drivers/serial.c 1.9 -> 1.10 # Documentation/md.txt 1.1 -> 1.2 # arch/um/kernel/Makefile 1.16 -> 1.19 # arch/m68k/mvme16x/Makefile 1.3 -> 1.4 # include/asm-sparc64/delay.h 1.4 -> 1.5 # mm/page-writeback.c 1.54 -> 1.55 # fs/dquot.c 1.56 -> 1.58 # arch/arm/mach-sa1100/pcipool.c 1.4 -> 1.5 arch/arm/common/sa1111-pcipool.c (moved) # arch/m68k/atari/Makefile 1.5 -> 1.6 # sound/core/sound.c 1.17 -> 1.20 # drivers/scsi/qlogicpti.c 1.15 -> 1.16 # drivers/acpi/processor.c 1.27 -> 1.32 # include/net/ip.h 1.13 -> 1.14 # arch/x86_64/kernel/time.c 1.7 -> 1.10 # net/ipv4/tcp_output.c 1.19 -> 1.21 # sound/core/pcm_memory.c 1.5 -> 1.8 # sound/pci/trident/trident_memory.c 1.4 -> 1.5 # net/irda/irnet/irnet.h 1.14 -> 1.15 # sound/pci/es1938.c 1.12 -> 1.15 # fs/xfs/xfs_inode_item.c 1.5 -> 1.6 # include/asm-ia64/elf.h 1.5 -> 1.7 # security/Kconfig 1.4 -> 1.5 # sound/pci/trident/Makefile 1.4 -> 1.7 # drivers/net/arcnet/Makefile 1.5 -> 1.6 # arch/um/include/choose-mode.h 1.1 -> 1.2 # Documentation/s390/s390dbf.txt 1.2 -> 1.3 # include/asm-mips/ng1hw.h 1.1 -> 1.2 # drivers/video/aty/atyfb_base.c 1.48 -> 1.50 # arch/m68knommu/Kconfig 1.4 -> 1.5 # arch/x86_64/kernel/signal.c 1.11 -> 1.12 # sound/core/Makefile 1.22 -> 1.23 # drivers/message/i2o/Makefile 1.5 -> 1.6 # Documentation/scsi/ibmmca.txt 1.4 -> 1.6 # sound/core/seq/seq_timer.h 1.3 -> 1.4 # sound/isa/es1688/Makefile 1.4 -> 1.5 # arch/m68knommu/Makefile 1.3 -> 1.5 # include/linux/page-flags.h 1.34 -> 1.36 # arch/arm/mach-sa1100/stork.c 1.6 -> 1.7 # arch/alpha/kernel/core_irongate.c 1.8 -> 1.9 # arch/ppc64/kernel/sys_ppc32.c 1.44 -> 1.45 # arch/arm/kernel/time.c 1.12 -> 1.13 # sound/core/seq/seq_ports.c 1.7 -> 1.8 # arch/sparc/kernel/signal.c 1.18 -> 1.19 # fs/xfs/Makefile 1.8 -> 1.9 # sound/pci/es1968.c 1.14 -> 1.16 # drivers/net/fealnx.c 1.23 -> 1.24 # sound/drivers/mpu401/mpu401.c 1.6 -> 1.7 # Documentation/SubmittingDrivers 1.6 -> 1.7 # drivers/video/riva/fbdev.c 1.32 -> 1.33 # drivers/scsi/fdomain.c 1.15 -> 1.16 # arch/um/kernel/syscall_kern.c 1.5.1.1 -> 1.10 # drivers/hotplug/Makefile 1.11 -> 1.13 # arch/um/include/sysdep-i386/sigcontext.h 1.2 -> 1.3 # fs/jfs/jfs_dtree.c 1.18 -> 1.20 # sound/pci/sonicvibes.c 1.9 -> 1.12 # security/Makefile 1.4 -> 1.5 # drivers/scsi/constants.c 1.8 -> 1.10 # fs/seq_file.c 1.5 -> 1.6 # include/asm-x86_64/compat.h 1.4 -> 1.5 # arch/um/drivers/xterm_kern.c 1.3 -> 1.4 # arch/arm/mach-integrator/pci_v3.c 1.13 -> 1.15 # include/asm-ppc/kmap_types.h 1.13 -> 1.14 # sound/core/seq/instr/ainstr_gf1.c 1.2 -> 1.3 # drivers/acorn/scsi/cumana_2.c 1.20 -> 1.22 # drivers/acpi/acpi_drivers.h 1.12 -> 1.13 include/acpi/acpi_drivers.h (moved) # drivers/serial/8250_gsc.c 1.2 -> 1.3 # include/asm-i386/kmap_types.h 1.12 -> 1.13 # drivers/net/skfp/h/supern_2.h 1.1 -> 1.2 # kernel/module.c 1.51 -> 1.62 # arch/s390x/kernel/linux32.c 1.33 -> 1.34 # include/linux/security.h 1.9 -> 1.14 # drivers/usb/storage/dpcm.c 1.5 -> 1.6 # drivers/acpi/include/acdispat.h 1.11 -> 1.12 include/acpi/acdispat.h (moved) # drivers/net/e1000/e1000_proc.c 1.9 -> (deleted) # include/linux/quota.h 1.20 -> 1.21 # sound/usb/usbaudio.c 1.24 -> 1.30 # drivers/usb/serial/Kconfig 1.4 -> 1.5 # drivers/scsi/in2000.c 1.14 -> 1.16 # drivers/scsi/qlogicfc.c 1.22 -> 1.25 # include/net/sock.h 1.29 -> 1.30 # include/asm-ppc64/elf.h 1.4 -> 1.7 # include/asm-x86_64/kmap_types.h 1.6 -> 1.7 # include/asm-s390/signal.h 1.3 -> 1.4 # Documentation/scsi/aic79xx.txt 1.6 -> 1.7 # net/ipv4/sysctl_net_ipv4.c 1.6 -> 1.7 # sound/synth/emux/soundfont.c 1.3 -> 1.4 # drivers/input/power.c 1.3 -> 1.4 # arch/ia64/kernel/perfmon_mckinley.h 1.2 -> 1.5 # arch/ia64/lib/swiotlb.c 1.11 -> 1.12 # drivers/ide/pci/pdc202xx_new.c 1.9 -> 1.10 # arch/ppc64/kernel/smp.c 1.27 -> 1.28 # drivers/usb/net/Kconfig 1.2 -> 1.3 # include/asm-cris/io.h 1.6 -> 1.7 # arch/x86_64/kernel/Makefile 1.14 -> 1.15 # fs/nfs/write.c 1.37 -> 1.38 # fs/ext2/Makefile 1.6 -> 1.7 # fs/xfs/xfs_trans.h 1.3 -> 1.4 # include/asm-um/ptrace-generic.h 1.2 -> 1.3 # drivers/net/pcmcia/Kconfig 1.1 -> 1.2 # arch/um/kernel/unmap.c 1.1 -> 1.2 arch/um/kernel/tt/unmap.c (moved) # include/asm-mips64/signal.h 1.2 -> 1.3 # drivers/net/tokenring/smctr_firmware.h 1.2 -> 1.3 # arch/x86_64/mm/Makefile 1.6 -> 1.7 # Documentation/kbuild/makefiles.txt 1.5 -> 1.6 # drivers/scsi/53c7,8xx.h 1.5 -> (deleted) # include/asm-i386/pgtable.h 1.22 -> 1.24 # drivers/net/irda/Kconfig 1.2 -> 1.3 # drivers/net/hamradio/yam.c 1.11 -> 1.12 # arch/ia64/ia32/ia32_ioctl.c 1.5 -> 1.6 # drivers/acpi/include/acconfig.h 1.29 -> 1.31 include/acpi/acconfig.h (moved) # fs/nfs/nfs4proc.c 1.11 -> 1.12 # drivers/media/video/saa5249.c 1.10 -> 1.11 # arch/um/kernel/tlb.c 1.7 -> 1.8 # include/sound/info.h 1.6 -> 1.8 # net/ipv6/route.c 1.15 -> 1.16 # drivers/pcmcia/Kconfig 1.1 -> 1.2 # drivers/serial/mux.c 1.3 -> 1.4 # drivers/net/tulip/Kconfig 1.1 -> 1.2 # drivers/usb/storage/datafab.h 1.4 -> 1.5 # drivers/parisc/sba_iommu.c 1.6 -> 1.8 # arch/i386/mm/init.c 1.41 -> 1.43 # drivers/acpi/battery.c 1.13 -> 1.14 # arch/ppc/kernel/time.c 1.18 -> 1.19 # net/ipv4/tcp_minisocks.c 1.21 -> 1.22 # drivers/usb/input/Kconfig 1.2 -> 1.3 # arch/sparc/mm/sun4c.c 1.23 -> 1.24 # arch/arm/mach-sa1100/leds.h 1.6 -> 1.7 # drivers/media/video/bttv-driver.c 1.24 -> 1.25 # net/ipv6/Makefile 1.6 -> 1.7 # drivers/char/ftape/zftape/Makefile 1.4 -> 1.5 # sound/oss/i810_audio.c 1.31 -> 1.32 # sound/oss/trident.c 1.28 -> 1.29 # arch/alpha/Kconfig 1.13 -> 1.15 # arch/arm/kernel/ecard.c 1.18 -> 1.19 # arch/m68k/kernel/Makefile 1.7 -> 1.8 # fs/jfs/namei.c 1.23 -> 1.24 # drivers/s390/char/tape_char.c 1.1 -> 1.2 # drivers/block/DAC960.c 1.50 -> 1.51 # drivers/block/DAC960.h 1.16 -> 1.17 # Documentation/scsi/ChangeLog.sym53c8xx 1.4 -> 1.5 # sound/core/seq/seq_timer.c 1.7 -> 1.8 # sound/core/seq/instr/ainstr_simple.c 1.2 -> 1.3 # drivers/usb/storage/unusual_devs.h 1.23 -> 1.24 # drivers/acpi/include/platform/aclinux.h 1.16 -> 1.17 include/acpi/platform/aclinux.h (moved) # arch/um/kernel/tt/gdb_kern.c 1.1 -> 1.2 # sound/core/pcm_misc.c 1.5 -> 1.7 # arch/ia64/kernel/brl_emu.c 1.4 -> 1.5 # include/linux/module.h 1.42 -> 1.49 # arch/alpha/kernel/irq.c 1.17 -> 1.18 # mm/slab.c 1.56 -> 1.60 # include/sound/pcm_sgbuf.h 1.3 -> 1.5 # arch/um/sys-i386/bugs.c 1.2 -> 1.3 # drivers/net/skfp/h/osdef1st.h 1.1 -> 1.2 # drivers/usb/serial/ftdi_sio.c 1.40 -> 1.41 # fs/xfs/xfsidbg.c 1.17 -> 1.18 # arch/s390/kernel/signal.c 1.16 -> 1.17 # drivers/pcmcia/Makefile 1.20 -> 1.21 # arch/um/main.c 1.4 -> 1.6 # drivers/net/skfp/smt.c 1.1 -> 1.2 # arch/x86_64/Kconfig 1.12 -> 1.13 # drivers/scsi/aic7xxx/aic7xxx.seq 1.8 -> 1.9 # drivers/scsi/scsi_scan.c 1.52 -> 1.58 # sound/pci/fm801.c 1.11 -> 1.13 # arch/um/kernel/um_arch.c 1.8 -> 1.11 # kernel/sched.c 1.151 -> 1.155 # include/linux/agp_backend.h 1.22 -> 1.23 # include/asm-parisc/smp.h 1.2 -> 1.3 # arch/ppc/boot/simple/misc.c 1.9 -> 1.10 # crypto/tcrypt.c 1.20 -> 1.21 # sound/drivers/mtpav.c 1.12 -> 1.13 # sound/isa/sb/sb16.c 1.11 -> 1.12 # drivers/net/irda/sir_kthread.c 1.2 -> 1.3 # sound/core/seq/seq_queue.c 1.10 -> 1.11 # fs/jbd/recovery.c 1.8 -> 1.9 # drivers/usb/host/ehci-dbg.c 1.16 -> 1.17 # drivers/usb/host/ehci-q.c 1.42 -> 1.43 # drivers/scsi/Makefile 1.34 -> 1.37 # fs/quota_v2.c 1.8 -> 1.9 # arch/cris/lib/old_checksum.c 1.4 -> 1.5 # fs/xfs/xfs_extfree_item.c 1.1 -> 1.2 # init/Kconfig 1.8 -> 1.10 # include/linux/jbd.h 1.14 -> 1.15 # drivers/acpi/osl.c 1.21 -> 1.22 # lib/zlib_inflate/Makefile 1.3 -> 1.4 # drivers/block/Makefile 1.13 -> 1.14 # drivers/sbus/char/Makefile 1.11 -> 1.12 # include/asm-um/archparam-i386.h 1.1 -> 1.2 # include/asm-i386/pgtable-3level.h 1.8 -> 1.10 # scripts/Makefile.build 1.17 -> 1.27 # arch/um/kernel/irq.c 1.3.1.1 -> 1.6 # arch/mips/dec/time.c 1.4 -> 1.5 # drivers/char/pcmcia/Kconfig 1.1 -> 1.2 # drivers/scsi/sim710.c 1.6 -> 1.8 # arch/ia64/kernel/gate.S 1.9 -> 1.13 # drivers/scsi/dpt_i2o.c 1.20.1.1 -> 1.24 # kernel/params.c 1.3 -> 1.4 # sound/pci/ens1370.c 1.20 -> 1.24 # sound/core/rtctimer.c 1.11 -> 1.13 # include/asm-cris/signal.h 1.1 -> 1.2 # drivers/hotplug/pci_hotplug_core.c 1.31 -> 1.35 # include/asm-ppc/io.h 1.11 -> 1.12 # drivers/usb/serial/ipaq.c 1.25 -> 1.26 # sound/core/seq/instr/Makefile 1.11 -> 1.14 # drivers/base/Makefile 1.17 -> 1.18 # drivers/mtd/ftl.c 1.42 -> 1.43 # net/ipv4/netfilter/Kconfig 1.1 -> 1.2 # sound/oss/Kconfig 1.3 -> 1.4 # arch/um/kernel/tt/process_kern.c 1.4 -> 1.6 # arch/s390x/kernel/time.c 1.9 -> 1.10 # drivers/input/mouse/Kconfig 1.3 -> 1.4 # fs/sysfs/inode.c 1.78 -> 1.80 # arch/um/kernel/sys_call_table.c 1.13.1.1 -> 1.19 # arch/m68k/mac/macints.c 1.7 -> 1.8 # sound/pci/cs46xx/dsp_spos.c 1.11 -> 1.12 # drivers/cdrom/Kconfig 1.1 -> 1.2 # drivers/isdn/hysdn/Kconfig 1.1 -> 1.2 # drivers/isdn/hardware/eicon/Makefile 1.2 -> 1.3 # sound/core/seq/seq_midi.c 1.7 -> 1.8 # fs/vfat/Makefile 1.3 -> 1.4 # fs/jfs/jfs_unicode.c 1.3 -> 1.4 # arch/um/include/signal_kern.h 1.1 -> 1.2 # arch/ia64/vmlinux.lds.S 1.22 -> 1.27 # arch/i386/kernel/timers/timer_pit.c 1.7 -> 1.8 # drivers/scsi/aic7xxx/aic79xx.seq 1.3 -> 1.4 # arch/ia64/hp/common/Makefile 1.6 -> 1.7 # drivers/pnp/pnpbios/Makefile 1.2 -> 1.3 # scripts/per-cpu-check.awk 1.2 -> 1.3 # drivers/char/ftape/lowlevel/ftape-init.c 1.3 -> 1.4 # drivers/usb/host/ehci.h 1.15 -> 1.17 # sound/isa/cs423x/Makefile 1.7 -> 1.8 # drivers/net/hamradio/scc.c 1.18 -> 1.19 # arch/ia64/kernel/minstate.h 1.8 -> 1.9 # include/asm-mips64/r10kcache.h 1.2 -> 1.3 # include/asm-arm/ecard.h 1.5 -> 1.6 # drivers/char/ftape/compressor/zftape-compress.c 1.7 -> 1.8 # drivers/net/Kconfig 1.10 -> 1.12 # drivers/i2c/busses/Kconfig 1.3 -> 1.4 # arch/ppc64/kernel/pci.c 1.21 -> 1.22 # arch/um/kernel/process.c 1.7 -> 1.10 # fs/jfs/jfs_dmap.c 1.12 -> 1.13 # drivers/usb/serial/ftdi_sio.h 1.4 -> 1.5 # sound/core/oss/pcm_oss.c 1.16 -> 1.19 # drivers/scsi/eata.c 1.23 -> 1.26 # net/bluetooth/Kconfig 1.1 -> 1.2 # drivers/char/drm/Kconfig 1.1 -> 1.2 # arch/ia64/mm/discontig.c 1.1 -> 1.2 # sound/pci/nm256/nm256.c 1.11 -> 1.13 # arch/i386/kernel/acpi.c 1.17 -> 1.19 # net/llc/Makefile 1.6 -> 1.7 # drivers/s390/Kconfig 1.8 -> 1.9 # drivers/net/tokenring/tmspci.c 1.10 -> 1.11 # sound/pci/ymfpci/ymfpci_main.c 1.11 -> 1.15 # drivers/telephony/ixj_pcmcia.c 1.2 -> 1.3 # arch/ppc64/kernel/misc.S 1.41 -> 1.44 # arch/sparc64/Kconfig 1.10 -> 1.11 # drivers/acpi/thermal.c 1.17 -> 1.19 # arch/sparc/kernel/Makefile 1.13 -> 1.14 # drivers/macintosh/Makefile 1.10 -> 1.11 # arch/um/drivers/pcap_user.c 1.1 -> 1.2 # kernel/exit.c 1.80 -> 1.88 # arch/arm/mm/proc-arm922.S 1.11 -> 1.12 # net/ipv4/ah.c 1.9 -> 1.11 # include/linux/types.h 1.7 -> 1.8 # sound/oss/maestro.c 1.15 -> 1.17 # arch/alpha/kernel/process.c 1.24 -> 1.25 # arch/um/drivers/pty.c 1.3 -> 1.5 # arch/um/kernel/skas/include/skas_ptrace.h 1.1 -> 1.3 arch/um/include/skas_ptrace.h (moved) # drivers/parport/parport_gsc.c 1.7 -> 1.8 # arch/um/drivers/slip_user.c 1.2 -> 1.3 # arch/ia64/kernel/irq.c 1.16 -> 1.17 # arch/x86_64/Makefile 1.21 -> 1.22 # include/asm-x86_64/proto.h 1.5 -> 1.6 # drivers/usb/input/pid.c 1.5 -> 1.6 # net/sched/Kconfig 1.1 -> 1.2 # arch/ppc/platforms/4xx/Makefile 1.6 -> 1.7 # drivers/usb/host/uhci-hcd.c 1.29 -> 1.30 # arch/um/drivers/line.c 1.8 -> 1.12 # net/irda/Makefile 1.7 -> 1.8 # drivers/hotplug/cpqphp_nvram.c 1.6 -> 1.7 # arch/sparc64/kernel/power.c 1.8 -> 1.9 # net/ax25/Kconfig 1.1 -> 1.2 # drivers/acpi/include/acinterp.h 1.19 -> 1.20 include/acpi/acinterp.h (moved) # sound/usb/usbmidi.c 1.17 -> 1.21 # arch/arm/mach-epxa10db/Makefile 1.4 -> 1.5 # arch/um/kernel/skas/mem.c 1.1 -> 1.2 # arch/alpha/kernel/ptrace.c 1.11 -> 1.12 # sound/pci/emu10k1/memory.c 1.5 -> 1.6 # drivers/scsi/pcmcia/aha152x_stub.c 1.9 -> 1.11 # fs/hugetlbfs/inode.c 1.12 -> 1.18 # arch/ppc/kernel/Makefile 1.32 -> 1.33 # include/asm-ia64/tlbflush.h 1.6 -> 1.7 # drivers/scsi/aic7xxx_old/aic7xxx_proc.c 1.7 -> 1.8 # arch/arm/boot/compressed/head.S 1.17 -> 1.18 # fs/xfs/linux/xfs_aops.c 1.22 -> 1.23 # drivers/scsi/Kconfig 1.9 -> 1.12 # include/asm-ia64/bitops.h 1.9 -> 1.10 # sound/core/seq/Makefile 1.20 -> 1.24 # drivers/net/wireless/orinoco_cs.c 1.16 -> 1.17 # arch/arm/kernel/Makefile 1.13 -> 1.15 # arch/ia64/kernel/unaligned.c 1.8 -> 1.11 # arch/ia64/tools/print_offsets.c 1.10 -> 1.13 # arch/parisc/Makefile 1.14 -> 1.17 # drivers/media/video/stradis.c 1.12 -> 1.13 # sound/drivers/dummy.c 1.12 -> 1.13 # fs/partitions/sun.c 1.5 -> 1.6 # arch/alpha/kernel/pci_impl.h 1.9 -> 1.10 # arch/ppc64/kernel/signal32.c 1.31 -> 1.35 # drivers/pci/Makefile 1.20 -> 1.22 # net/irda/irlmp.c 1.20 -> 1.21 # arch/um/kernel/user_syms.c 1.1 -> 1.3 # arch/cris/Kconfig 1.4 -> 1.5 # arch/arm/mach-sa1100/sa1111.c 1.19 -> 1.20 arch/arm/common/sa1111.c (moved) # drivers/scsi/pci2000.h 1.5 -> 1.6 # include/asm-sparc64/kmap_types.h 1.3 -> 1.4 # Documentation/ia64/README 1.1 -> 1.2 # drivers/net/sgiseeq.c 1.12 -> 1.13 # drivers/pci/hotplug.c 1.8 -> 1.10 # arch/mips/kernel/sysirix.c 1.9 -> 1.10 # arch/m68k/Makefile 1.9 -> 1.11 # drivers/serial/Kconfig 1.4 -> 1.5 # sound/isa/gus/gus_irq.c 1.2 -> 1.3 # Documentation/Changes 1.31 -> 1.32 # drivers/acpi/namespace/nsload.c 1.15 -> 1.16 # arch/i386/mm/hugetlbpage.c 1.22 -> 1.29 # drivers/scsi/aic7xxx/aic79xx.reg 1.3 -> 1.4 # fs/msdos/Makefile 1.3 -> 1.4 # drivers/net/e100/Makefile 1.5 -> 1.6 # sound/pci/cs46xx/dsp_spos_scb_lib.c 1.10 -> 1.11 # sound/pci/ac97/ac97_patch.c 1.6 -> 1.8 # arch/um/kernel/umid.c 1.3 -> 1.5 # sound/core/seq/seq_midi_emul.c 1.3 -> 1.5 # net/sunrpc/svc.c 1.19 -> 1.20 # drivers/acpi/dispatcher/dsinit.c 1.5 -> 1.6 # drivers/acorn/char/pcf8583.c 1.6 -> 1.7 # arch/ppc64/kernel/time.c 1.15 -> 1.16 # drivers/nubus/Makefile 1.3 -> 1.4 # arch/arm/mach-iop310/Makefile 1.4 -> 1.5 # fs/xfs/xfs_bmap.c 1.5 -> 1.6 # arch/ia64/ia32/binfmt_elf32.c 1.10 -> 1.11 # drivers/media/video/Kconfig 1.2 -> 1.5 # drivers/char/ipmi/Makefile 1.1 -> 1.2 # drivers/net/arcnet/Kconfig 1.2 -> 1.3 # drivers/usb/host/ehci-mem.c 1.12 -> 1.13 # drivers/block/paride/Makefile 1.7 -> 1.8 # sound/pci/ali5451/ali5451.c 1.17 -> 1.20 # drivers/usb/host/ohci-q.c 1.33 -> 1.34 # drivers/input/Makefile 1.10 -> 1.11 # arch/ia64/kernel/perfmon.c 1.30 -> 1.35 # drivers/scsi/3w-xxxx.c 1.20 -> 1.22 # drivers/hotplug/cpqphp_pci.c 1.9 -> 1.12 # include/asm-ia64/bugs.h 1.1 -> 1.2 # include/asm-ia64/compat.h 1.5 -> 1.8 # drivers/net/ppp_generic.c 1.21 -> 1.22 # sound/core/pcm_sgbuf.c 1.6 -> 1.9 # arch/um/include/sysdep-i386/frame_user.h 1.1 -> 1.2 # drivers/net/tokenring/madgemc.c 1.9 -> 1.10 # fs/autofs4/waitq.c 1.5 -> 1.6 # arch/ia64/Kconfig 1.12 -> 1.14 # drivers/scsi/BusLogic.c 1.13 -> 1.15 # drivers/net/pcmcia/3c589_cs.c 1.12 -> 1.13 # drivers/hotplug/cpqphp_proc.c 1.5 -> 1.6 # drivers/char/Makefile 1.52 -> 1.54 # drivers/acpi/Makefile 1.26 -> 1.29 # arch/ia64/lib/Makefile 1.15 -> 1.16 # sound/pci/cs4281.c 1.18 -> 1.21 # mm/truncate.c 1.6 -> 1.8 # arch/um/kernel/skas/syscall_user.c 1.1 -> 1.2 # drivers/usb/host/Kconfig 1.2 -> 1.3 # drivers/usb/storage/Kconfig 1.1 -> 1.2 # arch/um/drivers/fd.c 1.2.1.1 -> 1.8 # net/bridge/Makefile 1.5 -> 1.6 # arch/arm/mach-ftvpci/Makefile 1.4 -> 1.5 # arch/um/kernel/tt/include/ptrace-tt.h 1.1 -> 1.2 # drivers/input/keyboard/Kconfig 1.3 -> 1.4 # arch/m68knommu/platform/68360/uCquicc/crt0_rom.S 1.1 -> 1.2 # include/sound/sb16_csp.h 1.1 -> 1.2 # drivers/video/acornfb.c 1.21 -> 1.22 # sound/core/info.c 1.18 -> 1.22 # arch/um/kernel/skas/process.c 1.3 -> 1.5 # fs/afs/kafsasyncd.c 1.2 -> 1.3 # sound/ppc/keywest.c 1.7 -> 1.8 # drivers/net/skfp/rmt.c 1.1 -> 1.2 # arch/ia64/kernel/sal.c 1.4 -> 1.5 # drivers/usb/misc/Kconfig 1.3 -> 1.4 # include/asm-sparc/mman.h 1.3 -> 1.4 # arch/ia64/kernel/traps.c 1.20 -> 1.25 # include/sound/seq_kernel.h 1.3 -> 1.4 # crypto/Makefile 1.15 -> 1.16 # arch/mips/au1000/common/Makefile 1.7 -> 1.8 # include/asm-arm/proc-armv/processor.h 1.5 -> 1.6 # include/asm-parisc/signal.h 1.1 -> 1.2 # fs/quota.c 1.11 -> 1.12 # arch/ia64/mm/fault.c 1.9 -> 1.10 # arch/s390/kernel/Makefile 1.15 -> 1.16 # arch/um/kernel/sigio_user.c 1.3 -> 1.6 # arch/um/drivers/pcap_kern.c 1.1 -> 1.2 # arch/i386/kernel/init_task.c 1.6 -> 1.7 # drivers/parport/parport_pc.c 1.31 -> 1.32 # sound/isa/ad1848/ad1848_lib.c 1.9 -> 1.12 # arch/um/drivers/hostaudio_kern.c 1.2 -> 1.3 # drivers/net/sk98lin/skxmac2.c 1.3 -> 1.4 # arch/x86_64/ia32/ia32_signal.c 1.8 -> 1.9 # drivers/video/sis/Makefile 1.7 -> 1.8 # arch/um/kernel/tt/sys-i386/sigcontext.c 1.1 -> 1.2 # drivers/net/wireless/netwave_cs.c 1.12 -> 1.13 # sound/pci/emu10k1/emu10k1_main.c 1.9 -> 1.11 # arch/um/drivers/slirp_kern.c 1.1 -> 1.2 # drivers/parport/Kconfig 1.3 -> 1.4 # drivers/usb/core/devices.c 1.19 -> 1.20 # include/asm-ppc64/topology.h 1.4 -> 1.5 # arch/arm/mach-l7200/Makefile 1.4 -> 1.5 # drivers/mtd/maps/Kconfig 1.2 -> 1.3 # arch/ppc64/kernel/module.c 1.1 -> 1.2 # arch/ppc64/kernel/Makefile 1.17 -> 1.19 # arch/parisc/kernel/signal.c 1.6 -> 1.7 # drivers/ide/pci/pdc202xx_old.c 1.9 -> 1.10 # drivers/acpi/include/platform/acgcc.h 1.14 -> 1.15 include/acpi/platform/acgcc.h (moved) # sound/isa/sb/emu8000_pcm.c 1.3 -> 1.4 # sound/isa/sb/sb16_csp.c 1.5 -> 1.6 # arch/ppc/8xx_io/Makefile 1.8 -> 1.9 # arch/ppc/kernel/signal.c 1.19 -> 1.20 # drivers/scsi/qlogicisp.c 1.15 -> 1.17 # arch/um/drivers/chan_kern.c 1.4 -> 1.5 # drivers/scsi/esp.c 1.21 -> 1.22 # arch/ppc/Kconfig 1.16 -> 1.17 # net/ipv4/ip_output.c 1.25 -> 1.26 # drivers/scsi/aic7xxx/aic79xx_seq.h_shipped 1.3 -> 1.4 # arch/ia64/kernel/ptrace.c 1.17 -> 1.18 # sound/isa/sb/sb_common.c 1.8 -> 1.9 # arch/sparc64/Makefile 1.22 -> 1.24 # include/scsi/scsi.h 1.8 -> 1.9 # drivers/ieee1394/Makefile 1.14 -> 1.15 # sound/isa/gus/Makefile 1.7 -> 1.10 # arch/m68k/mac/Makefile 1.3 -> 1.4 # drivers/parport/parport_cs.c 1.5 -> 1.6 # kernel/workqueue.c 1.3 -> 1.5 # arch/ia64/kernel/pal.S 1.5 -> 1.6 # drivers/acorn/scsi/eesox.c 1.20 -> 1.22 # fs/inode.c 1.79 -> 1.81 # include/asm-ia64/ia32.h 1.14 -> 1.17 # arch/sh/Kconfig 1.6 -> 1.7 # arch/um/os-Linux/file.c 1.5 -> 1.7 # net/bridge/br_if.c 1.5 -> 1.6 # drivers/hotplug/acpiphp.h 1.2 -> 1.4 # net/ipv4/route.c 1.37 -> 1.38 # drivers/usb/image/hpusbscsi.c 1.24 -> 1.25 # drivers/scsi/aic7xxx/aic79xx_reg.h_shipped 1.3 -> 1.4 # drivers/media/dvb/dvb-core/Makefile 1.2 -> 1.3 # sound/pci/rme32.c 1.11 -> 1.15 # drivers/acorn/scsi/fas216.h 1.3 -> 1.4 # drivers/bluetooth/bt3c_cs.c 1.6 -> 1.7 # arch/v850/kernel/mach.h 1.1 -> 1.2 # net/bluetooth/bnep/Kconfig 1.1 -> 1.2 # arch/i386/kernel/i386_ksyms.c 1.42 -> 1.43 # include/linux/slab.h 1.15 -> 1.17 # arch/ia64/kernel/Makefile 1.12 -> 1.14 # include/asm-ppc64/system.h 1.13 -> 1.16 # drivers/usb/storage/freecom.c 1.22 -> 1.23 # sound/core/ioctl32/seq32.c 1.6 -> 1.7 # drivers/base/memblk.c 1.3 -> 1.4 # include/sound/core.h 1.18 -> 1.21 # arch/parisc/kernel/syscall.S 1.5 -> 1.6 # drivers/acpi/Kconfig 1.3 -> 1.4 # drivers/scsi/sym53c8xx_2/sym_glue.h 1.7 -> 1.8 # drivers/isdn/hardware/eicon/io.h 1.1 -> 1.2 # drivers/net/hamachi.c 1.21 -> 1.22 # drivers/ide/pci/amd74xx.c 1.10 -> 1.11 # kernel/printk.c 1.21 -> 1.22 # drivers/media/radio/radio-zoltrix.c 1.9 -> 1.10 # include/asm-alpha/kmap_types.h 1.3 -> 1.4 # arch/um/os-Linux/drivers/tuntap_user.c 1.1 -> 1.2 # include/asm-arm/arch-rpc/hardware.h 1.2 -> 1.3 # arch/parisc/kernel/parisc_ksyms.c 1.6 -> 1.7 # sound/drivers/mpu401/Makefile 1.10 -> 1.11 # drivers/s390/block/Makefile 1.9 -> 1.10 # drivers/scsi/qla1280.c 1.24 -> 1.30 # arch/sparc64/kernel/sbus.c 1.10 -> 1.11 # drivers/usb/misc/speedtouch.c 1.28 -> 1.44 # arch/v850/kernel/signal.c 1.5 -> 1.6 # drivers/scsi/aic7xxx/aic7xxx_inline.h 1.6 -> 1.7 # sound/core/pcm.c 1.10 -> 1.12 # drivers/scsi/qlogicfas.c 1.16 -> 1.17 # sound/ppc/powermac.c 1.6 -> 1.8 # arch/ppc/platforms/Makefile 1.12 -> 1.13 # drivers/usb/media/usbvideo.c 1.32 -> 1.33 # arch/v850/kernel/Makefile 1.4 -> 1.5 # fs/xfs/xfs_log.c 1.8 -> 1.9 # drivers/macintosh/adb.c 1.14 -> 1.15 # drivers/scsi/53c7,8xx.scr 1.1 -> (deleted) # kernel/ptrace.c 1.23 -> 1.25 # arch/arm/mach-sa1100/Makefile 1.20 -> 1.24 # drivers/usb/core/Makefile 1.13 -> 1.14 # arch/um/kernel/init_task.c 1.2 -> 1.3 # arch/ia64/kernel/perfmon_itanium.h 1.2 -> 1.4 # fs/fs-writeback.c 1.27 -> 1.32 # arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c 1.3 -> 1.4 # sound/core/isadma.c 1.4 -> 1.6 # sound/ppc/pmac.c 1.9 -> 1.11 # arch/v850/Makefile 1.4 -> 1.5 # drivers/hotplug/ibmphp_core.c 1.15 -> 1.17 # drivers/usb/image/microtek.c 1.27 -> 1.28 # arch/arm/mach-sa1100/Kconfig 1.1 -> 1.3 # arch/parisc/kernel/traps.c 1.6 -> 1.7 # drivers/char/ip2main.c 1.21 -> 1.23 # arch/arm/mm/Makefile 1.16 -> 1.17 # arch/m68k/amiga/Makefile 1.3 -> 1.4 # arch/m68knommu/platform/68360/uCquicc/crt0_ram.S 1.1 -> 1.2 # drivers/message/fusion/Kconfig 1.1 -> 1.2 # arch/sparc64/solaris/signal.c 1.4 -> 1.5 # net/core/rtnetlink.c 1.7 -> 1.8 # arch/parisc/kernel/module.c 1.1 -> 1.2 # arch/mips/baget/Makefile 1.6 -> 1.7 # mm/pdflush.c 1.14 -> 1.15 # drivers/usb/host/hc_simple.c 1.5 -> 1.6 # Documentation/kernel-parameters.txt 1.12 -> 1.14 # arch/i386/mm/pgtable.c 1.5 -> 1.7 # net/ipv4/netfilter/ip_queue.c 1.8 -> 1.9 # arch/ia64/kernel/unwind.c 1.9 -> 1.11 # include/asm-parisc/compat.h 1.1 -> 1.2 # drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped 1.9 -> 1.10 # drivers/net/wireless/Makefile 1.8 -> 1.9 # include/asm-um/pgtable.h 1.5 -> 1.6 # arch/um/kernel/frame_kern.c 1.6 -> 1.7 # drivers/scsi/sym53c8xx_2/sym_glue.c 1.10 -> 1.13 # drivers/scsi/tmscsim.c 1.14 -> 1.16 # sound/isa/sgalaxy.c 1.8 -> 1.10 # fs/xfs/xfs_log.h 1.1 -> 1.2 # (new) -> 1.1 arch/um/vmlinux.lds.S # (new) -> 1.5 arch/ia64/kernel/fsys.S # (new) -> 1.1 arch/arm/def-configs/trizeps # (new) -> 1.2 arch/i386/kernel/cpu/cpufreq/acpi.c # (new) -> 1.1 arch/um/include/uml_uaccess.h # (new) -> 1.1 include/asm-um/ucontext.h # (new) -> 1.2 Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl # (new) -> 1.2 include/asm-um/common.lds.S # (new) -> 1.2 arch/um/kernel/tt/mem_user.c # (new) -> 1.1 arch/arm/mach-sa1100/leds-hackkit.c # (new) -> 1.3 Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl # (new) -> 1.1 mm/fadvise.c # (new) -> 1.1 drivers/char/hangcheck-timer.c # (new) -> 1.1 include/acpi/processor.h # (new) -> 1.2 arch/arm/common/Makefile # (new) -> 1.2 include/linux/seqlock.h # (new) -> 1.2 arch/um/Makefile-skas # (new) -> 1.1 include/asm-um/bug.h # (new) -> 1.3 arch/um/dyn.lds.S # (new) -> 1.1 include/asm-x86_64/dma-mapping.h # (new) -> 1.3 drivers/pci/pci-sysfs.c # (new) -> 1.4 Documentation/ia64/fsys.txt # (new) -> 1.2 Documentation/sound/alsa/OSS-Emulation.txt # (new) -> 1.1 arch/ia64/scripts/check-gas-asm.S # (new) -> 1.1 arch/um/kernel/uaccess_user.c # (new) -> 1.1 arch/um/Makefile-tt # (new) -> 1.1 drivers/usb/net/Makefile.mii # (new) -> 1.1 arch/ia64/scripts/check-gas # (new) -> 1.1 include/linux/fadvise.h # (new) -> 1.1 include/asm-arm/arch-sa1100/trizeps.h # (new) -> 1.1 arch/ia64/scripts/unwcheck.sh # (new) -> 1.1 include/asm-arm/arch-sa1100/mftb2.h # (new) -> 1.1 arch/alpha/kernel/srmcons.c # (new) -> 1.1 arch/um/sys-i386/extable.c # (new) -> 1.2 arch/arm/mach-sa1100/trizeps.c # (new) -> 1.1 arch/arm/mach-sa1100/hackkit.c # (new) -> 1.1 arch/arm/def-configs/hackkit # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/01/16 torvalds@penguin.transmeta.com 1.925.6.4 # Linux v2.5.59 # -------------------------------------------- # 03/01/17 anton@samba.org 1.925.8.1 # ppc64: SO_TIMESTAMP fix from sparc64 # -------------------------------------------- # 03/01/17 anton@samba.org 1.925.8.2 # ppc64: compat layer updates from Stephen Rothwell # -------------------------------------------- # 03/01/16 scott.feldman@intel.com 1.925.6.5 # [netdrvr e100] udelay a better way # # * Bug Fix: TCO workaround after hard reset of controller to wait for TCO # traffic to settle. Workaround requires issuing a CU load base command # after hard reset, followed by a wait for scb and finally a wait for # TCO traffic bit to clear. Affects 82559s and above wired to SMBus. # -------------------------------------------- # 03/01/16 scott.feldman@intel.com 1.925.6.6 # [netdrvr e100] fix TxDescriptor bit setting # -------------------------------------------- # 03/01/16 scott.feldman@intel.com 1.925.6.7 # [netdrvr e100] standardize nic-specific stats support # # * Removed /proc/net/PRO_LAN_Adapters # * Added ethtool GSTATS support # -------------------------------------------- # 03/01/16 jgarzik@redhat.com 1.925.6.8 # [netdrvr tg3] s/spin_lock/spin_lock_irqsave/ in tg3_poll and tg3_timer # # The tg3_timer one is very likely superfluous, and will hopefully be # removed after extended testing. # -------------------------------------------- # 03/01/16 jgarzik@redhat.com 1.925.6.9 # [netdrvr tg3] Better interrupt masking # # The bcm570x chips provide a register that disables (masks) or enables # interrupts, and as a side effect, each write to this register regardless # of value clears various PCI and internal interrupt-pending flags. This # register, intr-mbox-0, provides a superset of the function provided # by the mask-pci-int and clear-pci-int bits in the misc-host-ctrl register. # # Furthermore, the documentation clearly implies use of this register, # as an indicator that the host [tg3 driver] is in its interrupt handler. # # The new tg3 logic, taking this knowledge into account, masks-and-clears # irqs using intr-mbox-0 [only] when a hard irq is received, and # unmasks-and-clears irqs at the end of tg3_poll after all NAPI events # have been exhausted. # # The old logic twiddled the misc-host-ctrl irq masking bits separately # from intr-mbox-0 bits, which was not only inconsistent but also # a few additional I/Os that were not needed. # -------------------------------------------- # 03/01/17 jgarzik@redhat.com 1.925.6.10 # [netdrvr tg3] flush irq-mask reg write before checking hw status block, # in tg3_enable_ints. # -------------------------------------------- # 03/01/17 jgarzik@redhat.com 1.925.6.11 # [netdrvr tg3] manage jumbo flag on MTU change when interface is down # -------------------------------------------- # 03/01/17 jgarzik@redhat.com 1.925.6.12 # [netdrvr e100] remove e100_proc.c. should have been in prior cset. # -------------------------------------------- # 03/01/17 anton@samba.org 1.925.9.1 # Merge samba.org:/scratch/anton/linux-2.5 # into samba.org:/scratch/anton/for-alan # -------------------------------------------- # 03/01/17 anton@samba.org 1.927 # Merge samba.org:/scratch/anton/export into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/01/17 sfr@canb.auug.org.au 1.925.10.1 # [COMPAT]: compat_{old_}sigset_t sparc64. # -------------------------------------------- # 03/01/17 shaggy@shaggy.austin.ibm.com 1.925.11.1 # Merge jfs@jfs.bkbits.net:linux-2.5 # into shaggy.austin.ibm.com:/shaggy/bk/jfs-2.5 # -------------------------------------------- # 03/01/17 Matt_Domsch@dell.com 1.925.5.3 # Merge dell.com:/home/mdomsch/bk/linux-2.5 # into dell.com:/home/mdomsch/bk/edd/linux-2.5-edd # -------------------------------------------- # 03/01/17 kai@tp1.ruhr-uni-bochum.de 1.925.12.1 # kbuild: Fix __start_SECTION, __stop_SECTION # # In a discussion with Sam Ravnborg, the following problem became apparent: # Most vmlinux.lds.S (but the ARM ones) used the following construct: # # __start___ksymtab = .; # __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { # *(__ksymtab) # } # __stop___ksymtab = .; # # However, the link will align the beginning of the section __ksymtab # according to the requirements for the input sections. If '.' (current # location counter) wasn't sufficiently aligned before, it's possible # that __ksymtab actually starts at an address after the one # __start___ksymtab points to, which will confuse the users of # __start___ksymtab badly. The fix is to follow what the ARM Makefiles # did for this case, ie # # __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { # __start___ksymtab = .; # *(__ksymtab) # __stop___ksymtab = .; # } # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.13.1 # Merged the vmlinux.lds.h changes. # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.14.1 # Merge uml.karaya.com:/home/jdike/linux/2.5/linus-2.5 # into uml.karaya.com:/home/jdike/linux/2.5/fixes-2.5 # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.15.1 # Merged the vmlinux.lds.h changes. # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.16.1 # Merge uml.karaya.com:/home/jdike/linux/2.5/linus-2.5 # into uml.karaya.com:/home/jdike/linux/2.5/skas-2.5 # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.17.1 # Merge uml.karaya.com:/home/jdike/linux/2.5/linus-2.5 # into uml.karaya.com:/home/jdike/linux/2.5/stack-2.5 # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.18.1 # Merge uml.karaya.com:/home/jdike/linux/2.5/linus-2.5 # into uml.karaya.com:/home/jdike/linux/2.5/updates-2.5 # -------------------------------------------- # 03/01/17 ink@jurassic.park.msu.ru 1.925.19.1 # [PATCH] alpha_agpgart_size # # This allows to set the AGP aperture size from command line. # Default is 64Mb. # # Ivan. # -------------------------------------------- # 03/01/17 Jeff.Wiedemeier@hp.com 1.925.19.2 # [PATCH] NODE_BALANCE_RATE (numa) # # This defines NODE_BALANCE_RATE in include/asm-alpha/topology.h. Value is # pulled from asm-generic/topology.h. # # /jeff # -------------------------------------------- # 03/01/17 agrover@groveronline.com 1.925.1.25 # Merge groveronline.com:/root/bk/linux-2.5 # into groveronline.com:/root/bk/linux-acpi # -------------------------------------------- # 03/01/17 greg@kroah.com 1.925.20.1 # Merge kroah.com:/home/greg/linux/BK/bleeding_edge-2.5 # into kroah.com:/home/greg/linux/BK/gregkh-2.5 # -------------------------------------------- # 03/01/17 gibbs@overdrive.btc.adaptec.com 1.925.4.7 # Aic7xxx and Aic79xx DV Fix: # Don't bother with DV if the device can only do async # -------------------------------------------- # 03/01/17 gibbs@overdrive.btc.adaptec.com 1.925.4.8 # Aic79xx Driver Update # Enable abort and bus device reset handlers for both legacy # and packetized connections. # -------------------------------------------- # 03/01/17 david-b@pacbell.net 1.925.20.2 # [PATCH] usb root hub strings # # Someone changed the "get string" logic to use short reads, # not long ones, a while back. That broke many root hub # string accesses (not through tools like "lsusb"!) because # that logic didn't handle short reads quite right. # -------------------------------------------- # 03/01/17 baldrick@wanadoo.fr 1.925.20.3 # [PATCH] export speedtouch usb info # # speedtouch: restore use of MODULE_DEVICE_TABLE to export usb info. There may have # been a problem with older 2.4 kernels, but there is none now. # -------------------------------------------- # 03/01/17 davidm@wailua.hpl.hp.com 1.838.49.15 # ia64: Fix ia64_fls() so it works for all possible 64-bit values. # Reported by Dan Magenheimer (note: the bug didn't affect # the existing kernel, since the possible values passed to # the routine were always "safe"). # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.18.2 # Fixed asm/modules.h to update UML to 2.5.59. # -------------------------------------------- # 03/01/17 ganesh@tuxtop.vxindia.veritas.com 1.925.20.4 # [PATCH] USB ipaq driver ids # # Added ids for the Dell Axim and Toshiba E740. # # Thanks to Ian Molton and B.I. # -------------------------------------------- # 03/01/17 shaggy@shaggy.austin.ibm.com 1.925.11.2 # JFS: replace ugly JFS debug macros with simpler ones. # # JFS has always used ugly debug macros, jFYI, jEVENT, & jERROR. I have # replaced them with simpler jfs_info(), jfs_warn(), & jfs_err(). # -------------------------------------------- # 03/01/17 gibbs@overdrive.btc.adaptec.com 1.925.4.9 # Aic7xxx Driver Update: # o Determine more conclusively that a BIOS has initialized the # adapter before using "left over BIOS settings". # o Adapt to upcoming removal of cmd->target/channel/lun/host in 2.5.X # o Fix a memory leak on driver unload. # o Enable the pci_parity command line option and default to pci parity # error detection *disabled*. There are just too many broken VIA # chipsets out there. # o Move more functionality into aiclib to share with the aic79xx driver. # o Correct a few negotiation regressions. # o Don't bother doing full DV on devices that only support async transfers. # This should fix a few more of the reported problems with DV. # # Aic79xx Driver Update # o Add abort and bus device reset handlers. # o Fix a memory leak on driver unload. # o Adapt to upcoming removal of cmd->target/channel/lun/host in 2.5.X. # o Correct a few negotiation regressions. # -------------------------------------------- # 03/01/17 gibbs@overdrive.btc.adaptec.com 1.925.4.10 # Bump aic7xxx driver version to 6.2.27. # -------------------------------------------- # 03/01/17 gibbs@overdrive.btc.adaptec.com 1.925.4.11 # Aic7xxx and Aic79xx Driver Update # Force an SDTR after a rejected WDTR if the syncrate is unkonwn. # -------------------------------------------- # 03/01/17 agrover@groveronline.com 1.925.1.26 # ACPI: Move drivers/acpi/include directory to include/acpi # -------------------------------------------- # 03/01/17 davidm@tiger.hpl.hp.com 1.838.49.16 # ia64: Add unwcheck.sh script contributed by Harish Patil. It checks # the unwind info for consistency (well, just the obvious # stuff, but it's a start). # Fix the couple of bugs that this script uncovered (and work # around one false positive). # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.13.2 # Some build changes for 2.5.59 and SMP. Also cleanup of the linker # scripts and Kconfig. # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.15.2 # Correctly check the mmap return value. # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.14.2 # Some SMP fixes from Oleg. # -------------------------------------------- # 03/01/17 bjorn_helgaas@hp.com 1.838.49.17 # [PATCH] irq cleanups # # Cleanup the irq handling macros. # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.18.3 # Some SMP fixes. # -------------------------------------------- # 03/01/17 davidm@tiger.hpl.hp.com 1.838.49.18 # ia64: Fix Makefiles so that "make clean" removes the files generated # in the tools directory. Patch by Yu, Fenghua. # -------------------------------------------- # 03/01/17 jdike@uml.karaya.com 1.925.13.3 # Fixed dyn.lds.S to include common.lds.S. # -------------------------------------------- # 03/01/17 rohit.seth@intel.com 1.838.49.19 # [PATCH] ia64: Update to hugetlb # # Please find attached a patch that brings in the support of hugetlb # inline with the ia32 tree. This removes the syscall interface and gets # the hugetlbfs support (using mmap and shmat). I might be sending you # couple of more small updates a little later. At least wanted to get # this out first. # -------------------------------------------- # 03/01/17 davidm@tiger.hpl.hp.com 1.838.49.20 # Remove last vestiges of hugepage system calls (they have been replaced by hugetlbfs). # -------------------------------------------- # 03/01/17 eranian@hpl.hp.com 1.838.49.21 # [PATCH] ia64: perfmon update # # Here is the patch. It is rather big because there is some renaming and # cleanups. This patch bring 2.5 in line with 2.4.20: perfmon-1.3 # # It adds: # - idle task exclusion # - less ctxsw overhead in system wide # - cleanups most of the inline asm # - don't use PAL anymore to determine PMU features # - added temporary hooks for custom overflow handlers (VTUNE/Oprofile) # - renaming of the perfmon init functions # # Thanks. # -------------------------------------------- # 03/01/17 kochi@hpc.bs1.fc.nec.co.jp 1.838.49.22 # [PATCH] ia64: skip _PRT entry for non-existent IOSAPICs # # On some machines that support I/O hot-plugging, # it happens that after boottime one or more IO SAPICs appear # after hot-plug event. Even in that case, ACPI _PRT entries # can exist for devices behind those IO SAPICs at boottime # for future use. # # Currently iosapic.c will give up parsing _PRT entries # once one of them hits such a non-existent IO SAPIC. # # This patch fixes the problem on 2.5 ia64 bk tree. # For 2.4, we don't have this problem now. # -------------------------------------------- # 03/01/17 alex_williamson@hp.com 1.838.49.23 # [PATCH] ia64: fix typo in ia32_support.c # # Happened to notice the attached redundancy. # -------------------------------------------- # 03/01/17 davidm@tiger.hpl.hp.com 1.838.49.24 # ia64: Don't risk running past the end of the unwind-table. Based on a patch by # Suresh Siddha. # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.15.3 # Ported a cleanup from 2.4. # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.14.3 # Ported a uml-config.h change from 2.4. # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.17.2 # Ported a cleanup from 2.4. # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.18.4 # Changed some CONFIG_* names to UML_CONFIG_* names. # -------------------------------------------- # 03/01/18 rmk@flint.arm.linux.org.uk 1.925.21.1 # [ARM] Fix printk in rpcmouse.c # # printk was missing a new line, and displaying the (fixed) IRQ number # is rather meaningless. # -------------------------------------------- # 03/01/18 rmk@flint.arm.linux.org.uk 1.925.21.2 # [ARM] Fix buffer overflow in fas216-based SCSI drivers. # # 100 characters is too small for the SCSI "info" string buffer; the # last few characters appear to get stomped on. Make the buffer 150 # characters long. # -------------------------------------------- # 03/01/18 rmk@flint.arm.linux.org.uk 1.925.21.3 # [ARM] Fix fas216-based data-phase lockups # # Ensure SCpnt->request_bufflen is initialised correctly when we # request sense information. # -------------------------------------------- # 03/01/18 rmk@flint.arm.linux.org.uk 1.925.21.4 # [ARM] Add soft-cursor support to acornfb and sa1100fb. # -------------------------------------------- # 03/01/18 rmk@flint.arm.linux.org.uk 1.925.21.5 # [ARM] Make oops dump reasonble again without kallsyms support enabled. # # print_symbol() becomes a NOP when CONFIG_KALLSYMS=n, so we loose # the new line character as well. Explicitly call printk("\n"). # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.15.4 # A bunch of minor changes ported up from 2.4. # All userspace uses of CONFIG_* have been changed to UML_CONFIG_* # to avoid conflicts with the host's config. # os_open_file now has FD_CLOEXEC support. # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.14.4 # Fixed the time locking bug. # The mconsole and switch protocols are now 64-bit clean. # Fixed some smaller bugs. # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.17.3 # Changed CONFIG_KERNEL_STACK_ORDER to UML_CONFIG_KERNEL_STACK_ORDER. # -------------------------------------------- # 03/01/18 drow@nevyn.them.org 1.925.22.1 # Tweak has_stopped_jobs for use with debugging # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.15.5 # Replaced some CONFIG_* with UML_CONFIG_*. # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.16.2 # Replaced a CONFIG_* name with a UML_CONFIG_* name. # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.14.5 # Changed some CONFIG_* symbols to UML_CONFIG_*. # -------------------------------------------- # 03/01/18 jdike@jdike.wstearns.org 1.925.23.1 # Merge jdike.wstearns.org:/home/jdike/linux/linus-2.5 # into jdike.wstearns.org:/home/jdike/linux/fixes-2.5 # -------------------------------------------- # 03/01/18 drow@nevyn.them.org 1.925.22.2 # Add PTRACE_GETSIGINFO and PTRACE_SETSIGINFO # # These new ptrace commands allow a debugger to control signals more precisely; # for instance, store a signal and deliver it later, as if it had come from the # original outside process or in response to the same faulting memory access. # -------------------------------------------- # 03/01/18 jdike@jdike.wstearns.org 1.925.24.1 # Merge jdike.wstearns.org:/home/jdike/linux/linus-2.5 # into jdike.wstearns.org:/home/jdike/linux/skas-2.5 # -------------------------------------------- # 03/01/18 jdike@jdike.wstearns.org 1.925.25.1 # Merge jdike.wstearns.org:/home/jdike/linux/linus-2.5 # into jdike.wstearns.org:/home/jdike/linux/stack-2.5 # -------------------------------------------- # 03/01/18 jdike@jdike.wstearns.org 1.925.26.1 # Merge jdike.wstearns.org:/home/jdike/linux/linus-2.5 # into jdike.wstearns.org:/home/jdike/linux/updates-2.5 # -------------------------------------------- # 03/01/18 jdike@jdike.wstearns.org 1.925.27.1 # Fixed a conflict in the linker script. # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.18.5 # Merge jdike.stearns.org:linux/updates-2.5 # into uml.karaya.com:/home/jdike/linux/2.5/updates-2.5 # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.17.4 # Merge jdike.stearns.org:linux/stack-2.5/ # into uml.karaya.com:/home/jdike/linux/2.5/stack-2.5 # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.16.3 # Merge jdike.stearns.org:linux/skas-2.5/ # into uml.karaya.com:/home/jdike/linux/2.5/skas-2.5 # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.14.6 # Merge jdike.stearns.org:linux/fixes-2.5/ # into uml.karaya.com:/home/jdike/linux/2.5/fixes-2.5 # -------------------------------------------- # 03/01/18 jdike@jdike.wstearns.org 1.925.28.1 # Fixed a conflict in the linker script. # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.13.4 # Merge # -------------------------------------------- # 03/01/18 jdike@uml.karaya.com 1.925.15.6 # Merge jdike.stearns.org:linux/cleanup-2.5/ # into uml.karaya.com:/home/jdike/linux/2.5/cleanup-2.5 # -------------------------------------------- # 03/01/19 akpm@digeo.com 1.925.10.2 # [SPARC64]: Handle unchanging _TIF_32BIT properly in SET_PERSONALITY. # -------------------------------------------- # 03/01/19 jamie@shareable.org 1.925.10.3 # [SPARC64]: Fix MAP_GROWSDOWN value, cannot be the same as MAP_LOCKED. # -------------------------------------------- # 03/01/19 jdike@uml.karaya.com 1.925.18.6 # Added vmlinux.lds.S which is now necessary for linking the vmlinux # object file. # -------------------------------------------- # 03/01/20 anton@samba.org 1.925.29.1 # ppc64: defer change of 32/64bit mode, from Andrew Morton # -------------------------------------------- # 03/01/20 anton@samba.org 1.928 # Merge samba.org:/scratch/anton/linux-2.5_ppc64 # into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/01/20 anton@samba.org 1.925.29.2 # ppc64: now make it compile # -------------------------------------------- # 03/01/20 anton@samba.org 1.929 # Merge samba.org:/scratch/anton/linux-2.5_ppc64 # into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/01/19 Jeff.Wiedemeier@hp.com 1.925.19.3 # [PATCH] mark boot_cpu online in smp_prepare_boot_cpu # # Mark the boot cpu online in smp_prepare_boot_cpu instead of # smp_prepare_cpus so that early printks (srmcons) work with alpha smp # kernels. # # /jeff # -------------------------------------------- # 03/01/20 rth@kanga.twiddle.net 1.925.19.4 # [ALPHA] Add debugging access (core and ptrace) to the # PAL unique value. Support threaded core dumps. # -------------------------------------------- # 03/01/20 rth@kanga.twiddle.net 1.925.19.5 # [ALPHA] New SRM console driver. # # From Jeff Wiedemeier: # # How about this.. This version no longer piggy backs on ttyS0 (it # actually doesn't touch any files outside arch/alpha/kernel at all). It # does use a dynamic major for the tty piece of the driver. From # userspace, /dev/console is ok for most uses, but because of the 'noctty # = 1' at tty_tio.c:1329 (in the IS_SYSCONS_DEV section) using # /dev/console cannot result in a controlling tty so some things, like # 'resize' and bash job control don't work. For those uses, however, it's # easy enough to parse /proc/devices on the way up to get the major number # and create the specific device for the tty side of the driver. # # I made a distinction in kernel options as well. "srmcons" specifically # requests the early prints (as before) and "console=srm" requests the # full driver, including the early prints. The two options can be # combined with "console=srm" behavior resulting. The other change is that # if "console=srm" is specified, I don't unregister_srm_console before # console_init any more - that only happens in the "srmcons" case. That # way preferred console selection remains stable and "console=srm" doesn't # result in the early messages being repeated when the driver # re-registers. The use of "srmcons_allowed" is also eliminated due to the # "srmcons" vs. "console=srm" distinction. # -------------------------------------------- # 03/01/20 Jeff.Wiedemeier@hp.com 1.925.19.6 # [PATCH] remove srmcons_allowed implementation from marvel # # Remove unused marvel_srmcons_allowed implementation. # # /jeff # -------------------------------------------- # 03/01/20 Jeff.Wiedemeier@hp.com 1.925.19.7 # [PATCH] use CONFIG_EARLY_PRINTK to turn off "srmcons" prints # # Use CONFIG_EARLY_PRINTK to trigger disable_early_printk() call in # console_init (tty_io.c) to turn off "srmcons" prints rather than the # existing code in time.c. # # /jeff # -------------------------------------------- # 03/01/20 agrover@groveronline.com 1.925.1.27 # ACPI: Move more headers to include/acpi, and delete an unused header. # -------------------------------------------- # 03/01/20 agrover@groveronline.com 1.925.1.28 # CPUFREQ: Break out ACPI Perf code into its own module, under cpufreq # (Dominik Brodowski) # -------------------------------------------- # 03/01/20 agrover@groveronline.com 1.925.1.29 # ACPI: acpiphp.h includes both linux/acpi.h and acpi_bus.h. Since the # former now also includes the latter, acpiphp.h only needs the one, now. # -------------------------------------------- # 03/01/20 gibbs@overdrive.btc.adaptec.com 1.925.4.12 # Aic7xxx Driver Update 6.2.28 # o Add some more DV diagnostic code # o Fix bug that cause sequencer debug code to be # downloaded always. # # Aic79xx Driver Update 1.3.0.RC2 # o Correct a bug that effectively limited DV to just ID 0. # o Add some more DV diagnostic code # o Misc code cleanups. # -------------------------------------------- # 03/01/20 agrover@groveronline.com 1.925.1.30 # ACPI: Remove include of unused header (Adrian Bunk) # -------------------------------------------- # 03/01/20 agrover@groveronline.com 1.925.1.31 # ACPI: Properly init/clean up in cpufreq/acpi (Dominik Brodowski) # -------------------------------------------- # 03/01/20 agrover@groveronline.com 1.925.1.32 # ACPI: Make proc write interfaces work (Pavel Machek) # -------------------------------------------- # 03/01/20 agrover@groveronline.com 1.925.1.33 # ACPI: This makes it possible to select method of bios restoring after S3 # resume. [=> no more ugly ifdefs] (Pavel Machek) # -------------------------------------------- # 03/01/21 baldrick@wanadoo.fr 1.925.20.5 # [PATCH] USB: trivial speedtouch changes # # speedtouch: trivial whitespace and debug message changes. # -------------------------------------------- # 03/01/21 baldrick@wanadoo.fr 1.925.20.6 # [PATCH] USB: move udsl_atm_set_mac into speedtouch probe function # # speedtouch: roll udsl_atm_set_mac into udsl_usb_probe. # -------------------------------------------- # 03/01/21 baldrick@wanadoo.fr 1.925.20.7 # [PATCH] USB: eliminate pointless dynamic allocation in speedtouch # # speedtouch: use an array for rcvbufs rather than a pointer and dynamic allocation. # -------------------------------------------- # 03/01/21 baldrick@wanadoo.fr 1.925.20.8 # [PATCH] USB: move udsl_atm_startdevice into speedtouch probe function # # speedtouch: roll udsl_atm_startdevice into udsl_usb_probe. # -------------------------------------------- # 03/01/21 baldrick@wanadoo.fr 1.925.20.9 # [PATCH] USB: rework error handling in speedtouch probe function # # speedtouch: rework udsl_usb_probe error handling (for example, handle failure of # atm_dev_register). Do some trivial cleaning up while we're at it. # -------------------------------------------- # 03/01/21 baldrick@wanadoo.fr 1.925.20.10 # [PATCH] USB: turn speedtouch micro race into a nano race # # speedtouch: turn a micro race into a nano race. The race is that an ATM device can # be used the moment atm_dev_register returns, but you only get to fill out the # atm_dev structure after atm_dev_register returns (this is a design flaw in the # ATM layer). Thus there is a small window during which you can be called with an # incompletely set up data structure. Workaround this by causing all ATM callbacks # to fail if the dev_data field has not been set. There is still a nano race if # writing/reading the dev_data field is not atomic. Is it atomic on all architectures? # -------------------------------------------- # 03/01/21 baldrick@wanadoo.fr 1.925.20.11 # [PATCH] USB: simplify speedtouch receive urb lifecycle # # speedtouch: simplify the receive urb lifecycle: allocate them in the usb probe function, # free them on disconnect. # -------------------------------------------- # 03/01/21 henning@meier-geinitz.de 1.925.20.12 # [PATCH] USB scanner.h, scanner.c: New vendor/product ids # # This patch adds vendor/product ids for Artec, Canon, Compaq, Epson, # HP, and Microtek scanners. Further more, the device list was cleaned # up, sorted and duplicated entries have been removed. # -------------------------------------------- # 03/01/21 sri@us.ibm.com 1.925.30.1 # [IPV{4,6}]: Add ipfragok arg to ip_queue_xmit. # -------------------------------------------- # 03/01/21 davem@nuts.ninka.net 1.925.30.2 # [TCP]: Named struct initializers and tabbing fixes. # -------------------------------------------- # 03/01/21 davem@nuts.ninka.net 1.925.30.3 # [IPSEC]: Clear SKB checksum state when mangling. # -------------------------------------------- # 03/01/21 thomas@bender.thinknerd.de 1.925.30.4 # [IPSEC]: Fix some buglets in xfrm_user.c # -------------------------------------------- # 03/01/21 kaber@trash.net 1.925.30.5 # [PPP]: Handle filtering drops correctly. # -------------------------------------------- # 03/01/21 Jeff.Wiedemeier@hp.com 1.925.19.8 # [PATCH] fix /proc/interrupts on smp alpha kernels # # alpha show_interrupts was using irq as the cpu index and cpu as the irq # index fpr the kstat_cpu(cpu).irqs[irq] lookup. # # /jeff # -------------------------------------------- # 03/01/21 agrover@groveronline.com 1.925.1.34 # ACPI: Handle P_BLK lengths shorter than 6 more gracefully # -------------------------------------------- # 03/01/21 davidm@tiger.hpl.hp.com 1.925.31.1 # ia64: Merge with 2.5.59. # -------------------------------------------- # 03/01/21 Matt_Domsch@dell.com 1.925.5.4 # EDD: until SCSI layer sysfs is fixed, don't use it for raw_data either. # -------------------------------------------- # 03/01/21 Matt_Domsch@dell.com 1.925.5.5 # EDD: don't over-allocate EDD data block # # Found by Kevin Lawton. # -------------------------------------------- # 03/01/21 sfr@canb.auug.org.au 1.925.31.2 # [PATCH] ia64: [COMPAT] Eliminate the rest of the __kernel_..._t32 typedefs # # -------------------------------------------- # 03/01/21 sfr@canb.auug.org.au 1.925.31.3 # [PATCH] ia64: [COMPAT] {get,put}_compat_timspec 5/8 # # -------------------------------------------- # 03/01/21 sfr@canb.auug.org.au 1.925.31.4 # [PATCH] ia64: [COMPAT] compat_{old_}sigset_t # # -------------------------------------------- # 03/01/21 sfr@canb.auug.org.au 1.925.31.5 # [PATCH] ia64: [COMPAT] compat_sys_sigpending and compat_sys_sigprocmask # # -------------------------------------------- # 03/01/21 davidm@tiger.hpl.hp.com 1.925.31.6 # ia64: asm-ia64/system.h: Remove include of . # -------------------------------------------- # 03/01/21 sfr@canb.auug.org.au 1.925.31.7 # [PATCH] ia64: [COMPAT] compat_sys_[f]statfs # # -------------------------------------------- # 03/01/22 gibbs@overdrive.btc.adaptec.com 1.925.4.13 # Update Aic7xxx and Aic79xx driver documentation. # -------------------------------------------- # 03/01/22 gibbs@overdrive.btc.adaptec.com 1.925.4.14 # Bump aic79xx driver version number to 1.3.0, now that it has # passed functional test. # -------------------------------------------- # 03/01/23 dougg@torque.net 1.925.32.1 # [PATCH] SAM-3 status codes # # The perverse CHECK_CONDITION in include/scsi/scsi.h seems # to have struck again (see "Can't burn DVD under 2.5.59 with # ide-cd" thread on the linux kernel list). Most users of # CHECK_CONDITION found out to their surprise that it is # shifted 1 bit (right) from those values found in the # standards. # # The attachment marks the orginal list of SCSI status codes # as deprecated and supplies defines taken from the most # recent SAM-3 draft. # -------------------------------------------- # 03/01/23 ink@jurassic.park.msu.ru 1.925.19.9 # [PATCH] nautilus update # # - make irongate_ioremap() use generic __alpha_remap_area_pages(); # - remove huge debugging printk; # - AGP remapping hardware disabled for now. Any attempt to use it # would result in corrupted memory; # - albacore (UP1500) support: # - handle differences between AMD-761 (UP1500) and AMD-751 (UP1000/1100) # chipsets, namely ECC mode/status and pci_mem registers; # - customized nautilus_init_pci() to minimize amount of system memory # consumed by PCI MMIO for 4Gb configuration. # # Ivan. # -------------------------------------------- # 03/01/23 agrover@groveronline.com 1.925.1.35 # ACPI: update to 20030122 # -------------------------------------------- # 03/01/23 adam@yggdrasil.com 1.925.32.2 # | The following changes to ide-scsi.c are a recovery of the # | changes that I had in ide-scsi.c in the stock kernel's before # | Martin Dalecki's IDE tree was reverted and a few other changes. # | # | The principal change is that each ATAPI device is a Scsi_host # | (which reflects reality), instead of having one fake Scsi_Host with # | that appears to have all of the ATAPI devices on one bus regardless of # | actual hardware topology. This way it is much easier for software to # | tell that, for example, a scsi copy command will not work between two # | ATAPI devices. More importantly, hot plugging should theoretically # | work now, since Scsi_hosts are allocated and deallocated as ATAPI # | devices are added or removed. # | # | This change eliminates the idescsi_drives[] array and the # | ide_driver_t.id field that was used to index it. # | # | The idescsi_scsi_t data structure is now allocated at # | the end of the struct Scsi_Host rather than being a separate # | memory allocation. The calculation of various private pointers # | are changed slightly as a result. # | # | Other minor nits include making all global routines # | static and adding some missing error branches in # | init_idescsi_module. # | # | I've verified that I can at least read raw data # | from a DVD-ROM with with this change. # | # | When I unload this ide-scsi module, the stock ide-scsi module # | or the stock ide-cd modules in 2.5.56, I get what appears to be the # | same kernel bad memory reference, apparently due to some generic # | device device added to drivers/ide/ide.c. It does not appear to # | be due to this patch. # | # | The patch is a net deletion of one line. # | # -------------------------------------------- # 03/01/24 warlord@mit.edu 1.925.30.6 # [IPSEC]: Block on connect for IPSEC keying. # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.2 # kbuild: Remove -DEXPORT_SYMTAB switch # # rusty's module rewrite removed the reference to EXPORT_SYMTAB # from linux/module.h, and it's not used anywhere else, either. # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.3 # kbuild: Remove obsolete CONFIG_MODVERSIONS cruft # # Though the CONFIG_MODVERSIONS option was removed with rusty's module # rewrite and the associated code broken, a lot of that code was still # living on here and there. Now it's gone for good. # -------------------------------------------- # 03/01/24 davidm@tiger.hpl.hp.com 1.925.31.8 # ia64: Sync up with 2.5.59. # Add light-weight version of set_tid_address() system call. # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.4 # kbuild: Add CONFIG_MODVERSIONING and __kcrctab # # This patch adds the new config option CONFIG_MODVERSIONING which will # be the new way of checking for ABI changes between kernel and module # code. # # This and the following patches are in part based on an initial # implementation by Rusty Russell and I believe some of the ideas go back # to discussions on linux-kbuild, Keith Owens and Rusty. # # though I'm not sure I think credit for the basic idea of # storing version info in sections goes to Keith Owens and Rusty. # # o Rename __gpl_ksymtab to __ksymtab_gpl since that looks more consistent # and appending _gpl instead of putting it into the middle simplifies # sharing code for EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL() # o Add CONFIG_MODVERSIONING # o If CONFIG_MODVERSIONING is set, add a section __kcrctab{,_gpl}, which # contains the ABI checksums for the exported symbols listed in # __ksymtab{,_crc} Since we don't know the checksums yet at compilation # time, just make them an unresolved symbol which gets filled in by the # linker later. # -------------------------------------------- # 03/01/24 davidm@tiger.hpl.hp.com 1.925.31.9 # ia64: More vmlinux.lds.S cleanups. # -------------------------------------------- # 03/01/24 manish@Zambeel.com 1.925.6.13 # [netdrvr tg3] add support for another 5704 board, fix up 5704 phy init # -------------------------------------------- # 03/01/24 jgarzik@redhat.com 1.925.6.14 # [netdrvr tg3] more verbose failures, during initialization # -------------------------------------------- # 03/01/24 davidm@tiger.hpl.hp.com 1.925.31.10 # ia64: Switch over to using place-relative ("ip"-relative) entries in # the exception table. # -------------------------------------------- # 03/01/24 scott.feldman@intel.com 1.925.6.15 # [netdrvr e1000] ethtool eeprom buffer dynamic allocation, # rather than large static allocation on the stack # -------------------------------------------- # 03/01/24 scott.feldman@intel.com 1.925.6.16 # [netdrvr e1000] remove /proc support (superceded by ETHTOOL_GSTATS) # -------------------------------------------- # 03/01/24 scott.feldman@intel.com 1.925.6.17 # [netdrvr e1000] add ETHTOOL_GSTATS support # -------------------------------------------- # 03/01/24 scott.feldman@intel.com 1.925.6.18 # [netdrvr e1000] TSO fixes and cleanups: # # * Bug fix: TSO s/w workaround for premature desc write-back by h/w. h/w # was indicating desc done before DMA is complete, causing resources to # be returned to OS too early. Bad things happen then. # * Bug fix: Not time-stamping descriptors for fragmented sends. Could # cause false hang-detection. # * Removed unecessary #ifdefs # -------------------------------------------- # 03/01/24 robert.olsson@data.slu.se 1.925.6.19 # [netdrvr e1000] NAPI fixes: # # * e1000_irq_disable was used to disable irqs which called # synchronize_irq which in turn caused a solid hang on SMP # systems. # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.5 # kbuild: Generate versions for exported symbols # # Up to now, we had a way to store the checksums associated with the # exported symbols, but they were not filled in yet. This is done # with this patch, using the linker to actually do that for us. # # The comment added with this patch explains what magic exactly is going # on. # -------------------------------------------- # 03/01/24 davidm@tiger.hpl.hp.com 1.925.31.11 # ia64: Check for acceptable version of gas before trying to build # the kernel. Old gas versions will result in buggy kernels # that will bugcheck all over the place (usually mount() is # the first one to fail). # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.6 # kbuild/modules: Check __vermagic for validity # # modprobe --force allows to load modules without a matching version # magic string. This invalidation is done by clearing the SHF_ALLOC # flag, so check it in the kernel. Also, clear the SHF_ALLOC flag # unconditionally, since we don't need to store the __vermagic section # in the kernel, it's only checked once at load time. # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.7 # kbuild/modules: Don't save the license string # # Again, the license string is only used at load time, so no need # to store it permanently in kernel memory. # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.8 # kbuild/modules: Track versions of exported symbols # # Store the information on the checksum alongside the rest of the # information on exported symbols. To actually use them, we need # something to check them against first, though ;) # # Also, fix some conditional debug code to actually compile. # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.9 # kbuild: Always link module (.ko) from associated (.o) # # For extracting the versions and finding the unresolved symbols, we # need multi-part modules to be linked together already, so this # patch separates the building of the modules as a .o file from generating # the .ko in the next step. # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.10 # kbuild: Don't build final .ko yet when descending with CONFIG_MODVERSIONING # # With CONFIG_MODVERSIONING, we need to record the versions of the unresolved # symbols in the final .ko, which we only know after we finished # the descending build. So we only build .o in that case. # # Also, keep track of the modules we built, the post-processing step needs # a list of all modules. Keeping track is done by touching # .tmp_versions/path/to/module.ko # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.11 # kbuild/modules: Record versions for unresolved symbols # # In the case of CONFIG_MODVERSIONING, the build step will only # generate preliminary .o objects, and an additional # postprocessing step is necessary to record the versions of the unresolved # symbols and add them into the final .ko # # The version information for unresolved symbols is again recorded into # a special section, "__versions", which contains an array of symbol # name strings and checksum (struct modversion_info). Size is here not # an issue, since this section will not be stored permanently in kernel # memory. # # Makefile.modver takes care of the following steps: # o Collect the version information for all exported symbols from vmlinux # and all modules which export symbols. # o For each module, generate a C file which contains the modversion # information for all unresolved symbols in that module. # o For each module, compile that C file to an object file # o Finally, link the .ko using the preliminary + the # version information above. # # The first two steps are currently done by not very efficient scripting, # so there's room for performance improvement using some helper C code. # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.12 # kbuild/modules: Return the index of the symbol from __find_symbol() # # We'll need that index to find the version checksum for the symbol in # a bit. # -------------------------------------------- # 03/01/24 kai@tp1.ruhr-uni-bochum.de 1.925.12.13 # kbuild/modules: Check module symbol versions on insmod # # Yeah, the final step! # # Now that we've got the checksums for the exported symbols and the # checksums of the unresolved symbols for the module we're loading, # let's compare and see. # # Again, we allow to load a module which has the version info stripped, # but taint the kernel in that case. # -------------------------------------------- # 03/01/25 rmk@flint.arm.linux.org.uk 1.925.21.6 # [ARM] Drop "alloc" flag for the .stack segment. # # Some linkers obey the linker script and make .stack unallocatable, # others obey the flags from the object files. Dropping "a" should # make the end result deterministic in all cases. # -------------------------------------------- # 03/01/25 rmk@flint.arm.linux.org.uk 1.925.21.7 # [ARM] Add one CPU device to the driver model. # # Since CPUFreq now uses the driver model, we need to register a CPU # device with the driver model. # -------------------------------------------- # 03/01/25 rmk@flint.arm.linux.org.uk 1.925.21.8 # [ARM] Kill build warnings for Integrator PCI V3 driver. # -------------------------------------------- # 03/01/25 rmk@flint.arm.linux.org.uk 1.925.21.9 # [ARM] Fix KSTK_EIP and KSTK_ESP macros # # These two macros got missed when converting from the task-struct on # stack to thread_info-struct on stack. # -------------------------------------------- # 03/01/25 rmk@flint.arm.linux.org.uk 1.925.21.10 # [ARM] Add extra IO functionality. # # Add {read,write}[bwl] functionality to Acorn RISC PC. Add # {read,write}s[bwl] functionality for all. # -------------------------------------------- # 03/01/25 kai@tp1.ruhr-uni-bochum.de 1.925.12.14 # kbuild: Add cscope support to Makefile # # We support tags and TAGS already, so... # # by Louis Zhuang # -------------------------------------------- # 03/01/25 kai@tp1.ruhr-uni-bochum.de 1.925.12.15 # kbuild: gcc-3.3 warns about 2.5.59 EXPORT_SYMBOL # # When building linux-2.5.59 with gcc-3.3 (on s390, if that matters), # I get a warning like "warning: `__ksymtab___foo' defined but # not used" each time that EXPORT_SYMBOL is used. # # by Arnd Bergmann # -------------------------------------------- # 03/01/25 kai@tp1.ruhr-uni-bochum.de 1.925.12.16 # kbuild: Move the definition of MODVERDIR # # MODVERDIR was defined in the build-only section, but it's needed for # "make mrproper" as well. # -------------------------------------------- # 03/01/26 sam@mars.ravnborg.org 1.925.33.1 # kbuild: arch{mrproper,clean} no longer mandatory # # archmrproper and archclean is declared .PHONY in top-level Makefile, # therefore they are no longer mandatory in arch/$(ARCH)/Makefile. # -------------------------------------------- # 03/01/26 sam@mars.ravnborg.org 1.925.33.2 # kbuild/all archs: Removed unused arch{clean,rproper} targets # # The recent change in the top level makefile allowed this clean-up in all # the architecture specific Makefiles. # No functional changes, just deleted the now optional targets # -------------------------------------------- # 03/01/26 rmk@flint.arm.linux.org.uk 1.925.21.11 # [ARM] Convert ecard to allow use of ioremap + {read,write}[bwl] # -------------------------------------------- # 03/01/26 jejb@mulgrave.(none) 1.925.32.3 # [SCSI] make echo scsi add-single-device x x x x > /proc/scsi/scsi work again # # Correct the logic error making it fail # -------------------------------------------- # 03/01/26 sam@mars.ravnborg.org 1.925.33.3 # kbuild: HEAD replaced with head-y # # In arch/$(ARCH)/Makefile the objects to be linked as the very first are specified with HEAD. # To make more consistent naming, and to allow smarter kbuild style declarations # HEAD is replaced with head-y. # Support for the old notaion is kept for now. # Only i386 updated. # -------------------------------------------- # 03/01/26 sam@mars.ravnborg.org 1.925.33.4 # kbuild/all archs: Replace HEAD with head-y # # Replace done for all archs except mips* and cris. # These architectures are lacking too much behind that it made sense # -------------------------------------------- # 03/01/26 sam@mars.ravnborg.org 1.925.33.5 # kbuild: Update Documentation/kbuild/makefiles.txt # # makefiles.txt brought up-to-date with the changes that has occured # in kbuild within the last couple of months. # Restructured to present relevant info earlier, and rewritten the # architecture specific section to a certain degree. # # One change in style is that makefiles used throughout the kernel tree is called # "kbuild makefiles", because they follow the kbuild syntax. # Old notation was "subdirectory makefiles". # # There is added a TODO section, if anyone feel tempted to add a bit more text. # -------------------------------------------- # 03/01/26 sam@mars.ravnborg.org 1.925.33.6 # Documentation/modules.txt: How to compile modules outside the kernel tree # # Updated documentation/modules.txt with the following: # o Default config target is menuconfig # o Documented INSTLL_MOD_PATH # o Referenced to kernel 2.4 # o How to compile modules outside the kernel tree # # There is a lot of stuff in need for updating, this is first step # -------------------------------------------- # 03/01/26 sam@mars.ravnborg.org 1.925.33.7 # kbuild: Removed Documentation/kbuild/bug-list.txt # # The bugs listed was no longer relevant. # Also updated OO-INDEX # -------------------------------------------- # 03/01/26 rmk@flint.arm.linux.org.uk 1.925.21.12 # [ARM] Update Acorn SCSI drivers # # - Add scsi devclass support. # - Convert to use ioremap and friends. # - Fix oops which can occur when driver claims interrupt, and there's # an interrupt pending - move to a two-level fas driver initialisation. # -------------------------------------------- # 03/01/26 sam@mars.ravnborg.org 1.925.33.8 # kbuild: Enable the syntax "make dir/" # # "make dir/" is used to build a subsystem without going through the # full kernel tree, neither completing the build. # This is solely useful during development, when focus is on a # single subsystem. # This is the counterpart to "make dir/module.ko" # -------------------------------------------- # 03/01/26 sam@mars.ravnborg.org 1.925.33.9 # kbuild: Made cmd_link_multi readable # # Introduced ld_flags, and separated out the common parts of link_multi # for normal and module objects. # Added a bit of a comment as well # -------------------------------------------- # 03/01/26 sam@mars.ravnborg.org 1.925.33.10 # kbuild: ld_flags used consistently in Makefile.build # -------------------------------------------- # 03/01/26 rmk@flint.arm.linux.org.uk 1.925.21.13 # [ARM] Add linux/errno.h include to allow pcf8583.c to build. # -------------------------------------------- # 03/01/27 rmk@flint.arm.linux.org.uk 1.925.21.14 # [ARM] Remove 200Hz -> 100Hz conversion for ebsa110 timer. # # We now really run the ebsa110 kernel timer at 200Hz, and convert # where necessary to 100Hz for user space. # -------------------------------------------- # 03/01/27 rmk@flint.arm.linux.org.uk 1.925.21.15 # [ARM] Include ARM architecture version in module "version" string # -------------------------------------------- # 03/01/27 petkan@users.sourceforge.net 1.925.20.13 # [PATCH] USB: pegasus & mii cset # # Some ethernet drivers other than those in .../drivers/net need generic # MII code too and this cset shows how we do it for .../drivers/usb/net; # For now only pegasus.c is using this feature, but as soon as we find # more MII compliant controllers we'll put them in Makefile.mii too. # Note: drivers which use the generic mii routines should bracket the # code with #ifdef CONFIG_MII #endif since CONFIG_MII may not be present. # See pegasus.c for more details. # -------------------------------------------- # 03/01/27 david-b@pacbell.net 1.925.20.14 # [PATCH] USB ohci-hcd, don't force SLAB_ATOMIC allocations # # This is a minor cleanup to let per-request memory allocations block, # when the caller allows (it provided the bitmask). The driver used # to work that way until something like 2.4.3; an update (a few months # back) to how the "dma_addr_t" hashes to a "struct ohci_td *" lets us # simplify things again. Another benfit: it blocks irqs for less time # on the submit path. (The ehci driver already acts this way.) # -------------------------------------------- # 03/01/27 david-b@pacbell.net 1.925.20.15 # [PATCH] USB: usbcore misc cleanup (notably for non-dma hcds) # # The support for non-dma HCDs is likely the most interesting bit here. # # - makes dma calls behave sensibly when used with host controllers # that don't use dma (including sl811). usb_buffer_map() is a nop # while scatterlist dma mappings fail (as they must). # # - make usb_sg_init() behave sensibly when used with non-dma hcs. # the urbs are initted with transfer_buffer, not transfer_dma. # this is the higher level analogue to usb_buffer_map(), so it # needs to succeed unless there's a Real Error (tm). # # - moves two compatibility inlines from ehci.h into hcd.h so # it'll be more practical to have the other hcds work in other # environments (notably lk 2.4) too # # - remove URB_TIMEOUT_KILLED flag ... no device driver tests it; # hcds don't really (uhci sets it, never reads it; sl811 doesn't # enable the path that might set it), and it's not well defined. # if any hcd needs such state, keep it in hc-private storage. # # - in usb_sg_wait(), use yield() instead of schedule() to let # other activities free resources needed to continue. (This # was noted recently by Oliver.) # -------------------------------------------- # 03/01/27 andmike@us.ibm.com 1.925.32.4 # [SCSI] fix scsi_find_device() # -------------------------------------------- # 03/01/27 perex@suse.cz 1.925.34.1 # ALSA update # - removed some 2.2 code # - PCM - fixed memory leak for 24-bit samples # - gameport cleanups (CS4231, ENS1370/1371, SonicVibes, Trident) # - VIA82xx - fixed current pointer calculation # - sound_firmware - fixed errno problem # - USB - moved out compatibility code # # -------------------------------------------- # 03/01/27 shaggy@shaggy.austin.ibm.com 1.925.11.3 # JFS: Minor update in Documentation/filesystems/jfs.txt # # linuxjfs email address is obsolete. Updating todo list # -------------------------------------------- # 03/01/27 perex@suse.cz 1.925.34.2 # ALSA update # - added DocBook documentation # - added many source comments # - simplified proc style interface (per card) # - updated PCM scatter-gather routines # - moved PM locking outside callbacks # -------------------------------------------- # 03/01/27 zaitcev@redhat.com 1.925.10.4 # [SUN PARTITION]: Advance slot properly while scanning. # -------------------------------------------- # 03/01/27 zaitcev@redhat.com 1.925.10.5 # [SPARC]: Kill smp_found_cpus declaration. # -------------------------------------------- # 03/01/27 perex@suse.cz 1.925.34.3 # ALSA update # - added documentation for OSS emulation # - CMI8330 - duplex/mixer cleanups # - via82xx - rewritten for 8233+ (multiple playback, S/PDIF, secondary capture) # - USB - quirk code update # -------------------------------------------- # 03/01/27 davidm@tiger.hpl.hp.com 1.925.31.12 # ia64: Fix typo. # -------------------------------------------- # 03/01/27 perex@suse.cz 1.925.34.4 # ALSA update # - updated programmer's documentation # - recoded PCM scatter-gather memory management # - MPU401 - cleanups # - CMI8330 - cleanups # - EMU10K1 - Audigy2 update # - ENS1371 - added surround support # - USB - added more quirks and improved PCM constraint definitions # -------------------------------------------- # 03/01/27 davem@nuts.ninka.net 1.925.30.7 # [TCP]: Add tcp_low_latency sysctl. # Currently it turns of prequeue processing, but more decisions # may be guided by it in the future. # Based upon a patch from Andi Kleen. # -------------------------------------------- # 03/01/28 vojtech@suse.cz 1.925.20.16 # [PATCH] USB: Add an entry in cdc-acm.c for devices with ACM class (some Motorola phones) # # Normally the CDC ACM devices have an subclass of 0, and the ACM subclass is # only applied to their first interface. But some have the subclass set on # the device itself, namely Motorola mobile phones. This patch takes those # devices into account. # -------------------------------------------- # 03/01/28 vojtech@suse.cz 1.925.20.17 # [PATCH] USB: additions to hid-core.c blacklist # -------------------------------------------- # 03/01/28 jejb@raven.il.steeleye.com 1.925.4.15 # Merge # -------------------------------------------- # 03/01/28 luben@splentec.com 1.838.181.3 # cmd_alloc54-3.patch [3/3] # # this patch implements the new command allocation scheme for SCSI # Core, using the slab cache and a free_list for each host for a # backup store of one command (or many). # # o The three (3) subversion means that it has been updated to use # ISA DMA and PCI DMA memory for scsi command allocation, # i.e. there's two scsi command caches now. # # o The interface is, of course, unchanged; and this is the whole # point of making this allocation scheme -- i.e. the allocator # is abstracted. # # -------------------------------------------- # 03/01/28 jejb@raven.il.steeleye.com 1.925.35.1 # Merge raven.il.steeleye.com:/home/jejb/BK/scsi-cmd-changes-old-2.5 # into raven.il.steeleye.com:/home/jejb/BK/scsi-cmd-changes-2.5 # -------------------------------------------- # 03/01/28 jejb@raven.il.steeleye.com 1.925.35.2 # Merge raven.il.steeleye.com:/home/jejb/BK/scsi-cmd-changes-2.5.54 # into raven.il.steeleye.com:/home/jejb/BK/scsi-cmd-changes-2.5 # -------------------------------------------- # 03/01/28 perex@suse.cz 1.925.34.5 # ALSA update # - fixed makefiles for sequencer modules: # when CONFIG_SND_SEQUENCER is m, then synth modules should be m, too # -------------------------------------------- # 03/01/28 jejb@raven.il.steeleye.com 1.925.4.16 # Merge raven.il.steeleye.com:/home/jejb/BK/scsi-aic-2.5 # into raven.il.steeleye.com:/home/jejb/BK/scsi-combine-2.5 # -------------------------------------------- # 03/01/28 jejb@raven.il.steeleye.com 1.925.4.17 # Merge by hand # -------------------------------------------- # 03/01/28 davem@nuts.ninka.net 1.925.10.6 # [SPARC64]: Kill references to hugepage syscalls. # -------------------------------------------- # 03/01/28 eranian@hpl.hp.com 1.925.31.13 # [PATCH] ia64: fix PSR bug in perfmon code and switch to C99 initializers # # Please apply this small patch to your 2.5.59. # It fixes the psr problem reported by the NEC guy and also cleans # up the structure intializations in the model specific files. # -------------------------------------------- # 03/01/28 arun.sharma@intel.com 1.925.31.14 # [PATCH] ia64: make hugetlb support work again # # -------------------------------------------- # 03/01/28 jejb@mulgrave.(none) 1.925.4.18 # [SCSI] Correct command leaks in the prep_fn # -------------------------------------------- # 03/01/28 eranian@hpl.hp.com 1.925.31.15 # [PATCH] ia64: fix return type of sys_perfmonctl() # # -------------------------------------------- # 03/01/28 kuznet@ms2.inr.ac.ru 1.925.30.8 # [TCP]: Do not forget data copy while collapsing retransmission queue. # -------------------------------------------- # 03/01/29 anton@samba.org 1.930 # ppc64: some small optimisations # -------------------------------------------- # 03/01/29 anton@samba.org 1.931 # ppc64: restore non rt signals, we need to verify that older 64bit glibcs dont use them # -------------------------------------------- # 03/01/29 anton@samba.org 1.932 # ppc64: Preparation work for minimal register save/restore exception paths # -------------------------------------------- # 03/01/29 anton@samba.org 1.933 # ppc64: Fix compile with CONFIG_DEBUG_KERNEL disabled, from David Altobelli # -------------------------------------------- # 03/01/29 anton@samba.org 1.934 # ppc64: rtas proc fixes from David Altobelli # -------------------------------------------- # 03/01/29 anton@samba.org 1.935 # ppc64: defconfig update # -------------------------------------------- # 03/01/29 shaggy@shaggy.austin.ibm.com 1.925.11.4 # JFS: Implement get_index_page to replace some uses of read_index_page # # A recent change added the function read_index_page to replace calls to # read_metapage() when accessing the directory index table. However, we # replaced both calls to read_metapage() and get_metapage() with the same # function, but we really need two. In addition to unnecesary disk reads, # this problem caused an oops in __get_metapage(). # -------------------------------------------- # 03/01/29 rmk@flint.arm.linux.org.uk 1.925.21.16 # [ARM PATCH] 1361/1: EPXA10DB: Correct some typos in uart00.c # # Patch from Dirk Behme # # Patch some typos in uart00.c. frame is selected with FE_MSK and for OE_MSK rds # must be used. # -------------------------------------------- # 03/01/29 rmk@flint.arm.linux.org.uk 1.925.21.17 # [ARM PATCH] 1348/1: Add support for the HackKit board # # Patch from Stefan Eletzhofer # # This patch adds basic support for the HackKit Core CPU Board. # -------------------------------------------- # 03/01/29 davidm@tiger.hpl.hp.com 1.925.31.16 # ia64: Fix ARCH_DLINFO. # -------------------------------------------- # 03/01/29 davidm@tiger.hpl.hp.com 1.925.31.17 # ia64: Add light-weight version of getppid(). Detect at boottime whether the # McKinley Erratum 9 workaround is needed and, if not, patch the workaround # bundles with NOPs. # -------------------------------------------- # 03/01/30 dougg@torque.net 1.925.32.5 # [SCSI] Add length checking to sprintf in sg # -------------------------------------------- # 03/01/31 david-b@pacbell.net 1.925.20.18 # [PATCH] USB: ehci-hcd updates # # This should apply to 2.5.59 too. It seems to get rid of some pesky # hangs, on at least some hardware, but I won't have time to test it # on either VIA version ... maybe someone else will make the time? :) # # New QH state prevents a re-activation race # - nobody can un-halt a qh before its cleanup is done # - resubmit-from-completion had this race (some usbtest cases) # as could some normal submit paths on busy endpoints (storage) # - faster controllers would trip on this more consistently # # Queues of qtds # - work harder to avoid ever modifing any qh in software # - short reads block queue advance much less often # - be more cautious with large (>~19KB) unaligned buffers # # Unlinking urbs # - if qtd unlinked is at queue head, use its latest status # (main effect is reporting bytes from partial transfers) # - another new qh state: defer qh unlink if IAA is busy # (eliminates a busy-wait loop in a rare scenario) # # Enable features to improve bus utilization # - PCI MWI ... can produce better write throughput; and by # using right cacheline size, sometimes read throughput too # - USB NAK throttle ... sometimes reduces PCI access rates # # Other # - async dump shows more funky qh+qtd states, and NAK count # - cope with with some of the sprintf wierdness # - periodic dump is usually smaller (so is that schedule) # - minor cleanups # -------------------------------------------- # 03/01/31 baldrick@wanadoo.fr 1.925.20.19 # [PATCH] USB speedtouch: add a new speedtouch encoding function # # speedtouch: add a new encoding function, atmsar_encode. Calling it amounts to doing # atmsar_encode_aal5 followed by atmsar_encode_rawcell in one fell swoop. It eliminates # the need for intermediate buffers and reduces memory movement. The following patches # use it to simplify the send logic (and get rid of those annoying little oopsen). # -------------------------------------------- # 03/01/30 davem@nuts.ninka.net 1.925.30.9 # [TCP]: In tcp_check_req, handle ACKless packets properly. # -------------------------------------------- # 03/01/31 anton@samba.org 1.936 # ppc64: Fix my overoptimisation of zeroing RESULT. Yes Linus, it # was all my fault. # -------------------------------------------- # 03/01/31 akpm@digeo.com 1.925.30.10 # [IPV4]: Kill bogus semicolon in fib_get_next. # -------------------------------------------- # 03/02/01 rmk@flint.arm.linux.org.uk 1.925.21.18 # [ARM PATCH] 1097/3: trizeps IDE support # # Patch from Guennadi Liakhovetski # # The enclosed patch includes trizeps-specific IDE code. It adds a # Trizeps-specific section to asm/arch/ide.h. The patch is built # against 2.5.44-rmk1. # -------------------------------------------- # 03/02/01 rmk@flint.arm.linux.org.uk 1.925.21.19 # [ARM PATCH] 1096/4: trizeps PCMCIA support # # Patch from Guennadi Liakhovetski # # A minor update, trizeps.h has to be included explicitely now, since # platform-specific headers are commented out in hardware.h # -------------------------------------------- # 03/02/01 rmk@flint.arm.linux.org.uk 1.925.21.20 # [ARM PATCH] 1091/3: support for trizeps board (SA1110-based) # # Patch from Guennadi Liakhovetski # # The enclosed patch includes support for the trizeps board, based on the # StrongARM-1110 CPU, machine number 74. The patch is built against # 2.5.44-rmk1. Only the core files - from arch/arm and # include/asm-arm directories. # -------------------------------------------- # 03/02/01 rmk@flint.arm.linux.org.uk 1.925.21.21 # [ARM] Make trizeps_map_io static. # -------------------------------------------- # 03/02/01 rmk@flint.arm.linux.org.uk 1.925.21.22 # [ARM] Ensure GCC uses frame pointers when we want them. # # ARM GCC 2.95 generates frame pointers by default. GCC 3.2.x seems # to require some persuasion to generate them, despite being required # for debugging. # -------------------------------------------- # 03/02/01 rmk@flint.arm.linux.org.uk 1.925.21.23 # [ARM] Add missing #endif # -------------------------------------------- # 03/02/01 rmk@flint.arm.linux.org.uk 1.925.21.24 # [ARM] Remove IRQ desc->enabled in favour of testing disable_depth # -------------------------------------------- # 03/02/01 davem@nuts.ninka.net 1.925.6.20 # [TG3]: Let chip do pseudo-header csum on rx. # -------------------------------------------- # 03/02/01 davem@nuts.ninka.net 1.925.6.21 # [TG3]: Add device IDs for 5704S/5702a3/5703a3. # -------------------------------------------- # 03/02/01 davem@nuts.ninka.net 1.925.6.22 # [TG3]: Prevent dropped frames when flow-control is enabled. # -------------------------------------------- # 03/02/01 davem@nuts.ninka.net 1.925.6.23 # [TG3]: Correct MIN_DMA and ONE_DMA settings in dma_rwctrl. # -------------------------------------------- # 03/02/01 davem@nuts.ninka.net 1.925.6.24 # [TG3]: Workaround 5701 back-to-back register write bug. # -------------------------------------------- # 03/02/01 davem@nuts.ninka.net 1.925.6.25 # [TG3]: Add workaround for third-party phy issues. # -------------------------------------------- # 03/02/01 davem@nuts.ninka.net 1.925.6.26 # [TG3]: Remove anal grc_misc_cfg board IDs check. # -------------------------------------------- # 03/02/01 davem@nuts.ninka.net 1.925.6.27 # [TG3]: Fix typos in previous changes. # -------------------------------------------- # 03/02/01 jgarzik@redhat.com 1.925.6.28 # [netdrvr tg3] bump version, tidy comments # # No code changes in this patch, just cleanup and version bump. # -------------------------------------------- # 03/02/01 scott.feldman@intel.com 1.925.6.29 # [netdrvr e100] math fixes and a cleanup: # * Use correct math to calc timeout value passed to schedule_timeout # * Change "walkaround" to "workaround" # -------------------------------------------- # 03/02/02 wriede@riede.org 1.925.32.6 # [osst] fix bugzilla 244 (SRpnt initialisation problem) # # see http://bugzilla.kernel.org/show_bug.cgi?id=244 # -------------------------------------------- # 03/02/02 torvalds@home.transmeta.com 1.925.10.7 # Merge bk://kernel.bkbits.net/davem/sparc-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/02 torvalds@home.transmeta.com 1.925.10.8 # Make threaded core-dump names use the tgid instead of the pid. Makes # sense now that we can dump all threads in one core-dump. # # Fix from MAEDA Naoaki # -------------------------------------------- # 03/02/02 torvalds@home.transmeta.com 1.925.10.9 # Atyfb_base compile fix from Andres Salomon # -------------------------------------------- # 03/02/02 torvalds@home.transmeta.com 1.925.10.10 # Merge http://linux-sound.bkbits.net/linux-sound # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/02 rmk@flint.arm.linux.org.uk 1.925.21.25 # [ARM] Add arch/arm/common # # Certain support files are shared between various ARM machine classes. # In other to sanely support these, we place the shared files in # arch/arm/common instead of the individual machine class directories. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.1 # [PATCH] Fix data loss problem due to sys_sync # # In 2.5.52 I broke sys_sync() for ext2 in subtle ways. # # sys_sync() will set mapping->dirtied_when non-zero against a clean inode. # Later, in (say) __iget(), that inode gets moved over to inode_unused or # inode_in_use. But because it has non-zero ->dirtied_when, # __mark_inode_dirty() thinks that the inode must still be on sb->s_dirty. # # But it isn't. It's on inode_in_use. It (and its pages) never get written # out and the data gets thrown away on unmount. # # The patch ceases to use ->dirtied_when as an indicator of inode dirtiness. # Not sure why I even did that :( # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.2 # [PATCH] direct-IO: fix i_size handling on ENOSPC # # When an appending O_DIRECT write hits ENOSPC we're returning a short write # which is _too_ short. The file ends up with an undersized i_size and fsck # complains. # # So update the return value with the partial result before bailing out. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.3 # [PATCH] Fix inode size accounting race # # Since Jan removed the lock_kernel()s in inode_add_bytes() and # inode_sub_bytes(), these functions have been racy. # # One problematic workload has been discovered in which concurrent writepage # and truncate on SMP quickly causes i_blocks to go negative. writepage() does # not take i_sem, and it seems that for ext2, there are no other locks in # force when inode_add_bytes() is called. # # Putting the BKL back in there is not acceptable. To fix this race I have # added a new spinlock "i_lock" to the inode. # # That lock is presently used to protect i_bytes and i_blocks. We could use it # to protect i_size as well. # # The splitting of the used disk space into i_blocks and i_bytes is silly - we # should nuke all that and just have a bare loff_t i_usedbytes. Later. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.4 # [PATCH] vmlinux fix # # Patch from: "H. J. Lu" # # Fixes a commonly-reported insmod oops. # # Move the ksymtab labels definitions inside the liker section, so they get the # right addresses. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.5 # [PATCH] Compile fix in sound/oss/maestro.c # # Patch from "Ph. Marek" # # Compile fix in sound/oss/maestro.c # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.6 # [PATCH] remove lock_kernel() from exec of setuid apps # # Patch from Manfred Spraul # # exec of setuid apps and ptrace must be synchronized, to ensure that a normal # user cannot ptrace a setuid app across exec. ptrace_attach acquires the # task_lock around the uid checks, compute_creds acquires the BLK. The patch # converts compute_creds to the task_lock. Additionally, it removes the # do_unlock variable: the task_lock is not heaviliy used, there is no need to # avoid the spinlock by adding branches. # # The patch is a cleanup patch, not a fix for a security problem: AFAICS the # sys_ptrace in every arch acquires the BKL before calling ptrace_attach. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.7 # [PATCH] properly handle too long pathnames in d_path # # Forward port of a 2.4 patch by Christoph Hellwig. # # See http://cert.uni-stuttgart.de/archive/bugtraq/2002/03/msg00384.html # for the security implications. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.8 # [PATCH] fix handling of ext2 allocation failures # # Patch from: Hugh Dickins # # For almost a year (since 2.5.4) ext2_new_block has tended to set err 0 # instead of -ENOSPC or -EIO. This manifested variously (typically depends on # what's stale in ext2_get_block's chain[4] array): sometimes __brelse free # free buffer backtraces, sometimes release_pages oops, usually # generic_make_request beyond end of device messages, followed by further ext2 # errors. # # [Insert lecture on dangers of using goto for unwind :-] # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.9 # [PATCH] ext2_new_block cleanups and fixes # # The general error logic handling in there is: # # *errp = -EFOO; # # if (some_error) # goto out; # # this is fragile and unmaintainable, because the setting of the error code is # "far away" from the site where the error was detected. # # And the code was actually wrong - we're returning ENOSPC in places where fs # metadata inconsistency was detected. We traditionally return -EIO in this # case. # # So change it all to do, effectively: # # if (some_error) { # *errp = -EFOO; # goto out; # } # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.10 # [PATCH] ext3: fix scheduling storm and lockups # # There have been sporadic sightings of ext3 causing little blips of 100,000 # context switches per second when under load. # # At the start of do_get_write_access() we have this logic: # # repeat: # lock_buffer(jh->bh); # ... # unlock_buffer(jh->bh); # ... # if (jh->j_list == BJ_Shadow) { # sleep_on_buffer(jh->bh); # goto repeat; # } # # The problem is that the unlock_buffer() will wake up anyone who is sleeping # in the sleep_on_buffer(). # # So if task A is asleep in sleep_on_buffer() and task B now runs # do_get_write_access(), task B will wake task A by accident. Task B will then # sleep on the buffer and task A will loop, will run unlock_buffer() and then # wake task B. # # This state will continue until I/O completes against the buffer and kjournal # changes jh->j_list. # # Unless task A and task B happen to both have realtime scheduling policy - if # they do then kjournald will never run. The state is never cleared and your # box locks up. # # # The fix is to not do the `goto repeat;' until the buffer has been taken of # the shadow list. So we don't go and wake up the other waiter(s) until they # can actually proceed to use the buffer. # # The patch removes the exported sleep_on_buffer() function and simply exports # an existing function which provides access to a buffer_head's waitqueue # pointer. Which is a better interface anyway, because it permits the use of # wait_event(). # # This bug was introduced introduced into 2.4.20-pre5 and was faithfully ported # up. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.11 # [PATCH] slab poison checking fix # # Spotted by Andries Brouwer. There's one place where slab is calling # check_poison_obj() but not reporting on any detected failure. # # We used to go BUG() in there. Convert it over to the kinder, gentler # slab_error() regime. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.12 # [PATCH] quota locking fix # # Quota locking fix from Jan Kara. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.13 # [PATCH] quota semaphore fix # # The second quota locking fix. Sorry, I seem to have misplaced the # changelog. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.14 # [PATCH] preempt spinlock efficiency fix # # Patch from: jak@rudolph.ccur.com (Joe Korty) # # The new, preemptable spin_lock() spins on an atomic bus-locking read/write # instead of an ordinary read, as the original spin_lock implementation did. # Perhaps that is the source of the inefficiency being seen. # # Attached sample code compiles but is untested and incomplete (present # only to illustrate the idea). # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.15 # [PATCH] Make fix sync_filesystems() actually do something # # Random semicolon makes the whole thing a no-op. # # It _did_ work. I must have broken it between testing and sending :( # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.16 # [PATCH] stack overflow checking fix # # Patch from William Lee Irwin III # # struct thread_info is shared with the stack, not struct task_struct. # False positives have been seen. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.17 # [PATCH] slab IRQ fix # # Patch from Manfred Spraul # # cache_alloc_refill() forgets to disable interrupts again on an error path. # This exposes us to slab corruption and it makes slab debugging go BUG (it # expects local irqs to be disabled). # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.18 # [PATCH] blkdev.h fixes # # Patch from William Lee Irwin III # # BLK_BOUNCE_HIGH and BLK_BOUNCE_ANY are compared against 64-bit quantities. # Cast these unsigned long quantities to avoid overflow. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.19 # [PATCH] symbol_get linkage fix # # Patch from Rusty Russell # # Make symbol_get() use undefined weak symbols if !CONFIG_MODULE. # Many thanks to RTH for introducing undef weak symbols to me. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.20 # [PATCH] i386 pgd_index() doesn't parenthesize its arg # # Patch from William Lee Irwin III # # pgd_index() doesn't parenthesize its argument. This is a bad idea for # macros, since it's legitimate to pass expressions to them that will get # misinterpreted given operator precedence and the shift. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.21 # [PATCH] kernel param and KBUILD_MODNAME name-munging mess # # Patch from: Rusty Russell # # Mikael Pettersson points out that "-s" gets mangled to "_s" on the # kernel command line, even though it turns out not to be a # parameter. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.22 # [PATCH] i386 pgd_index() doesn't parenthesize its arg # # Patch from William Lee Irwin III # # PAE's pte_none() and pte_pfn() evaluate their arguments twice; # analogous fixes have been made to other things; c.f. pgtable.h's long # list of one-line inlines with parentheses still around their args. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.23 # [PATCH] pcmcia timer initialisation fixes # # pcmcia timer initialisation fixes from Anton Blanchard # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.24 # [PATCH] correct wait accounting in wait_on_buffer() # # __wait_on_buffer() needs to use io_schedule(), so processes in there are # accounted as being in I/O wait. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.25 # [PATCH] atyfb compilation fix # # Patch from "Andres Salomon" # # Fix compilation of atyfb_base.c # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.26 # [PATCH] floppy locking fix # # redo_fd_request() needs to take the queue lock around the call to # elv_next_request(). # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.27 # [PATCH] soundcore.c referenced non-existent errno variable # # Patch from: Petr Vandrovec # # soundcore is trying to perform kernel syscalls to load firmware, but falls # afoul of missing `errno'. Convert it to use VFS API functions. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.28 # [PATCH] Fix generic_file_readonly_mmap() # # We cannot clear VM_MAYWRITE in there - it turns writeable MAP_PRIVATE # mappings into readonly ones. # # So change it back to the 2.4 form - disallow a writeable MAP_SHARED mapping # against filesystems which do not implement ->writepage(). # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.29 # [PATCH] exit_mmap fix for 64bit->32bit execs # # The recent exit_mmap() changes broke PPC64 when 64-bit applications exec # 32-bit ones. ia32-on-ia64 was broken as well # # What is happening is that load_elf_binary() sets TIF_32BIT (via # SET_PERSONALITY) _before_ running exit_mmap(). So when we're unmapping the # vma's of the old image, we are running under the new image's personality. # # This causes PPC64 to pass a 32-bit TASK_SIZE to unmap_vmas(), even when the # execing process had a 64-bit image. Because unmap_vmas() is not provided # with the correct virtual address span it does not unmap all the old image's # vma's and we go BUG_ON(mm->map_count) in exit_mmap(). # # The early SET_PERSONALITY() is required before we look up the interpreter # because the lookup of the executable has to happen under the alternate root # which SET_PERSONALITY() may set. # # Unfortunately this means that we're running flush_old_exec() under the new # exec's personality. Hence this bug. # # So what the patch does is to simply pass ~0UL into unmap_vmas(), which tells # it to unmap everything regardless of current personality. Which is what the # old open-coded VMA killer was doing. # # There remains the problem that some architectures are sometimes passing the # incorrect TASK_SIZE into tlb_finish_mmu(). They've always been doing that. # -------------------------------------------- # 03/02/02 akpm@digeo.com 1.925.36.30 # [PATCH] fix show_task oops # # Patch from Russell King # # show_task() attempts to calculate the amount of free space which hasn't been # written to on the kernel stack by reading from the base of the kernel stack # upwards. # # However, it mistakenly uses the task_struct pointer as the base of the stack, # which it isn't, and this can cause an oops. # # Here is a patch which uses the task thread pointer instead, which should be # located at the bottom of the kernel stack. It appears this was missed when # the thread structure was introduced. # -------------------------------------------- # 03/02/02 torvalds@home.transmeta.com 1.925.10.11 # Merge # -------------------------------------------- # 03/02/02 torvalds@home.transmeta.com 1.925.10.12 # Merge bk://bk.arm.linux.org.uk # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/02 jmorris@intercode.com.au 1.925.30.11 # [IPSEC]: remove trailer_len from esp and xfrm properties. # -------------------------------------------- # 03/02/02 jmorris@intercode.com.au 1.925.30.12 # [IPSEC]: Update ah documentation. # -------------------------------------------- # 03/02/02 jmorris@intercode.com.au 1.925.30.13 # [IPSEC] Convert esp auth to use proper crypto api calls. # -------------------------------------------- # 03/02/02 jmorris@intercode.com.au 1.925.30.14 # [IPSEC] Generic ICV handling for ESP. # -------------------------------------------- # 03/02/03 jgarzik@redhat.com 1.925.6.30 # Merge kernel.bkbits.net:net-drivers-2.5 # into redhat.com:/garz/repo/net-drivers-2.5 # -------------------------------------------- # 03/02/02 jmorris@intercode.com.au 1.925.30.15 # [CRYPTO]: in/out scatterlist support for ciphers. # - Merge scatterwalk patch from Adam J. Richter # API change: cipher methods now take in/out scatterlists and nbytes # params. # - Merge gss_krb5_crypto update from Adam J. Richter # - Add KM_SOFTIRQn (instead of KM_CRYPTO_IN etc). # - Add asm/kmap_types.h to crypto/internal.h # - Update cipher.c credits. # - Update cipher.c documentation. # -------------------------------------------- # 03/02/03 James.Bottomley@steeleye.com 1.925.6.31 # 3c509 fixes: correct MCA probing, add back ISA probe to Space.c # -------------------------------------------- # 03/02/02 cw@f00f.org 1.925.30.16 # [IPV6]: Fix tcp_v6_xmit prototype. # -------------------------------------------- # 03/02/03 devik@cdi.cz 1.925.30.17 # [NET_SCHED]: HTB scheduler updates from Devik. # - repaired htb_debug_dump call in htb_dequeue # - removed performance counter macros # - error report text fixes, new more precise mindelay error reporting # - minor fixes and cleanup # -------------------------------------------- # 03/02/03 ak@muc.de 1.925.30.18 # [IPV4]: Better behavior for NETDEV_CHANGENAME requests. # -------------------------------------------- # 03/02/03 davem@nuts.ninka.net 1.925.30.19 # [IPSEC]: Revert previous change to ip_route_connect. # -------------------------------------------- # 03/02/03 kunihiro@ipinfusion.com 1.925.30.20 # [XFRM]: Add family member to xfrm_usersa_id. # -------------------------------------------- # 03/02/03 Matt_Domsch@dell.com 1.925.5.6 # Merge dell.com:/home/mdomsch/bk/linux-2.5 # into dell.com:/home/mdomsch/bk/edd/linux-2.5-edd # -------------------------------------------- # 03/02/03 jejb@raven.il.steeleye.com 1.925.4.19 # Merge raven.il.steeleye.com:/home/jejb/BK/scsi-combined-2.5 # into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.5 # -------------------------------------------- # 03/02/03 jejb@raven.il.steeleye.com 1.925.4.20 # Merge raven.il.steeleye.com:/home/jejb/BK/scsi-misc-2.5 # into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.5 # -------------------------------------------- # 03/02/03 torvalds@home.transmeta.com 1.925.4.21 # Merge http://linux-scsi.bkbits.net/scsi-for-linus-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/03 rddunlap@osdl.org 1.925.4.22 # [PATCH] fix references to discarded sections # # After disabling files that wouldn't build, there were 2 (in-kernel) # modules that referenced _init or _exit code sections when they # shouldn't. # # This fixes those modules. # -------------------------------------------- # 03/02/03 lord@sgi.com 1.925.10.13 # [XFS] Transaction A is in callback processing unpinning a buffer, # Transaction B is in the process of marking the buffer stale. # Between transaction A dropping its reference and checking # the stale state, transaction B gets a reference and stales # the buffer. A ends up freeing the log item and releasing # the buffer. End result is we have a reference to free memory # and an unlocked buffer. # # SGI Modid: 2.5.x-xfs:slinx:137748a # -------------------------------------------- # 03/02/03 lord@sgi.com 1.925.10.14 # [XFS] Do not release the last iclog of a transaction before we get our # callbacks attached to it. Otherwise we can end up executing the # callback out of order. # # SGI Modid: 2.5.x-xfs:slinx:137750a # -------------------------------------------- # 03/02/03 hch@sgi.com 1.925.10.15 # [XFS] remove a dead codepath in xfs_syncsub # # SGI Modid: 2.5.x-xfs:slinx:138037a # -------------------------------------------- # 03/02/03 lord@sgi.com 1.925.10.16 # [XFS] fix initialization of bio in end case where we are dealing with sub page # sized requests. # # SGI Modid: 2.5.x-xfs:slinx:138201a # -------------------------------------------- # 03/02/03 agrover@groveronline.com 1.925.1.36 # Merge groveronline.com:/root/bk/linux-2.5 # into groveronline.com:/root/bk/linux-acpi # -------------------------------------------- # 03/02/03 kai@tp1.ruhr-uni-bochum.de 1.925.12.17 # kbuild: Rename CONFIG_MODVERSIONING -> CONFIG_MODVERSIONS # # CONFIG_MODVERSIONING was a temporary name introduced to distinguish # between the old and new module version implementation. Since the # traces of the old implementation are now gone from the build system, # we rename the config option back in order to not confuse users more # than necessary in 2.6. # # Also, remove some historic modversions cruft throughout the tree. # -------------------------------------------- # 03/02/03 kai@tp1.ruhr-uni-bochum.de 1.925.12.18 # kbuild: Generate module versions in the normal object directories # # We generated the intermediate files that contain checksums for # unresolved symbols in .tmp_versions, which had the disadvantage # that is obscured what's going on during the build. Just # generate them as .ver.[co] right next to the actual objects in the # object tree. # -------------------------------------------- # 03/02/03 rusty@rustcorp.com.au 1.925.12.19 # kbuild: Modversions fixes # # Fix the case where no CRCs are supplied (OK, but taints kernel), and # only print one tainted message (otherwise --force gives hundreds of them). # -------------------------------------------- # 03/02/03 rusty@rustcorp.com.au 1.925.12.20 # kbuild: Ignore kernel version part of vermagic if CONFIG_MODVERSIONS # # Skip over the first part of __vermagic in modversioning is on: otherwise # you'll have to force it when changing from 2.6.0 to 2.6.1. # -------------------------------------------- # 03/02/03 kai@tp1.ruhr-uni-bochum.de 1.925.4.23 # Hand merged # -------------------------------------------- # 03/02/03 kai@tp1.ruhr-uni-bochum.de 1.925.4.24 # Merge tp1.ruhr-uni-bochum.de:/scratch/kai/kernel/v2.5/linux-2.5.make-sam # into tp1.ruhr-uni-bochum.de:/scratch/kai/kernel/v2.5/linux-2.5.make # -------------------------------------------- # 03/02/03 kai@tp1.ruhr-uni-bochum.de 1.925.4.25 # kbuild: Assorted fixlets # # o Build modules with CONFIG_MODVERSIONS when just saying "make" # o Ignore generated *.ver.c files # o Fix a typo (Sam Ravnborg) # o Fix another typo (Paul Marinceu) # -------------------------------------------- # 03/02/03 kai@tp1.ruhr-uni-bochum.de 1.925.4.26 # kbuild: Remove export-objs := ... statements # # One of the goals of the whole new modversions implementation: # export-objs is gone for good! # -------------------------------------------- # 03/02/03 jfs.adm@hostme.bitkeeper.com 1.925.37.1 # Merge bk://linux.bkbits.net/linux-2.5 # into hostme.bitkeeper.com:/ua/repos/j/jfs/linux-2.5 # -------------------------------------------- # 03/02/03 shaggy@shaggy.austin.ibm.com 1.925.37.2 # Merge jfs@jfs.bkbits.net:linux-2.5 # into shaggy.austin.ibm.com:/shaggy/bk/jfs-2.5 # -------------------------------------------- # 03/02/03 torvalds@penguin.transmeta.com 1.925.4.27 # Merge http://jfs.bkbits.net/linux-2.5 # into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux # -------------------------------------------- # 03/02/03 agrover@groveronline.com 1.925.1.37 # ACPI: It is OK to not have a _PPC, so don't error out if it's not found # -------------------------------------------- # 03/02/04 greg@kroah.com 1.925.20.20 # [PATCH] USB: add a blank line between each device in usbfs/devices # -------------------------------------------- # 03/02/04 greg@kroah.com 1.925.20.21 # [PATCH] USB: fix to get usb-storage code to work again. # # Thanks to Matt Dharm and David Brownell for tracking this bug down. # -------------------------------------------- # 03/02/04 mdharm-usb@one-eyed-alien.net 1.925.20.22 # [PATCH] usb-storage: move to SCSI hotplugging # # The attached patch is my first implementation of SCSI hotplugging. # # It's only been tested that it compiles, as I can't get the current # linux-2.5 tree from linuxusb to boot. It dies _very_ early. Greg, I'm not # sure if you'll want to apply this. Linus seemed to want this very much, # and it is 2.5.x... I say go for it, but I can understand if you have # reservations. # # I would definately like to see this tested by anyone who can get a kernel # to boot. # # This patch is quite large. Lots of things had to be changed. Among them: # # (o) The proc interface now uses the host number to look up the SCSI host # structure, and then finds the usb-storage structure from that. # (o) The SCSI interface has been changed. The code flow is now much # clearer, as more work is done from the USB probe/detach functions than # from auxillary functions. # (o) Names have been changed for newer conventions # (o) GUIDs have been removed # (o) The linked-list of devices has been removed, and it's associated # semaphore # (o) All code dealing with re-attaching a device to it's old association has # been removed # (o) Some spaces changed to tabs # (o) usb-storage now takes one directory under /proc/scsi instead of # one per virtual-HBA # (o) All control threads now have the same name. This could be changed back # to the old behavior, if enough people want it. # # Known problems: # (o) Testing, testing, testing # (o) More dead code needs to be cut # (o) It's a unclear how a LLD is supposed to cut off the flow of # commands, so that the unregister() call always succeeds. SCSI folks # need to work on this. # (o) Probing needs to be broken down into smaller functions, probably. # -------------------------------------------- # 03/02/04 mdharm-scsi@one-eyed-alien.net 1.925.20.23 # [PATCH] usb-storage: fix typo # # This patch goes on top of the last one. It fixes a typo in the test for # scsi_register() failure. # # -- reversed the logic of failure test for scsi_register() # -------------------------------------------- # 03/02/04 mdharm-scsi@one-eyed-alien.net 1.925.20.24 # [PATCH] usb-storage: fix oops # # It should fix the OOPS on attach. # # This fixes a silly error where I fail to initialize a pointer early enough # for the scanning code. If this isn't a perfect example of why # scsi_register() and scsi_add_host() aren't two separate functions, I don't # know what is. :) # # Oh, and I added a couple of comments, too. # # - Fix an OOPS by moving the setting of the hostdata[] pointer to _before_ # the device scan starts. # -------------------------------------------- # 03/02/04 mdharm-usb@one-eyed-alien.net 1.925.20.25 # [PATCH] usb-storage: comments, cleanup # # This patch does the following: # (o) Add comments showing what needs to be done to complete the hot-unplug # system. # (o) Add a BUG_ON() for (what is now) a critical failure case. # (o) Make certain that a debug print happens even if a usb_get_intfdata() # crashes. # (o) Add an un-necessary up() to balance a down, for the auto-code-checkers. # -------------------------------------------- # 03/02/04 mdharm-usb@one-eyed-alien.net 1.925.20.26 # [PATCH] usb-storage: remove US_FL_DEV_ATTACHED # # This patch removes the US_FL_DEV_ATTACHED flag, which is now rendered # obsolete by the new hotplug system. # # It also adds a comment or two about areas of code that need to be # re-examined. # -------------------------------------------- # 03/02/04 mdharm-usb@one-eyed-alien.net 1.925.20.27 # [PATCH] usb-storage: convert spaces to tabs # # This is a minor cleanup to convert 8 spaces into tabs. There is no # functional change here. # -------------------------------------------- # 03/02/04 mdharm-usb@one-eyed-alien.net 1.925.20.28 # [PATCH] Replace a line of code that shouldn't have been removed. # -------------------------------------------- # 03/02/04 henning@meier-geinitz.de 1.925.20.29 # [PATCH] USB scanner.h, scanner.c: maintainer change # # This patch changes the maintainer from Brian Beattie to Henning # Meier-Geinitz and adds a link to the documentation and website. # -------------------------------------------- # 03/02/04 henning@meier-geinitz.de 1.925.20.30 # [PATCH] USB scanner.c: Adjust syslog output # # This patch prints the vendor + product ids of the scanner after it has # been successfully detected. # # Also the annoying error message about "Scanner device is already open" # was downgraded to a dbg. Scanning for devices while one scanner device # was open produced several 100 error messages in syslog. # -------------------------------------------- # 03/02/04 anton@samba.org 1.937 # Merge samba.org:/scratch/anton/linux-2.5 # into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/02/04 baldrick@wanadoo.fr 1.925.20.31 # [PATCH] USB speedtouch: let the tasklet do all processing of speedtouch receive urbs # # speedtouch: move all processing of receive urbs to udsl_atm_processqueue. This has # several advantages, as will be seen in the next few patches. The most important is # that it makes it easy to reuse of the urb's buffer (right now a new buffer is # allocated every time the urb completes). By the way, this patch is much smaller than # it looks: most of the bulk is due to indentation changes. # -------------------------------------------- # 03/02/04 baldrick@wanadoo.fr 1.925.20.32 # [PATCH] USB speedtouch: re-recycle speedtouch receive buffers # # Rediffed version of the original patch - no sk_buff on the stack this time. # # speedtouch: recycle the receive urb's buffer. Currently, every time a receive urb # completes, its old buffer is thrown away and replaced with a new one. This patch # performs the minor changes needed to reuse the old buffer. # -------------------------------------------- # 03/02/04 baldrick@wanadoo.fr 1.925.20.33 # [PATCH] USB speedtouch: re-recycle failed speedtouch receive urbs # # speedtouch: more robust handling of receive urb failure: retry failed urbs whenever # a new connection is opened. This should work well with pppd's persist option. # -------------------------------------------- # 03/02/04 baldrick@wanadoo.fr 1.925.20.34 # [PATCH] USB speedtouch: re-wait for speedtouch completion handlers after usb_unlink_urb # # speedtouch: wait for receive urb completion handlers to finish after calling # usb_unlink_urb. # -------------------------------------------- # 03/02/04 baldrick@wanadoo.fr 1.925.20.35 # [PATCH] USB speedtouch: re-cosmetic speedtouch changes # # speedtouch: a pile of cosmetic changes to make me feel happier (no code changes). # -------------------------------------------- # 03/02/04 baldrick@wanadoo.fr 1.925.20.36 # [PATCH] USB speedtouch: tweak speedtouch status logic # # speedtouch: change data_started to firmware_loaded, which is what it actually # means, plus some minor related changes. # -------------------------------------------- # 03/02/04 baldrick@wanadoo.fr 1.925.20.37 # [PATCH] USB speedtouch: allocate speedtouch send urbs in the USB probe routine # # speedtouch: allocate send urbs in udsl_usb_probe rather than in udsl_usb_data_init. # Since this diminishes udsl_usb_data_init down to almost nothing, roll it into the one # place it was used. Get rid of the semaphore Oliver put it - it is no longer needed. # # # speedtouch.c | 86 ++++++++++++++++++++++++++--------------------------------- # 1 files changed, 38 insertions(+), 48 deletions(-) # -------------------------------------------- # 03/02/04 baldrick@wanadoo.fr 1.925.20.38 # [PATCH] USB speedtouch: earlier rejection of outgoing speedtouch packets # # speedtouch: reject outgoing packets earlier when the firmware is not loaded. # -------------------------------------------- # 03/02/04 mdharm-usb@one-eyed-alien.net 1.925.20.39 # [PATCH] USB usb-storage: host a host refcount a little bit longer # # This patch makes us hold the host reference count a little bit longer in # the /proc interface code. We were releasing it too early before. # -------------------------------------------- # 03/02/04 mdharm-usb@one-eyed-alien.net 1.925.20.40 # [PATCH] USB usb-storage: implement device-offline code # # This code implements the setting of devices offline during the removal # phase. # -------------------------------------------- # 03/02/04 mdharm-usb@one-eyed-alien.net 1.925.20.41 # [PATCH] USB usb-storage: implement clearing of device queue # # This patch clears out the device queue when a unit is removed. # -------------------------------------------- # 03/02/04 p.guehring@futureware.at 1.925.20.42 # [PATCH] USB: FTDI driver, new id added # -------------------------------------------- # 03/02/04 greg@kroah.com 1.925.20.43 # [PATCH] USB: added tripp device id's to pl2303 driver. # # Thanks to John Moses for the information. # -------------------------------------------- # 03/02/04 anton@samba.org 1.938 # ppc64: fix UP compile # -------------------------------------------- # 03/02/04 anton@samba.org 1.937.1.1 # ppc64: module updates from Rusty # -------------------------------------------- # 03/02/04 anton@samba.org 1.939 # Merge samba.org:/scratch/anton/linux-2.5_ppc64_up # into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/02/04 davem@kernel.bkbits.net 1.925.4.28 # Merge davem@nuts.ninka.net:/home/davem/src/BK/net-2.5 # into kernel.bkbits.net:/home/davem/net-2.5 # -------------------------------------------- # 03/02/04 davem@nuts.ninka.net 1.925.38.1 # [SPARC]: Add ndelay. # -------------------------------------------- # 03/02/04 davem@nuts.ninka.net 1.925.38.2 # [FC4]: Update for scsi_cmnd changes. # -------------------------------------------- # 03/02/04 davem@nuts.ninka.net 1.925.38.3 # [SCSI ESP]: Update for scsi_cmnd changes. # -------------------------------------------- # 03/02/04 davem@nuts.ninka.net 1.925.38.4 # [SCSI QLOGICPTI]: Update for scsi_cmnd changes. # -------------------------------------------- # 03/02/04 davem@nuts.ninka.net 1.925.38.5 # [SCSI PLUTO/FCAL]: Update for scsi_cmnd changes. # -------------------------------------------- # 03/02/04 Matt_Domsch@dell.com 1.925.39.1 # Merge dell.com:/home/mdomsch/bk/linux-2.5 # into dell.com:/home/mdomsch/bk/edd/linux-2.5-edd # -------------------------------------------- # 03/02/04 nlaredo@transmeta.com 1.925.40.1 # [PATCH] stradis.c "proper" port to 2.5.x # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.41.1 # [PATCH] qlogic fix # # Linus's current BK tree needs the following build fix: # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.2 # [PATCH] implement posix_fadvise64() # # An implementation of posix_fadvise64(). It adds 368 bytes to my vmlinux and # is worth it. # # I didn't bother doing posix_fadvise(), as userspace can implement that by # calling fadvise64(). # # The main reason for wanting this syscall is to provide userspace with the # ability to explicitly shoot down pagecache when streaming large files. This # is what O_STEAMING does, only posix_fadvise() is standards-based, and harder # to use. # # posix_fadvise() also subsumes sys_readahead(). # # POSIX_FADV_WILLNEED will generally provide asynchronous readahead semantics # for small amounts of I/O. As long as things like indirect blocks are aready # in core. # # POSIX_FADV_RANDOM gives unprivileged applications a way of disabling # readahead on a per-fd basis, which may provide some benefit for super-seeky # access patterns such as databases. # # # # The POSIX_FADV_* values are already implemented in glibc, and this patch # ensures that they are in sync. # # A test app (fadvise.c) is available in ext3 CVS. See # # http://www.zip.com.au/~akpm/linux/ext3/ # # for CVS details. # # Ulrich has reviewed this patch (thanks). # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.3 # [PATCH] fix agp compile warning # # A static function in a header where presumably a static inline was intended. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.4 # [PATCH] add stats for page reclaim via inode freeing # # pagecache can be reclaimed via the page LRU and via prune_icache. We # currently don't know how much reclaim is happening via each. # # The patch adds instrumentation to display the number of pages which were # freed via prune_icache. This is displayed in /proc/vmstat:pginodesteal and # /proc/vmstat:kswapd_inodesteal. # # Turns out that under some workloads (well, dbench at least), fully half of # page reclaim is via the unused inode list. Which seems quite OK to me. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.5 # [PATCH] file-backed vma merging # # Implements merging of file-backed VMA's. Based on Andrea's 2.4 patch. # # It's only done for mmap(). mprotect() and mremap() still will not merge # VMA's. # # It works for hugetlbfs mappings also. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.6 # [PATCH] mm/mmap.c whitespace cleanups # # - Don't require a 160-col xterm # # - Coding style consistency # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.7 # [PATCH] cleanup in read_cache_pages() # # Patch from Nikita Danilov # # read_cache_pages() is passed a bunch of pages to start I/O against and it is # supposed to consume all those pages. But if there is an I/O error, someone # need to throw away the unused pages. # # At present the single user of read_cache_pages() (nfs_readpages) does that # cleanup by hand. But it should be done in the core kernel. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.8 # [PATCH] remove __GFP_HIGHIO # # Patch From: Hugh Dickins # # Recently noticed that __GFP_HIGHIO has played no real part since bounce # buffering was converted to mempool in 2.5.12: so this patch (over 2.5.58-mm1) # removes it and GFP_NOHIGHIO and SLAB_NOHIGHIO. # # Also removes GFP_KSWAPD, in 2.5 same as GFP_KERNEL; leaves GFP_USER, which # can be a useful comment, even though in 2.5 same as GFP_KERNEL. # # One anomaly needs comment: strictly, if there's no __GFP_HIGHIO, then # GFP_NOHIGHIO translates to GFP_NOFS; but GFP_NOFS looks wrong in the block # layer, and if you follow them down, you find that GFP_NOFS and GFP_NOIO # behave the same way in mempool_alloc - so I've used the less surprising # GFP_NOIO to replace GFP_NOHIGHIO. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.9 # [PATCH] Use a slab cache for pgd and pmd pages # # From Bill Irwin # # This allocates pgd's and pmd's using the slab and slab ctors. It has a # benefit beyond preconstruction in that PAE pmd's are accounted via # /proc/slabinfo # # Profiling of kernel builds by Martin Bligh shows a 30-40% drop in CPU load # due to pgd_alloc()'s page clearing activity. But this was already a tiny # fraction of the overall CPU time. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.10 # [PATCH] pgd_ctor update # # From wli # # A moment's reflection on the subject suggests to me it's worthwhile to # generalize pgd_ctor support so it works (without #ifdefs!) on both PAE # and non-PAE. This tiny tweak is actually more noticeably beneficial # on non-PAE systems but only really because pgd_alloc() is more visible; # the most likely reason it's less visible on PAE is "other overhead". # It looks particularly nice since it removes more code than it adds. # # Touch tested on NUMA-Q (PAE). OFTC #kn testers testing the non-PAE case. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.11 # [PATCH] Avoid losing timer ticks when slab debug is enabled. # # Patch from Manfred Spraul # # When slab debugging is enabled we're holding off interrupts for too long # (more than a jiffy), so reduce the alloc/free batching size when slab debug # is enabled. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.12 # [PATCH] remove unneeded locking in do_syslog() # # Lots of nonsensical locking in there. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.13 # [PATCH] hangcheck-timer # # Patch from: Joel Becker # # This kernel module will detect long durations when jiffies has failed to # increment, and will reboot the machine in response. # # Joel says: # # # "Here's why Oracle wants such a thing. We run clusters. Imagine a two node # cluster. Node1 pauses completely for some reason. There are multiple # reasons this can happen. A bad driver can udelay() for 90 seconds (qla used # to do this). zVM on S/390 can page Linux out for minutes at a time. # Anything that causes the box to freeze. Jiffies does *not* count during # this, so when Node1 returns it feels that no time has passed. # # Node2, however, has been counting time. When Node1 goes away, the Oracle # cluster manager starts looking for it. After a timeout, it gives up. It # then recovers any in-progress transactions from Node1. After that, it # starts new operations, modifying the data in ways that Node1 has no idea # about (it's still out to lunch). # # When Node1 finally returns (udelay() ends, zVM pages it in, whatever), any # I/O that it has queued or is about to queue will get sent to the disk. # Oops, you've just corrupted your shared data. # # hangcheck-timer should catch this and reboot the box. # # This is why Oracle wants this driver. We figure that such functionality # would be beneficial to others as well, so we posted to l-k. We'd all hope # that driver writers don't udelay() for 90s, but S/390 with zVM is still # around. Some folks might want to notice when it happens. I am sure other # things exist that trigger the same symptoms." # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.14 # [PATCH] Restore LSM hook calls to sendfile # # Patch from "Stephen D. Smalley" # # This patch restores the LSM hook calls in sendfile to 2.5.59. The hook was # previously added as of 2.5.29 but the hook calls in sendfile were # subsequently lost as a result of the sendfile rewrite as of 2.5.30. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.15 # [PATCH] asm-i386/mmzone.h macro paren/eval fixes # # Patch from William Lee Irwin III # # Okay, this one looks ugly because we're missing some of the definitions # available with which to convert to inline functions (esp. struct page). # A lot of these introduce temporaries and sort of hope names won't clash, # which might be important to whoever cares about -Wshadow. # # - node_end_pfn() evaluates nid twice # - local_mapnr() evaluates kvaddr twice # - kern_addr_valid() evaluates kaddr twice # - pfn_to_page() evaluates pfn multiple times # - page_to_pfn() evaluates page thrice # - pfn_valid() doesn't parenthesize its argument # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.16 # [PATCH] remove spaces from slab names # # From Anton Blanchard: remove spaces from slab cache identifiers. Simplifies # parsing of /proc/slabinfo. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.17 # [PATCH] remove will_become_orphaned_pgrp() # # Patch from William Lee Irwin III # # will_become_orphaned_pgrp()'s sole use is is_orphaned_pgrp(). Fold its body # into is_orphaned_pgrp(), rename __will_become_orphaned_pgrp(), and adjust # callers. Code shrinkage plus some relief from underscore-itis. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.18 # [PATCH] MAX_IO_APICS #ifdef'd wrongly # # Patch from William Lee Irwin III # # CONFIG_X86_NUMA no longer exists. This changes the MAX_IO_APICS definition # to 32, where it is required to be so large on NUMA-Q in order to boot. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.19 # [PATCH] patch to DAC960 driver for error retry # # Patch from Dave Olien # # The following patch implements retry on media errors for the DAC960 driver. # On such media errors, the DAC960 apparently doesn't report how much of the # transfer may have been successful before the error was encountered. # # This type of error should be rare on healthy hardware, especially if the # disks are stripped or mirrored. But, when large transfers are submitted to # the controller, it's especially bad to have to fail the entire transfer # because one disk sector may have been bad. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.20 # [PATCH] Remove __ from topology macros # # Patch from Matthew Dobson # # When I originally wrote the patches implementing the in-kernel topology # macros, they were meant to be called as a second layer of functions, # sans underbars. This additional layer was deemed unnecessary and # summarily dropped. As such, carrying around (and typing!) all these # extra underbars is quite pointless. Here's a patch to nip this in the # (sorta) bud. The macros only appear in 16 files so far, most of them # being the definitions themselves. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.21 # [PATCH] put_user() warning fix # # Patch from Russell King # # Have a couple of extra warnings: # # fs/binfmt_elf.c: In function `create_elf_tables': # fs/binfmt_elf.c:239: warning: initialization makes integer from pointer without a cast # fs/binfmt_elf.c:249: warning: initialization makes integer from pointer without a cast # # #ifndef elf_addr_t # #define elf_addr_t unsigned long # #endif # # elf_addr_t *argv, *envp; # # __put_user(NULL, argv); # __put_user(NULL, envp); # # It would therefore appear that x86 __put_user is not properly type-checking # the arguments to __put_user(). # # Here's a patch which fixes the warning (but doesn't fix x86's type-check # challenged __put_user implementation). # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.22 # [PATCH] fix #warnings # # Patch from "Randy.Dunlap" # # This fixes a few #warning's that gcc 2.96 complains about having # unmatched single-quote marks. (warnings on #warnings) # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.23 # [PATCH] ia32 Lost tick compensation # # Patch from john stultz # # Adds some lost-tick compensation code, which handles the case where time # accounting goes wrong due to interrupts being disabled for longer than two # ticks. # # This patch solves the problem by checking when an interrupt occurs if # timer->get_offset() is a value greater then 2 ticks. If so, it increments # jiffies appropriately. # # I was concerned that we'd be better off finding and fixing the misbehaving # drivers, but it turns out that the main culprits are system management cards # over which the kernel has no control. # # However John has added some debug code which will drop a backtrace on the # first five occurrences which will allow us to find-and-fix bad drivers if # overruns _are_ due to Linux software. (I disabled this - it was irritating # me. Dave Hansen has a patch which allows it to be turned on via a kernel # boot parameter, like the x86_64 equiv). # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.24 # [PATCH] Include in fs/seq_file.c, as it uses # # Patch from miles@lsi.nec.co.jp (Miles Bader) # # Otherwise it won't compile. I guesss this used to work because # was included somewhere to get the BUG macros, but now with the advent of # that's changed. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.25 # [PATCH] scsi_eh_* needs to run even during suspend # # Patch from Pavel Machek # # scsi_eh_* needs to run even during suspend because suspend does not prevent a # hard disk from reporting an error. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.26 # [PATCH] misc fixes # # - Fix dead comment in load_elf_interp() (Dave Airlie) # # - Add some (hard-won) commentary around the early SET_PERSONALITY() in # load_elf_binary(). # # - Remove dead hugetlb prototype. # # - Fix some silliness in hugetlbpage.c # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.27 # [PATCH] Remove unneeded code in fs/fs-writeback.c # # We do not need to pass the `wait' argument down to __sync_single_inode(). # That information is now present at wbc->sync_mode. # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.28 # [PATCH] Fix latencies during writeback # # When a throttled writer is performing writeback, and it encounters an inode # which is already under writeback it is forced to wait on the inode. So that # process sleeps until whoever is writing it out finishes the writeout. # # Which is OK - we want to throttle that process, and another process is # currently pumping data at the disk anyway. # # But in one situations the delays are excessive. If one process is performing # a huge linear write, other processes end up waiting for a very long time # indeed. It appears that this is because the writing process just keeps on # hogging the CPU, returning to userspace, generating more dirty data, writing # it out, sleeping in get_request_wait, etc. All other throttled dirtiers get # starved. # # So just remove the wait altogether if it is just a memory-cleansing writeout. # The calling process will then throttle in balance_dirty_pages()'s call to # blk_congestion_wait(). # -------------------------------------------- # 03/02/04 akpm@digeo.com 1.925.40.29 # [PATCH] fix i_sem contention in sys_unlink() # # Truncates can take a very long time. Especially if there is a lot of # writeout happening, because truncate must wait on in-progress I/O. # # And sys_unlink() is performing that truncate while holding the parent # directory's i_sem. This basically shuts down new accesses to the entire # directory until the synchronous I/O completes. # # In the testing I've been doing, that directory is /tmp, and this hurts. # # So change sys_unlink() to perform the actual truncate outside i_sem. # # When there is a continuous streaming write to the same disk, this patch # reduces the time for `make -j4 bzImage' from 370 seconds to 220. # -------------------------------------------- # 03/02/04 torvalds@home.transmeta.com 1.925.40.30 # Merge # -------------------------------------------- # 03/02/04 hch@hera.kernel.org 1.925.42.1 # Merge # -------------------------------------------- # 03/02/04 torvalds@home.transmeta.com 1.925.40.31 # Fix up manual merge error in usb/storage/scsiglue.c # -------------------------------------------- # 03/02/04 torvalds@home.transmeta.com 1.925.40.32 # Fix Makefile syntax error for (deprecated) "make dep" # -------------------------------------------- # 03/02/04 torvalds@home.transmeta.com 1.925.40.33 # Merge master.kernel.org:/home/hch/BK/xfs/linux-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/04 torvalds@home.transmeta.com 1.925.4.29 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/04 torvalds@home.transmeta.com 1.925.4.30 # Merge bk://kernel.bkbits.net/davem/sparc-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/04 willy@debian.org 1.925.4.31 # [PATCH] PA-RISC updates for 2.5.59 # # - conversion of remaining drivers to generic device model # - more of sfr's compat stuff # - eliminate some bogus syscalls # - update for MUX driver # - beginnings of new module code # - tell the keyboard driver about CONFIG_PARISC # -------------------------------------------- # 03/02/04 tim@physik3.uni-rostock.de 1.925.4.32 # [PATCH] use 64 bit jiffies: infrastructure # # Provide a sane way to avoid unneccessary locking on 64 bit platforms, # and a 64 bit analogous to "jiffies_to_clock_t()". # -------------------------------------------- # 03/02/04 tim@physik3.uni-rostock.de 1.925.4.33 # [PATCH] use 64 bit jiffies: fix utime wrap # # Use 64 bit jiffies for reporting uptime. # -------------------------------------------- # 03/02/04 tim@physik3.uni-rostock.de 1.925.4.34 # [PATCH] use 64 bit jiffies: 64-bit process start time # # This prevents reporting processes as having started in the future, after # 32 bit jiffies wrap. # -------------------------------------------- # 03/02/04 Matt_Domsch@dell.com 1.925.4.35 # Merge dell.com:/home/mdomsch/bk/linux-2.5 # into dell.com:/home/mdomsch/bk/edd/linux-2.5-edd # -------------------------------------------- # 03/02/04 hch@lst.de 1.925.41.2 # [PATCH] remove __scsi_add_host # # now that scsi_add_host accepts a NMULL dev argument we don't need it # anymore. # -------------------------------------------- # 03/02/04 drow@nevyn.them.org 1.925.22.3 # Use force_sig_specific to send SIGSTOP to newly-created CLONE_PTRACE processes. # -------------------------------------------- # 03/02/05 greg@kroah.com 1.925.43.1 # USB: fix up drivers the scsi people missed # -------------------------------------------- # 03/02/04 hch@lst.de 1.925.41.3 # [PATCH] fixes and cleanups for the new command allocation code # # On Tue, Feb 04, 2003 at 12:33:23PM -0600, James Bottomley wrote: # > I agree with this. It is a guarantee the mid-layer makes to the LLD # > (and there are some LLDs with static issue queues for which this is a # > hard requirement). I think (once the dust has settled and we've agreed # > which field holds the current queue depth) what's needed is a check in # > the scsi_request_fn() to see if we're over the LLD's current depth for # > the device and plug the queue and exit if we are. The next returning # > command will unplug and send. # > # > This way of doing things means that we're free to prep as many commands # > as we can, but we guarantee only to have the correct number outstanding # > to the LLD. # # Okay, here's a new versin of the patch. Changes: # # * throttel on number of inflight command blocks # * rename scsi_cmnd->new_queue_depth to scsi_cmnd->queue_depth # * remove scsi_do_cmd # * serialize pool handling # -------------------------------------------- # 03/02/04 agrover@groveronline.com 1.925.1.38 # ACPI: Optimize for space # -------------------------------------------- # 03/02/04 davidm@wailua.hpl.hp.com 1.925.31.18 # ia64: Use printk severity-levels where appropriate. # Triggered by analysis done by Philipp Marek. # -------------------------------------------- # 03/02/04 davidm@tiger.hpl.hp.com 1.925.31.19 # ia64: Fix potential perfmon deadlock. Patch by Stephane Eranian. # -------------------------------------------- # 03/02/05 greg@kroah.com 1.925.44.1 # [PATCH] PCI Hotplug: dereference null variable cleanup patches. # # These were pointed out by "dan carpenter" # from his smatch tool. # -------------------------------------------- # 03/02/05 greg@kroah.com 1.925.44.2 # [PATCH] IBM PCI Hotplug driver: Clean up the slot filename generation logic a lot. # -------------------------------------------- # 03/02/05 stanley.wang@linux.co.intel.com 1.925.44.3 # [PATCH] PCI Hotplug: Replace pcihpfs with sysfs. # -------------------------------------------- # 03/02/05 stanley.wang@linux.co.intel.com 1.925.44.4 # [PATCH] PCI Hotplug: Remove procfs stuff from pci_hotplug_core # # Here is a little patch that remove procfs stuff in pci_hotplug_core.c # Remove /proc entry for pci_hotplug_core. # -------------------------------------------- # 03/02/05 greg@kroah.com 1.925.44.5 # [PATCH] PCI Hotplug: change pci_hp_change_slot_info() to take a hotplug_slot and not a string. # -------------------------------------------- # 03/02/05 greg@kroah.com 1.925.44.6 # [PATCH] sysfs: add sysfs_update_file() function. # -------------------------------------------- # 03/02/05 greg@kroah.com 1.925.44.7 # [PATCH] PCI Hotplug: Make pci_hp_change_slot_info() work again # # Relies on sysfs_update_file() to be present in the kernel. # -------------------------------------------- # 03/02/05 greg@kroah.com 1.925.44.8 # [PATCH] PCI Hotplug: moved the some stuff into the pci core # # Moved functions from drivers/hotplug/pci_hotplug_util.c to # drivers/pci/hotplug.c, which is a better place for them. # -------------------------------------------- # 03/02/05 rddunlap@osdl.org 1.925.44.9 # [PATCH] PCI Hotplug: checker patches # # Fixes problems found by the CHECKER program in the pci hotplug drivers # -------------------------------------------- # 03/02/05 jdike@uml.karaya.com 1.925.14.7 # Merged a conflict in ptrace.h. # -------------------------------------------- # 03/02/05 riel@conectiva.com.br 1.925.41.4 # [PATCH] Re: [CHECKER] 112 potential memory leaks in 2.5.48 # # On Wed, 5 Feb 2003, Rik van Riel wrote: # > On Tue, 4 Feb 2003, Andy Chou wrote: # # Thanks for the checker output. First patch below... # # > > [BUG] # > > u1/acc/linux/2.5.48/drivers/scsi/sr_ioctl.c:188:sr_do_ioctl: # > > ERROR:LEAK:85:188:Memory leak [Allocated from: # > > /u1/acc/linux/2.5.48/drivers/scsi/sr_ioctl.c:85:scsi_allocate_request] # > # > Bug indeed, I've created a patch to fix the possible leak of # > a scsi request, but can't figure out the bounce buffer logic... # # The patch below fixes the scsi request leak. I'm not sure # how the bounce buffer thing is supposed to work (Christoph? # James?) so I'm not touching that at the moment. # # Linus, could you please apply this patch (against today's # bk tree) ? # # thank you, # # Rik # -- # Bravely reimplemented by the knights who say "NIH". # http://www.surriel.com/ http://guru.conectiva.com/ # Current spamtrap: october@surriel.com # # # ===== drivers/scsi/sr_ioctl.c 1.27 vs edited ===== # -------------------------------------------- # 03/02/05 jejb@raven.il.steeleye.com 1.925.41.5 # Correct compiler warnings with use of likely() on pointers # -------------------------------------------- # 03/02/05 jejb@raven.il.steeleye.com 1.925.41.6 # Fix sr_ioctl.c bounce buffer usage # # Make sure all DMAs come from kmalloc'd memory with the correct # GFP_ flags # -------------------------------------------- # 03/02/05 jejb@raven.il.steeleye.com 1.925.41.7 # move queue_depth check from scsi_prep_fn to scsi_request_fn # -------------------------------------------- # 03/02/05 jdike@uml.karaya.com 1.925.13.5 # Merge # -------------------------------------------- # 03/02/05 green@namesys.com 1.925.45.1 # [PATCH] fix HZ=100 case with 64 bit jiffies # # The updates to use 64-bit jiffies broke fs/proc/proc_misc.c for # architectures still using a 100 Hz clocktick (e.g. UML) # -------------------------------------------- # 03/02/05 torvalds@home.transmeta.com 1.925.43.2 # Merge penguin:v2.5/linux # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/05 rth@are.twiddle.net 1.925.46.1 # Merge # -------------------------------------------- # 03/02/05 torvalds@home.transmeta.com 1.925.43.3 # Merge bk://are.twiddle.net/axp-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/05 agrover@groveronline.com 1.925.1.39 # Merge groveronline.com:/root/bk/linux-2.5 # into groveronline.com:/root/bk/linux-acpi # -------------------------------------------- # 03/02/05 kai@tp1.ruhr-uni-bochum.de 1.925.47.1 # kbuild: Don't default to building modules when not selected # # Defaulting to building modules together with vmlinux when just doing # "make" or "make all" is only a good choice when "CONFIG_MODULES" is set. # -------------------------------------------- # 03/02/06 stekloff@w-stekloff.beaverton.ibm.com 1.925.44.10 # [PATCH] pci patch for sysfs files # # The patch is modeled after your method for creating files for usb. It # makes a single file for pci sysfs files (except for pool, which I haven't # touched yet). It also exposes more pci information to User Space # through sysfs. Finally, it removes the dependence on the proc pci code # for sysfs files. # -------------------------------------------- # 03/02/06 greg@kroah.com 1.925.44.11 # [PATCH] PCI: put proper field sizes on sysfs files, and add class file. # -------------------------------------------- # 03/02/05 torvalds@penguin.transmeta.com 1.925.43.4 # Merge http://linux-isdn.bkbits.net/linux-2.5.make # into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux # -------------------------------------------- # 03/02/06 randy.dunlap@verizon.net 1.925.44.12 # [PATCH] PCI Hotplug: memory leaks in acpiphp_glue # # Here's the memory leaks patch for acpiphp_glue.c. # -------------------------------------------- # 03/02/05 randy.dunlap@verizon.net 1.925.43.5 # [PATCH] do_mounts memory leak # # The Stanford Checker identified a memory leak in init/do_mounts.c. # # This corrects it. # -------------------------------------------- # 03/02/05 shemminger@osdl.org 1.925.43.6 # [PATCH] x86_64 gettimeofday bug. # # Found by inspection of of the x86_64 gettimeofday. # # The problem is that the code always records the maximum value # but it is not reset on the next clock tick. As written, I see it # keeping the maximum number of microseconds since the last clock tick. # -------------------------------------------- # 03/02/05 chris@wirex.com 1.925.43.7 # [PATCH] 2.5-bk trivial LSM cleanup # # Trivial patch from Randy Dunlap removes some useless # error/retval assignments. # -------------------------------------------- # 03/02/05 shemminger@osdl.org 1.925.43.8 # [PATCH] seqlock for xtime # # Add "seqlock" infrastructure for doing low-overhead optimistic reader # locks (writer increments a sequence number, reader verifies that no # writers came in during the critical region, and lots of careful memory # barriers to take care of business). # # Make xtime/get_jiffies_64() use this new locking. # -------------------------------------------- # 03/02/05 torvalds@penguin.transmeta.com 1.925.1.40 # Merge http://linux-acpi.bkbits.net/linux-acpi # into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux # -------------------------------------------- # 03/02/05 rmk@arm.linux.org.uk 1.925.1.41 # [PATCH] disassociate_ctty SMP fix # # Ok, here's my proposed fix, which appears to work with preempt. I haven't # tested on non-preempt, nor (obviously since its from me) SMP. However, # I forsee no problems caused by this change. # # release_dev() sets filp->private_data to NULL when the tty layer has # done with the file descriptor. However, it remains on the tty_files # list until __fput completes. # -------------------------------------------- # 03/02/05 torvalds@penguin.transmeta.com 1.925.1.42 # Merge http://mdomsch.bkbits.net/linux-2.5-edd # into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux # -------------------------------------------- # 03/02/06 anton@samba.org 1.940 # Merge samba.org:/scratch/anton/linux-2.5 # into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/02/06 greg@kroah.com 1.925.44.13 # [PATCH] Compaq PCI Hotplug: fix checker memory leak bugs. # -------------------------------------------- # 03/02/06 greg@kroah.com 1.925.44.14 # [PATCH] IBM PCI Hotplug: fix memory leak found by checker project. # -------------------------------------------- # 03/02/05 akpm@digeo.com 1.925.1.43 # [PATCH] seqlock fix: read_seqretry_irqrestore() # -------------------------------------------- # 03/02/06 anton@samba.org 1.941 # Merge samba.org:/scratch/anton/linux-2.5 # into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/02/06 anton@samba.org 1.942 # Merge samba.org:/scratch/anton/linux-2.5 # into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/02/05 patmans@us.ibm.com 1.925.41.8 # [PATCH] add back single_lun support # # On Wed, Feb 05, 2003 at 05:14:00PM -0600, James Bottomley wrote: # # > I don't see device_active getting set anywhere. # > # > shouldn't we just dump device_active in favour of a non-zero check of # > device_busy (it's all done under the queue lock, anyway). # > # > James # # OK - once more. # # This patch against the current scsi-misc-2.5 adds back the check for the # single_lun case and removes the unused device_active field. # # I compiled and booted with this applied but don't have any devices (i.e. # CD ROM changer) for testing. # -------------------------------------------- # 03/02/06 greg@kroah.com 1.925.44.15 # [PATCH] IBM PCI Hotplug: fix a load of memory leak errors found by the checker project. # -------------------------------------------- # 03/02/06 anton@samba.org 1.936.1.1 # ppc64: Add ppc64 relocations to asm/elf.h. I am the example of good taste. # -------------------------------------------- # 03/02/06 anton@samba.org 1.943 # Merge samba.org:/scratch/anton/linux-2.5_ppc64 # into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/02/06 greg@kroah.com 1.925.1.44 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/pci-hp-2.5 # -------------------------------------------- # 03/02/06 greg@kroah.com 1.925.1.45 # sysfs: remember to add EXPORT_SYMBOL() for sysfs_update_file. # -------------------------------------------- # 03/02/05 torvalds@home.transmeta.com 1.925.1.46 # Merge http://jdike.stearns.org:5000/updates-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/05 torvalds@home.transmeta.com 1.925.1.47 # Merge http://jdike.stearns.org:5000/skas-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/05 torvalds@home.transmeta.com 1.925.1.48 # Merge http://jdike.stearns.org:5000/stack-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/05 torvalds@home.transmeta.com 1.925.1.49 # Merge http://jdike.stearns.org:5000/fixes-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/06 anton@samba.org 1.944 # Merge samba.org:/scratch/anton/linux-2.5 # into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/02/06 rem@osdl.org 1.925.1.50 # [NETFILTER]: Delete un-used stack variable in ip_nat_helper.c # -------------------------------------------- # 03/02/06 elenstev@mesatop.com 1.925.1.51 # [NETFILTER]: Update Kconfig help text to match 2.4.x # -------------------------------------------- # 03/02/06 vojtech@suse.cz 1.925.48.1 # x86-64: Minor fixes to make the kernel compile and remove warnings. # -------------------------------------------- # 03/02/06 hch@lst.de 1.925.41.9 # [SCSI] Remove host_active # # It isn't used anywhere anymore # -------------------------------------------- # 03/02/06 rusty@rustcorp.com.au 1.925.41.10 # [PATCH] [patch, 2.5] scsi_qla1280.c free on error path # # From: Marcus Alanen # # Remove check_region in favour of request_region. Free resources # properly on error path. Horribly subtle ioremap/iounmap lurks here I # think, in qla1280_pci_config(), which the below patch should take care # of. # # I'm wondering if there couldn't / shouldn't be a better way to # allocate resources. Obviously lots of drivers have broken error paths. # Is this even necessary? # # Marcus # # # # # # create_patch: qla1280_release_on_error_path-2002-12-08-A.patch # # Date: Sun Dec 8 22:32:33 EET 2002 # # # -------------------------------------------- # 03/02/06 rusty@rustcorp.com.au 1.925.41.11 # [PATCH] 2.5.59 add two help texts to drivers_scsi_Kconfig # # From: Steven Cole # # Here are some help texts from 2.4.21-pre3 Configure.help which are # needed in 2.5.59 drivers/scsi/Kconfig. # # Steven # -------------------------------------------- # 03/02/06 hch@lst.de 1.925.41.12 # [PATCH] coding style updates for scsi_lib.c # # I just couldn't see the mess anymore.. Nuke the ifdefs and use sane # variable names. Some more small nitpicks but no behaviour changes at # all. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.1 # [PATCH] BTTV build fix # # Patch from Gerd Knorr # # bttv requires CONFIG_SOUND. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.2 # [PATCH] reiserfs v3 readpages support # # Patch from Chris Mason # # The patch below is against 2.5.59, various forms have been floating # around for a while, and Andrew recently included this fixed version in # 2.5.55-mm. The end result is faster reads and writes for reiserfs. # # This adds reiserfs support for readpages, along with a support func in # fs/mpage.c to deal with the reiserfs_get_block call sending back up to # date buffers with packed tails copied into them. # # Most of the changes are to reiserfs_writepage, which still had many # 2.4isms in the way it started io, dealt with errors and handled the bh # state bits. I've also added an optimization so it only starts # transactions when we need to copy a packed tail into the btree or fill a # hole, instead of any time reiserfs_writepage hits an unmapped buffer. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.3 # [PATCH] self-unplugging request queues # # The patch teaches a queue to unplug itself: # # a) if is has four requests OR # b) if it has had plugged requests for 3 milliseconds. # # These numbers may need to be tuned, although doing so doesn't seem to # make much difference. 10 msecs works OK, so HZ=100 machines will be # fine. # # Instrumentation shows that about 5-10% of requests were started due to # the three millisecond timeout (during a kernel compile). That's # somewhat significant. It means that the kernel is leaving stuff in the # queue, plugged, for too long. This testing was with a uniprocessor # preemptible kernel, which is particularly vulnerable to unplug latency # (submit some IO, get preempted before the unplug). # # This patch permits the removal of a lot of rather lame unplugging in # page reclaim and in the writeback code, which kicks the queues # (globally!) every four megabytes to get writeback underway. # # This patch doesn't use blk_run_queues(). It is able to kick just the # particular queue. # # The patch is not expected to make much difference really, except for # AIO. AIO needs a blk_run_queues() in its io_submit() call. For each # request. This means that AIO has to disable plugging altogether, # unless something like this patch does it for it. It means that AIO # will unplug *all* queues in the machine for every io_submit(). Even # against a socket! # # This patch was tested by disabling blk_run_queues() completely. The # system ran OK. # # The 3 milliseconds may be too long. It's OK for the heavy writeback # code, but AIO may want less. Or maybe AIO really wants zero (ie: # disable plugging). If that is so, we need new code paths by which AIO # can communicate the "immediate unplug" information - a global unplug is # not good. # # # To minimise unplug latency due to user CPU load, this patch gives keventd # `nice -10'. This is of course completely arbitrary. Really, I think keventd # should be SCHED_RR/MAX_RT_PRIO-1, as it has been in -aa kernels for ages. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.4 # [PATCH] Remove most of the blk_run_queues() calls # # We don't need these with self-unplugging queues. # # The patch also contains a couple of microopts suggested by Andrea: we # don't need to run sync_page() if the page just came unlocked. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.5 # [PATCH] Updated Documentation/kernel-parameters.txt # # Patch from Petr Baudis # # this patch (against 2.5.59) updates Documentation/kernel-parameters.txt to # the (more-or-less; I certainly missed some parameters) current state of # kernel. Note also that I will probably send up another update after few # further kernel releases.. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.6 # [PATCH] JBD Documentation # # Patch from Roger Gammans # # Adds lots of API documentation to the JBD layer. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.7 # [PATCH] Restore LSM hook calls to sendfile # # Patch from "Stephen D. Smalley" # # This patch restores the LSM hook calls in sendfile to 2.5.59. The hook was # previously added as of 2.5.29 but the hook calls in sendfile were # subsequently lost as a result of the sendfile rewrite as of 2.5.30. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.8 # [PATCH] Fix SMP race betwen __sync_single_inode and # # Patch from Mikulas Patocka # # there's a SMP race condition between __sync_single_inode (or __sync_one on # 2.4.20) and __mark_inode_dirty. __mark_inode_dirty doesn't take inode # spinlock. As we know -- unless you take a spinlock or use barrier, # processor can change order of instructions. # # CPU 1 # # modify inode # (but modifications are in cpu-local # buffer and do not go to bus) # # calls # __mark_inode_dirty # it sees I_DIRTY and exits immediatelly # CPU 2 # takes spinlock # calls __sync_single_inode # inode->i_state &= ~I_DIRTY # writes the inode (but does not see # modifications by CPU 1 yet) # # CPU 1 flushes its write buffer to the bus # inode is already written, clean, modifications # done by CPU1 are lost # # The easiest fix would be to move the test inside spinlock in # __mark_inode_dirty; if you do not want to suffer from performance loss, # use the attached patches that use memory barriers to ensure ordering of # reads and writes. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.9 # [PATCH] ia32 IRQ distribution rework # # Patch from "Kamble, Nitin A" # # Hello All, # # We were looking at the performance impact of the IRQ routing from # the 2.5.52 Linux kernel. This email includes some of our findings # about the way the interrupts are getting moved in the 2.5.52 kernel. # Also there is discussion and a patch for a new implementation. Let # me know what you think at nitin.a.kamble@intel.com # # Current implementation: # ====================== # We have found that the existing implementation works well on IA32 # SMP systems with light load of interrupts. Also we noticed that it # is not working that well under heavy interrupt load conditions on # these SMP systems. The observations are: # # * Interrupt load of each IRQ is getting balanced on CPUs independent # of load of other IRQs. Also the current implementation moves the # IRQs randomly. This works well when the interrupt load is light. But # we start seeing imbalance of interrupt load with existence of # multiple heavy interrupt sources. Frequently multiple heavily loaded # IRQs gets moved to a single CPU while other CPUs stay very lightly # loaded. To achieve a good interrupts load balance, it is important to # consider the load of all the interrupts together. # This further can be explained with an example of 4 CPUs and 4 # heavy interrupt sources. With the existing random movement approach, # the chance of each of these heavy interrupt sources moving to separate # CPUs is: (4/4)*(3/4)*(2/4)*(1/4) = 3/16. It means 13/16 = 81.25% of # the time the situation is, some CPUs are very lightly loaded and some # are loaded with multiple heavy interrupts. This causes the interrupt # load imbalance and results in less performance. In a case of 2 CPUs # and 2 heavily loaded interrupt sources, this imbalance happens # 1/2 = 50% of the times. This issue becomes more and more severe with # increasing number of heavy interrupt sources. # # * Another interesting observation is: We cannot see the imbalance # of the interrupt load from /proc/interrupts. (/proc/interrupts shows # the cumulative load of interrupts on all CPUs.) If the interrupt load # is imbalanced and this imbalance is getting rotated among CPUs # continuously, then /proc/interrupts will still show that the interrupt # load is going to processors very evenly. Currently at the frequency # (HZ/50) at which IRQs are moved across CPUs, it is not possible to # see any interrupt load imbalance happening. # # * We have also found that, in certain cases the static IRQ binding # performs better than the existing kernel distribution of interrupt # load. The reason is, in a well-balanced interrupt load situations, # these interrupts are unnecessarily getting frequently moved across # CPUs. This adds an extra overhead; also it takes off the CPU cache # warmth benefits. # This came out from the performance measurements done on a 4-way HT # (8 logical processors) Pentium 4 Xeon system running 8 copies of # netperf. The 4 NICs in the system taking different IRQs generated # sizable interrupt load with the help of connected clients. # # Here the netperf transactions/sec throughput numbers observed are: # # IRQs nicely manually bound to CPUs: 56.20K # The current kernel implementation of IRQ movement: 50.05K # ----------------------- # The static binding of IRQs has performed 12.28% better than the # current IRQ movement implemented in the kernel. # # * The current implementation does not distinguish siblings from the # HT (Hyper-Threading(tm)) enabled CPUs. It will be beneficial to # balance the interrupt load with respect to processor packages first, # and then among logical CPUs inside processor packages. # For example if we have 2 heavy interrupt sources and 2 processor # packages (4 logical CPUs); Assigning both the heavy interrupt sources # in different processor packages is better, it will use different # execution resources from the different processor packages. # # # # New revised implementation: # ========================== # We also have been working on a new implementation. The following # points are in main focus. # # * At any moment heavily loaded IRQs are distributed to different # CPUs to achieve as much balance as possible. # # * Lightly loaded interrupt sources are ignored from the load # balancing, as they do not cause considerable imbalance. # # * When the heavy interrupt sources are balanced, they are not moved # around. This also helps in keeping the CPU caches warm. # # * It has been made HT aware. While distributing the load, the load # on a processor package to which the logical CPUs belong to is also # considered. # # * In the situations of few (lesser than num_cpus) heavy interrupt # sources, it is not possible to balance them evenly. In such case # the existing code has been reused to move the interrupts. The # randomness from the original code has been removed. # # * The time interval for redistribution has been made flexible. It # varies as the system interrupt load changes. # # * A new kernel_thread is introduced to do the load balancing # calculations for all the interrupt sources. It keeps the balanace_maps # ready for interrupt handlers, keeping the overhead in the interrupt # handling to minimum. # # * It allows the disabling of the IRQ distribution from the boot loader # command line, if anybody wants to do it for any reason. # # * The algorithm also takes into account the static binding of # interrupts to CPUs that user imposes from the # /proc/irq/{n}/smp_affinity interface. # # # Throughput numbers with the netperf setup for the new implementation: # # Current kernel IRQ balance implementation: 50.02K transactions/sec # The new IRQ balance implementation: 56.01K transactions/sec # --------------------- # The performance improvement on P4 Xeon of 11.9% is observed. # # The new IRQ balance implementation also shows little performance # improvement on P6 (Pentium II, III) systems. # # On a P6 system the netperf throughput numbers are: # Current kernel IRQ balance implementation: 36.96K transactions/sec # The new IRQ balance implementation: 37.65K transactions/sec # --------------------- # Here the performance improvement on P6 system of about 2% is observed. # # # --------------------- # # Andrew Theurer did some testing of this patch on a quad # P4: # # # I got a chance to run the NetBench benchmark with your patch on 2.5.54-mjb2 # kernel. NetBench measures SMB/CIFS performance by using several SMB # clients (in this case 44 Windows 2000 systems), sending SMB requests to a # Linux server running Samba 2.2.3a+sendfile. Result is in throughput, # Mbps. Generally the network traffic on the server is 60% recv, 40% tx. # # I believe we have very similar systems. Mine is a 4 x 1.6 GHz, 1 MB L3 P4 # Xeon with 4 GB DDR memory (3.2 GB/sec I believe). The chipset is "Summit". # I also have more than one Intel e1000 adapters. # # I decided to run a few configurations, first with just one adapter, with # and without HT support in the kernel (acpi=off), then add another adapter # and test again with/without HT. # # Here are the results: # # 4P, no HT, 1 x e1000, no kirq: 1214 Mbps, 4% idle # 4P, no HT, 1 x e1000, kirq: 1223 Mbps, 4% idle, +0.74% # # I suppose we didn't see much of an improvement here because we never run # into the situation where more than one interrupt with a high rate is # routed to a single CPU on irq_balance. # # 4P, HT, 1 x e1000, no kirq: 1214 Mbps, 25% idle # 4P, HT, 1 x e1000, kirq: 1220 Mbps, 30% idle, +0.49% # # Again, not much of a difference just yet, but lots of idle time. We may # have reached the limit at which one logical CPU can process interrupts for # an e1000 adapter. There are other things I can probably do to help this, # like int delay, and NAPI, which I will get to eventually. # # 4P, HT, 2 x e1000, no kirq: 1269 Mbps, 23% idle # 4P, HT, 2 x e1000, kirq: 1329 Mbps, 18% idle +4.7% # # OK, almost 5% better! Probably has to do with a couple of things; the fact # that your code does not route two different interrupts to the same # core/different logical cpus (quite obvious by looking at /proc/interrupts), # and that more than one interrupt does not go to the same cpu if possible. # I suspect irq_balance did some of those [bad] things some of the time, and # we observed a bottleneck in int processing that was lower than with kirq. # # I don't think all of the idle time is because of a int processing # bottleneck. I'm just not sure what it is yet :) Hopefully something will # become obvious to me... # # Overall I like the way it works, and I believe it can be tweaked to work # with NUMA when necessary. I hope to have access to a specweb system on a # NUMA box soon, so we can verify that. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.10 # [PATCH] Fix futexes in huge pages # # Using a futex in a large page causes a kernel lockup in __pin_page() - # because __pin_page's page revalidation uses follow_page(), and follow_page() # doesn't work for hugepages. # # The patch fixes up follow_page() to return the appropriate 4k page for # hugepages. # # This incurs a vma lookup for each follow_page(), which is considerable # overhead in some situations. We only _need_ to do this if the architecture # cannot determin a page's hugeness from the contents of the PMD. # # So this patch is a "reference" implementation for, say, PPC BAT-based # hugepages. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.11 # [PATCH] Optimise follow_page() for page-table-based hugepages # # ia32 and others can determine a page's hugeness by inspecting the pmd's value # directly. No need to perform a VMA lookup against the user's virtual # address. # # This patch ifdef's away the VMA-based implementation of # hugepage-aware-follow_page for ia32 and replaces it with a pmd-based # implementation. # # The intent is that architectures will implement one or the other. So the architecture either: # # 1: Implements hugepage_vma()/follow_huge_addr(), and stubs out # pmd_huge()/follow_huge_pmd() or # # 2: Implements pmd_huge()/follow_huge_pmd(), and stubs out # hugepage_vma()/follow_huge_addr() # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.12 # [PATCH] default_idle micro-optimisation # # Patch from rwhron@earthlink.net # # Micro-optimization of default_idle from -aa. current_cpu_data.hlt_works_ok # is only false for some old 386/486 pcs. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.13 # [PATCH] loop inefficiency fix # # Patch from Hugh Dickins # # The loop driver's loop over elements of bi_io_vec is in lo_send and # lo_receive: iterating that same transfer bi_vcnt times at the level above is, # er, excessive. (And no need to increment bi_idx here.) # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.14 # [PATCH] pte_chain_alloc fixes # # There are several places in which the return value from pte_chain_alloc() is # not being checked, and one place in which a GFP_KERNEL allocatiopn is # happening inside spinlock. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.15 # [PATCH] give hugetlbfs a set_page_dirty a_op # # Seems that nobody has tested direct IO into hugetlb pages yet. The VFS gets # upset about running set_page_dirty() against a non-uptodate page. # # So give hugetlbfs inodes a private no-op ->set_page_dirty() to isolate them # from all that. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.16 # [PATCH] Infrastructure for correct hugepage refcounting # # We currently have a problem when things like ptrace, futexes and direct-io # try to pin user pages. If the user's address is in a huge page we're # elevting the refcount of a constituent 4k page, not the head page of the # high-order allocation unit. # # To solve this, a generic way of handling higher-order pages has been # implemented: # # - A higher-order page is called a "compound page". Chose this because # "huge page", "large page", "super page", etc all seem to mean different # things to different people. # # - The first (controlling) 4k page of a compound page is referred to as the # "head" page. # # - The remaining pages are tail pages. # # All pages have PG_compound set. All pages have their lru.next pointing at # the head page (even the head page has this). # # The head page's lru.prev, if non-zero, holds the address of the compound # page's put_page() function. # # The order of the allocation is stored in the first tail page's lru.prev. # This is only for debug at present. This usage means that zero-order pages # may not be compound. # # The above relationships are established for _all_ higher-order pages in the # page allocator. Which has some cost, but not much - another atomic op during # fork(), mainly. # # This functionality is only enabled if CONFIG_HUGETLB_PAGE, although it could # be turned on permanently. There's a little extra cost in get_page/put_page. # # These changes do not preclude adding compound pages to the LRU in the future # - we can add a new page flag to the head page and then move all the # additional data to the first tail page's lru.next, lru.prev, list.next, # list.prev, index, private, etc. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.17 # [PATCH] convert hugetlb code to use compound pages # # The odd thing about hugetlb is that it maintains its own freelist of pages. # And it has to do that, else it would trivially run out of pages due to buddy # fragmetation. # # So we we don't want callers of put_page() to be passing those pages # to __free_pages_ok() on the final put(). # # So hugetlb installs a destructor in the compound pages to point at # free_huge_page(), which knows how to put these pages back onto the free list. # # Also, don't mark hugepages as all PageReserved any more. That's preenting # callers from doing proper refcounting. Any code which does a user pagetable # walk and hits part of a hugepage will now handle it transparently. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.18 # [PATCH] get_unmapped_area for hugetlbfs # # Having to specify the mapping address is a pain. Give hugetlbfs files a # file_operations.get_unmapped_area(). # # The implementation is in hugetlbfs rather than in arch code because it's # probably common to several architectures. If the architecture has special # needs it can define HAVE_ARCH_HUGETLB_UNMAPPED_AREA and go it alone. Just # like HAVE_ARCH_UNMAPPED_AREA. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.19 # [PATCH] hugetlbfs: fix truncate # # - Opening a hugetlbfs file O_TRUNC calls the generic vmtruncate() functions # and nukes the kernel. # # Give S_ISREG hugetlbfs files a inode_operations, and hence a setattr # which know how to handle these files. # # - Don't permit the user to truncate hugetlbfs files to sizes which are not # a multiple of HPAGE_SIZE. # # - We don't support expanding in ftruncate(), so remove that code. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.20 # [PATCH] hugetlbfs i_size fixes # # We're expanding hugetlbfs i_size in the wrong place. If someone attempts to # mmap more pages than are available, i_size is updated to reflect the # attempted mapping size. # # So set i_size only when pages are successfully added to the mapping. # # i_size handling at truncate time is still a bit wrong - if the mapping has # pages at (say) page offset 100-200 and the mappng is truncated to (say) page # offset 50, i_size should be set to zero. But it is instead set to # 50*HPAGE_SIZE. That's harmless. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.21 # [PATCH] hugetlbfs cleanups # # - Remove quota code. # # - Remove extraneous copy-n-paste code from truncate: that's only for # physically-backed filesystems. # # - Whitespace changes. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.22 # [PATCH] Give all architectures a hugetlb_nopage(). # # If someone maps a hugetlbfs file, then truncates it, then references the part # of the mapping outside the truncation point, they take a pagefault and we end # up hitting hugetlb_nopage(). # # We want to prevent this from ever happening. This patch just makes sure that # all architectures have a goes-BUG hugetlb_nopage() to trap it. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.23 # [PATCH] Fix hugetlbfs faults # # If the underlying mapping was truncated and someone references the # now-unmapped memory the kernel will enter handle_mm_fault() and will start # instantiating PAGE_SIZE pte's inside the hugepage VMA. Everything goes # generally pear-shaped. # # So trap this in handle_mm_fault(). It adds no overhead to non-hugepage # builds. # # Another possible fix would be to not unmap the huge pages at all in truncate # - just anonymise them. # # But I think we want full ftruncate semantics for hugepages for management # purposes. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.24 # [PATCH] ia32 hugetlb cleanup # # - whitespace # # - remove unneeded spinlocking no-op. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.25 # [PATCH] Fix hugetlb_vmtruncate_list() # # This function is quite wrong - has an "=" where it should have a "-" and # confuses PAGE_SIZE and HPAGE_SIZE in its address and file offset arithmetic. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.26 # [PATCH] hugetlb mremap fix # # If you attempt to perform a relocating 4k-aligned mremap and the new address # for the map lands on top of a hugepage VMA, do_mremap() will attempt to # perform a 4k-aligned unmap inside the hugetlb VMA. The hugetlb layer goes # BUG. # # Fix that by trapping the poorly-aligned unmap attempt in do_munmap(). # do_remap() will then fall through without having done anything to the place # where it tests for a hugetlb VMA. # # It would be neater to perform these checks on entry to do_mremap(), but that # would incur another VMA lookup. # # Also, if you attempt to perform a 4k-aligned and/or sized munmap() inside a # hugepage VMA the same BUG happens. This patch fixes that too. # # This all means that an mremap attempt against a hugetlb area will fail, but # only after having unmapped the source pages. That's a bit messy, but # supporting hugetlb mremap doesn't seem worth it, and completely disallowing # it will add overhead to normal mremaps. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.27 # [PATCH] mm/mremap.c whitespace cleanup # # - Not everyone uses 160-column xterms. # # - Coding style consistency # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.28 # [PATCH] spinlock debugging on uniprocessors # # Patch from Manfred Spraul # # This enables spinlock debuggng on uniprocessor builds, under # CONFIG_DEBUG_SPINLOCK. # # The reason I want this is that one day we'll need to pull out the debugging # support from the timer code which detects uninitialised timers. And once # that has gone, uniprocessor developers and testers have no way of detecting # uninitialised timers - there will be mysterious deadlocks on SMP machines. # And there will surely be more uninitialised timers # # The patch also removes the last pieces of the support for including # directly. Doesn't work since (IIRC) 2.3.x # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.29 # [PATCH] CPU Hotplug mm/slab.c CPU_UP_CANCELED fix # # Patch from Manfred Spraul. # # Fixes a bug which was exposed by Zwane's hotplug CPU work. The # cache_cache.array pointer is initially given a temp bootstrap area, which is # later converted over to the final value after the CPU is brought up. # # But if slab is enhanced to permit cancellation of a CPU bringup, this pointer # ends up pointing at stale memory. So reinitialise it by hand when # kmem_cache_init() is run. # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.49.30 # [PATCH] Fix signed use of i_blocks in ext3 truncate # # Patch from "Stephen C. Tweedie" # # Fix "h_buffer_credits<0" assert failure during truncate. # # The bug occurs when the "i_blocks" count in the file's inode overflows # past 2^31. That works fine most of the time, because i_blocks is an # unsigned long, and should go up to 2^32; but there's a place in truncate # where ext3 calculates the size of the next transaction chunk for the # delete, and that mistakenly uses a signed long instead. Because the # huge i_blocks gets cast to a negative value, ext3 does not reserve # enough credits for the transaction and the above error results. # # This is usually only possible on filesystems corrupted for other # reasons, but it is reproducible if you create a single, non-sparse file # larger than 1TB on ext3 and then try to delete it. # -------------------------------------------- # 03/02/06 torvalds@home.transmeta.com 1.925.48.2 # Merge bk://kernel.bkbits.net/vojtech/x86-64 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/06 randy.dunlap@verizon.net 1.925.48.3 # [PATCH] quota memleak # # The Stanford Checker found a memleak. # -------------------------------------------- # 03/02/06 jejb@raven.il.steeleye.com 1.925.48.4 # Merge raven.il.steeleye.com:/home/jejb/BK/scsi-misc-2.5 # into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.5 # -------------------------------------------- # 03/02/06 agrover@groveronline.com 1.925.50.1 # ACPI: Enable compilation w/o cpufreq # -------------------------------------------- # 03/02/06 torvalds@home.transmeta.com 1.925.51.1 # Merge http://linux-acpi.bkbits.net/linux-acpi # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/06 torvalds@home.transmeta.com 1.925.48.5 # Merge http://linux-scsi.bkbits.net/scsi-for-linus-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/06 David_Jeffery@adaptec.com 1.925.48.6 # [PATCH] ips driver 1/4: fix struct length and remove dead code # # This small patch fixes the length of the IPS_ENQ # struct. It was too short which can cause the adapter # to write beyond the the end of the struct during # driver initialization and corrupt part of memory. # -------------------------------------------- # 03/02/06 David_Jeffery@adaptec.com 1.925.48.7 # [PATCH] ips driver 2/4: initialization reordering # # This large patch reworks much of the adapter initialization # code. # # It splits the scsi initialization code from the pci # initialization. It adds support for working with some # future cards. It also removes the use of multiple pci_driver # registrations and instead does its own adapter ordering. # -------------------------------------------- # 03/02/06 David_Jeffery@adaptec.com 1.925.48.8 # [PATCH] ips driver 3/4: 64bit dma addressing # # This large patch adds support for using 64bit addressing. # # Special thanks goes to Mike Anderson who did the initial # versions of this patch. # -------------------------------------------- # 03/02/06 David_Jeffery@adaptec.com 1.925.48.9 # [PATCH] ips driver 4/4: error messages # # This small patch does 2 things. It reworks the firmware/driver # versioning messages to make them more understandable, and it # fixes one case where the 64bit addressing changes caused # error/success to not be properly reported to the serveraid tools. # -------------------------------------------- # 03/02/06 drow@nevyn.them.org 1.925.22.4 # Add PTRACE_O_TRACEVFORKDONE and PTRACE_O_TRACEEXIT facilities. # -------------------------------------------- # 03/02/06 mingo@elte.hu 1.925.48.10 # [PATCH] signal-fixes-2.5.59-A4 # # this is the current threading patchset, which accumulated up during the # past two weeks. It consists of a biggest set of changes from Roland, to # make threaded signals work. There were still tons of testcases and # boundary conditions (mostly in the signal/exit/ptrace area) that we did # not handle correctly. # # Roland's thread-signal semantics/behavior/ptrace fixes: # # - fix signal delivery race with do_exit() => signals are re-queued to the # 'process' if do_exit() finds pending unhandled ones. This prevents # signals getting lost upon thread-sys_exit(). # # - a non-main thread has died on one processor and gone to TASK_ZOMBIE, # but before it's gotten to release_task a sys_wait4 on the other # processor reaps it. It's only because it's ptraced that this gets # through eligible_child. Somewhere in there the main thread is also # dying so it reparents the child thread to hit that case. This means # that there is a race where P might be totally invalid. # # - forget_original_parent is not doing the right thing when the group # leader dies, i.e. reparenting threads to init when there is a zombie # group leader. Perhaps it doesn't matter for any practical purpose # without ptrace, though it makes for ppid=1 for each thread in core # dumps, which looks funny. Incidentally, SIGCHLD here really should be # p->exit_signal. # # - one of the gdb tests makes a questionable assumption about what kill # will do when it has some threads stopped by ptrace and others running. # # exit races: # # 1. Processor A is in sys_wait4 case TASK_STOPPED considering task P. # Processor B is about to resume P and then switch to it. # # While A is inside that case block, B starts running P and it clears # P->exit_code, or takes a pending fatal signal and sets it to a new # value. Depending on the interleaving, the possible failure modes are: # a. A gets to its put_user after B has cleared P->exit_code # => returns with WIFSTOPPED, WSTOPSIG==0 # b. A gets to its put_user after B has set P->exit_code anew # => returns with e.g. WIFSTOPPED, WSTOPSIG==SIGKILL # # A can spend an arbitrarily long time in that case block, because # there's getrusage and put_user that can take page faults, and # write_lock'ing of the tasklist_lock that can block. But even if it's # short the race is there in principle. # # 2. This is new with NPTL, i.e. CLONE_THREAD. # Two processors A and B are both in sys_wait4 case TASK_STOPPED # considering task P. # # Both get through their tests and fetches of P->exit_code before either # gets to P->exit_code = 0. => two threads return the same pid from # waitpid. # # In other interleavings where one processor gets to its put_user after # the other has cleared P->exit_code, it's like case 1(a). # # # 3. SMP races with stop/cont signals # # First, take: # # kill(pid, SIGSTOP); # kill(pid, SIGCONT); # # or: # # kill(pid, SIGSTOP); # kill(pid, SIGKILL); # # It's possible for this to leave the process stopped with a pending # SIGCONT/SIGKILL. That's a state that should never be possible. # Moreover, kill(pid, SIGKILL) without any repetition should always be # enough to kill a process. (Likewise SIGCONT when you know it's # sequenced after the last stop signal, must be sufficient to resume a # process.) # # 4. take: # # kill(pid, SIGKILL); // or any fatal signal # kill(pid, SIGCONT); // or SIGKILL # # it's possible for this to cause pid to be reaped with status 0 # instead of its true termination status. The equivalent scenario # happens when the process being killed is in an _exit call or a # trap-induced fatal signal before the kills. # # plus i've done stability fixes for bugs that popped up during # beta-testing, and minor tidying of Roland's changes: # # - a rare tasklist corruption during exec, causing some very spurious and # colorful crashes. # # - a copy_process()-related dereference of already freed thread structure # if hit with a SIGKILL in the wrong moment. # # - SMP spinlock deadlocks in the signal code # # this patchset has been tested quite well in the 2.4 backport of the # threading changes - and i've done some stresstesting on 2.5.59 SMP as # well, and did an x86 UP testcompile + testboot as well. # -------------------------------------------- # 03/02/06 markh@osdl.org 1.925.48.11 # [PATCH] fix megaraid driver compile error # # This moves access of the host element to device since host has been # removed from struct scsi_cmnd. # -------------------------------------------- # 03/02/06 drow@nevyn.them.org 1.925.22.5 # Signal handling bugs for thread exit + ptrace # -------------------------------------------- # 03/02/06 colpatch@us.ibm.com 1.925.48.12 # [PATCH] Broken CLEAR_BITMAP() macro # # The CLEAR_BITMAP() macro in include/linux/types.h is broken and doesn't # round the bitmap size to the proper 'long' boundary. # # This fixes it by creating a macro BITS_TO_LONGS that just rounds a # number of bits up to the closest number of unsigned longs. This makes # the DECLARE & CLEAR _BITMAP macros more readable and fixes the bug. # -------------------------------------------- # 03/02/06 drow@nevyn.them.org 1.925.52.1 # Hand-merge with Ingo's changes # -------------------------------------------- # 03/02/06 elenstev@mesatop.com 1.925.48.13 # [PATCH] Spelling fixes # # OK, here is the diff against 2.5.59-bk2, now up to 880 lines due to an # additional misspelling which crept in the -bk2 snapshot. # # Fixes 'seperate' -> 'separate' and 'definate' -> 'definite'. # # Kernal codrs cna't spel. # -------------------------------------------- # 03/02/06 roland@redhat.com 1.925.48.14 # [PATCH] Make sys_wait4() more readable # # I cleaned up sys_wait4; it was straightforward and I think a definite # improvement. While at it, I noticed that one of the races I fixed in the # TASK_STOPPED case actually can happen earlier. Between read_unlock and # write_lock_irq, another thread could reap the process and make P invalid, # so now I do get_task_struct before read_unlock and then the existing race # checks catch all scenarios. # # Aside from the aforementioned race tweak, the code should be the same as # in the previous patch (that Ingo and I have tested more thoroughly) # modulo being moved into functions and some reformatting and comment # changes. # # Oh, my old patch had one case where it failed to retake the read lock after # a race bailout that I just noticed reading over it. That's fixed too. # # These exit fixes were something I noticed incidentally and spent less time # on than the signals changes. Another few passes of eyeballs over them are # certainly warranted. (In particular, there are code paths like that one # that check for specific races that have probably never been seen in # practice, so those code paths have never run once.) # -------------------------------------------- # 03/02/06 akpm@digeo.com 1.925.48.15 # [PATCH] revert extra sendfile security hook patch # # hm. It seems that I sent this patch twice. # # After resyncing with your tree I go through and try to reapply all the sent # patches, throwing out the ones which get a lot of rejects. Just to make sure # that everything got through OK. # # But it appears that that particular patch happily applied on top of itself, # so I assumed it was not applied... # -------------------------------------------- # 03/02/06 Andries.Brouwer@cwi.nl 1.925.48.16 # [PATCH] Remove dead code # # In struct char_dev the fields openers and sem are unused. # The file char_dev.c claims that it is called differently. # -------------------------------------------- # 03/02/06 Andries.Brouwer@cwi.nl 1.925.48.17 # [PATCH] Doc fix # -------------------------------------------- # 03/02/06 hch@sgi.com 1.925.48.18 # [PATCH] fix leaks in vxfs_read_fshead() # # The Stanford checker disclose that vxfs_read_fshead was missing any # unwinding in the error cases.. # -------------------------------------------- # 03/02/06 fdavis@si.rr.com 1.925.48.19 # [PATCH] 2.5.59 : drivers/media/video/bt856.c # # This fixes a bt856.c compile error. The driver now compiles. Its a # straightforward patch and have emailed l-k and no objections have been # reported. # -------------------------------------------- # 03/02/06 drow@nevyn.them.org 1.925.53.1 # Merge # -------------------------------------------- # 03/02/06 fdavis@si.rr.com 1.925.48.20 # [PATCH] 2.5.59 : drivers/media/video/saa7185.c # # This patch to saa7185 to resolves buzilla bug #168 (compile error). It # has been sent to l-k and has received no objections. # -------------------------------------------- # 03/02/06 fdavis@si.rr.com 1.925.48.21 # [PATCH] 2.5.59 : drivers/media/video/bt819.c # # This patch for bt819.c addresses buzilla bug #169 (compile error). # -------------------------------------------- # 03/02/06 anton@samba.org 1.925.48.22 # [PATCH] missing include in pci-sysfs.c # # Add a missing include for those pesky S_IRUGO thingys. # -------------------------------------------- # 03/02/06 roland@redhat.com 1.925.48.23 # [PATCH] exit_notify/do_exit cleanup # # Here is a cleanup moving the new pending thread signal check into # exit_notify. # # I also made exit_notify and do_exit consistent in using the saved tsk # variable instead of current, as most of do_exit already does. # -------------------------------------------- # 03/02/06 torvalds@home.transmeta.com 1.925.48.24 # Merge # -------------------------------------------- # 03/02/07 bdschuym@pandora.be 1.925.1.52 # [BRIDGE]: update to new module scheme. # -------------------------------------------- # 03/02/07 jmorris@intercode.com.au 1.925.1.53 # [IPV4]: Fix skb leak in inet_rtm_getroute. # -------------------------------------------- # 03/02/07 jmorris@intercode.com.au 1.925.1.54 # [IPV6]: Fix skb leak in inet6_rtm_getroute. # -------------------------------------------- # 03/02/07 buytenh@gnu.org 1.925.1.55 # [BRIDGE]: Update maintainership status. # -------------------------------------------- # 03/02/07 buytenh@gnu.org 1.925.1.56 # [BRIDGE]: handle out-of-ports corner case. # -------------------------------------------- # 03/02/07 jmorris@intercode.com.au 1.925.1.57 # [LSM]: networking hooks, kconfig bits. # -------------------------------------------- # 03/02/07 jmorris@intercode.com.au 1.925.1.58 # [LSM]: Networking top-level socket operation hooks. # -------------------------------------------- # 03/02/07 jmorris@intercode.com.au 1.925.1.59 # [LSM]: Networking socket SKB receive hook. # -------------------------------------------- # 03/02/07 jmorris@intercode.com.au 1.925.1.60 # [LSM]: Networking AF_UNIX hooks. # -------------------------------------------- # 03/02/07 jmorris@intercode.com.au 1.925.1.61 # [LSM]: Networking netlink socket capability hooks. # -------------------------------------------- # 03/02/07 elenstev@mesatop.com 1.925.48.25 # [PATCH] Spelling fixes for consistent, dependent, persistent # # This fixes the following common misspellings and their variants. # # consistant -> consistent # dependant -> dependent # persistant -> persistent # -------------------------------------------- # 03/02/07 roland@redhat.com 1.925.48.26 # [PATCH] SA_NOCLDWAIT now supported - update comments # # This patch removes all the comments on the SA_NOCLDWAIT definitions, # since SA_NOCLDWAIT is fully supported now. # -------------------------------------------- # 03/02/07 roland@redhat.com 1.925.48.27 # [PATCH] do_sigaction locking cleanup # # This changes do_sigaction to avoid read_lock(&tasklist_lock) on every # call. Only in the fairly uncommon cases where it's really needed will # it take that lock (which requires unlocking and relocking the siglock # for locking order). # # I also changed the ERESTARTSYS added in my earlier patch to ERESTARTNOINTR. # That is an "instantaneous" case, and there is no reason to have it possibly # return EINTR if !SA_RESTART (which AFAIK sigaction never could before, and # it might not be kosher by POSIX); rollback is always better. # -------------------------------------------- # 03/02/07 akpm@digeo.com 1.925.48.28 # [PATCH] Fix possible uninitialised variable in vma merging code # # Spotted by davem. Strange that it ever worked. Don't know why the compiler # didn't warn... # -------------------------------------------- # 03/02/07 torvalds@home.transmeta.com 1.925.48.29 # Don't special-case SIGKILL/SIGSTOP - the blocking masks should # already take care of it. # # This fixes kernel threads that _do_ block SIGKILL/STOP. # -------------------------------------------- # 03/02/07 torvalds@home.transmeta.com 1.925.48.30 # Split up "struct signal_struct" into "signal" and "sighand" parts. # # This is required to get make the old LinuxThread semantics work # together with the fixed-for-POSIX full signal sharing. A traditional # CLONE_SIGHAND thread (LinuxThread) will not see any other shared # signal state, while a new-style CLONE_THREAD thread will share all # of it. # # This way the two methods don't confuse each other. # -------------------------------------------- # 03/02/07 drow@nevyn.them.org 1.925.48.31 # Hand merge # -------------------------------------------- # 03/02/07 cw@f00f.org 1.925.48.32 # [PATCH] signal locking update # # Accomodate the signal locking moving from "tsk->sig" to "tsk->sighand". # -------------------------------------------- # 03/02/07 roland@redhat.com 1.925.48.33 # [PATCH] TASK_STOPPED wakeup cleanup # # For handle_stop_signal to do the special case for SIGKILL and have it # work right in all SMP cases (without changing all the existing ptrace # stops), it needs to at least set TIF_SIGPENDING on each thread before # resuming it. # # handle_stop_signal addresses a related race for SIGCONT by setting # TIF_SIGPENDING already, so having SIGKILL handled the same way makes # sense. # # Now it seems pretty clean to have handle_stop_signal resume threads for # SIGKILL, and have on SIGKILL special case in group_send_sig_info. # # There is also an SMP race issue with cases like do_syscall_trace, i.e. # TASK_STOPPED state set without holding the siglock. So I think # handle_stop_signal should call wake_up_process unconditionally. # -------------------------------------------- # 03/02/08 anton@samba.org 1.945 # resolve conflicts # -------------------------------------------- # 03/02/08 kai@tp1.ruhr-uni-bochum.de 1.925.48.34 # kbuild: Handle external SUBDIRS with modversions # # We need to collect a list of all modules during the recursive build. I used # a "touch .tmp_versions/" to do so, which however doesn't # work so well, when path/to isn't inside the kernel tree. # # The best way to build external modules is currently using kbuild by saying # "make SUBDIRS=/some/external/dir modules", which was thus broken. While this # way is not all that optimal and I hope to come up with something better # before 2.6, it works and should keep working, so this patch fixes the usage # above. # # Instead of touching files with the entire path added, we just create a # .mod file in $(MODVERDIR) now, and save the path to the module.ko # in it. Since module names are unique, a flat hierarchy is actually fine here. # -------------------------------------------- # 03/02/08 kai@tp1.ruhr-uni-bochum.de 1.925.48.35 # kbuild: Warn on obsolete export-objs use # # Setting export-objs is not necessary anymore, so warn on encountering it # to prevent it from creeping back in ;) # # Also, make the error when we find someone still using O_TARGET non-fatal, # so that people sharing stuff between 2.4 and 2.5 don't have more hassle # than necessary. # -------------------------------------------- # 03/02/08 perex@suse.cz 1.925.54.1 # ALSA update # - cmipci driver cleanups (ac3 & surround) # - replaced snd_dma_residue() with snd_dma_pointer() # - GCC 3.3 warnings removal # - timer interface # - recoded using tasklet # - improved slave timer locking (should be much faster) # - added async support # - improved ioctl32 wrapper functions # - fixed Makefile problems (synth modules were build for not selected driver) # - AC97 codec # - improved SPSA control # - moved reset function outside the main init code # - improved ALC650 initialization # - USB driver # - added quirk for Roland XV-2020 # # -------------------------------------------- # 03/02/08 kai@tp1.ruhr-uni-bochum.de 1.925.48.36 # kbuild: Modversions fix # # We're still using the old genksyms binary, that's why we have to # postprocess the output to convert it into a linker script - that # postprocessing got confused by "__verify_write". # # Kick out the grep, do it all and correctly within sed. # # Bug reported by Thomas Molina. # -------------------------------------------- # 03/02/08 kai@tp1.ruhr-uni-bochum.de 1.925.48.37 # kbuild: Add a bug trap for people playing with SUBDIRS too much # # If SUBDIRS is set manually on the command line, the contents of # .tmp_versions are not deleted before descending and can accumulate # stale entries. Print a warning if that case is detected, but deal with # it gracefully. # -------------------------------------------- # 03/02/08 perex@suse.cz 1.925.54.2 # ALSA update # - emu10k1 - fixed makefile to not build synth module when emu10k1 is not selected # -------------------------------------------- # 03/02/08 cw@f00f.org 1.925.54.3 # [PATCH] missing sound include file # # Sound drivers need for tasklets # -------------------------------------------- # 03/02/08 torvalds@home.transmeta.com 1.925.54.4 # More signal handling fixups for the threaded signal fix upheavals. # # This fixes the signal code to not wake up threads with blocked signals, # especially noticeable with kernel threads that may not be able to handle # signals at all. # # We also don't unnecessarily wake processes in TASK_UNINTERRUPTIBLE. # -------------------------------------------- # 03/02/09 anton@samba.org 1.946 # Merge samba.org:/scratch/anton/linux-2.5 # into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/02/09 rmk@arm.linux.org.uk 1.925.54.5 # [PATCH] Fix Alt-SysRQ-T status, and comment # # Fix wrong order of process status. It's # # #define TASK_RUNNING 0 # #define TASK_INTERRUPTIBLE 1 # #define TASK_UNINTERRUPTIBLE 2 # #define TASK_STOPPED 4 # #define TASK_ZOMBIE 8 # #define TASK_DEAD 16 # # but SysRQ printout routines switch stopped and zombie around. # # So, for one more time, here's another mailing of the same patch to fix # this brokenness. In addition, fix the wrong comment in fs/proc/array.c # -------------------------------------------- # 03/02/09 akpm@digeo.com 1.925.54.6 # [PATCH] Fix compile warning for 'sys_exit_group' # # sys_exit_group() doesn't return any value, and obviously cannot. # # So don't make the compiler unhappy about it by claiming it does. # -------------------------------------------- # 03/02/09 jamie@shareable.org 1.925.54.7 # [PATCH] CONFIG_PREEMPT fix of do_debug() # # If CONFIG_PREEMPT is enabled, and the kernel is preempted just before # do_debug() has a chance to save the debug register values, DR6 could be # read from the wrong CPU. # # It is exactly the same problem as reading %cr2 in the page fault # handler. Same fix: make the handler a interrupt gate, and enable # interrupts only once safe. # -------------------------------------------- # 03/02/09 davem@kernel.bkbits.net 1.925.1.62 # Merge davem@nuts.ninka.net:/home/davem/src/BK/net-2.5 # into kernel.bkbits.net:/home/davem/net-2.5 # -------------------------------------------- # 03/02/09 jejb@raven.il.steeleye.com 1.925.54.8 # Restore device command queue functionality # # The recent slab allocation changes mean that we no longer keep a # permanent list of commands on the device_queue list. However, # certain pieces of SCSI code relied on being able to traverse this # list to find details of all outstanding commands (the error handler # being the prime example). This code adds back a new dynamic cmd_list # which keeps the list of commands currently allocated to the device. # Since the list is dynamic, it is protected by a lock (list_lock). # -------------------------------------------- # 03/02/09 jejb@raven.il.steeleye.com 1.925.54.9 # [SCSI] Migrate sim710 to 53c700 chip driver # # This should add synchronous support and Tagged Command Queueing. # At the moment, it cuts down on the number of command line options, # but we can add those back in later. # # This patch also migrates the driver to the new device model for # both MCA and EISA. # -------------------------------------------- # 03/02/09 luben@splentec.com 1.925.54.10 # [SCSI] add commands at the tail of cmd_list # # It's probably going to be a fifo, so it should be more efficient # for taking them off again # -------------------------------------------- # 03/02/09 jejb@raven.il.steeleye.com 1.925.54.11 # [SCSI] Remove 53c7,8xx since we have plenty of alternatives. # # We have 53c700.c and 53c7xx for the 7xx series and # ncr53c8xx for the 720. The sym53c8xx_2 covers all the 8xx chips. # -------------------------------------------- # 03/02/09 jejb@mulgrave.(none) 1.925.54.12 # [SCSI] Add missing list head init of cmd_list # -------------------------------------------- # 03/02/09 perex@suse.cz 1.925.55.1 # ALSA update # - moved inclusion of from to # - pmac driver - removed beep stuff for 2.5 kernels # - USB driver - fixed compilation # -------------------------------------------- # 03/02/10 anton@samba.org 1.947 # Merge samba.org:/scratch/anton/linux-2.5 # into samba.org:/scratch/anton/sfr # -------------------------------------------- # 03/02/10 anton@samba.org 1.948 # ppc64: update for signal changes # -------------------------------------------- # 03/02/10 anton@samba.org 1.949 # ppc64: Fix nasty bug in cmpxchg where we would sign extend the old value. # -------------------------------------------- # 03/02/09 torvalds@home.transmeta.com 1.950 # Merge http://linux-sound.bkbits.net/linux-sound # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/09 torvalds@home.transmeta.com 1.951 # Merge http://linux-scsi.bkbits.net/scsi-for-linus-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/09 mingo@elte.hu 1.952 # [PATCH] Lock session and group ID setting # # - session-IDs and group-IDs are set outside the tasklist lock. This # causes breakage in the USB code. The correct fix is to do this: # # I introduced the bug with the new pidhash. # -------------------------------------------- # 03/02/09 mingo@elte.hu 1.953 # [PATCH] lock group_send_sig_info() properly # # - a read_lock(&tasklist_lock) is missing around the group_send_sig_info() # in send_sig_info(). # -------------------------------------------- # 03/02/09 torvalds@home.transmeta.com 1.954 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/09 roland@redhat.com 1.955 # [PATCH] zap_other_threads() needs tasklist_lock held # -------------------------------------------- # 03/02/09 mikulas@artax.karlin.mff.cuni.cz 1.956 # [PATCH] simple EXT2 patch # # Do not crash on null pointer dereference, if cannot reread superblock. # -------------------------------------------- # 03/02/09 torvalds@home.transmeta.com 1.957 # Make sigprocmask() available to kernel threads too, since a lot of # them do want to temporarily block signals. # # Kernel users can also block signals that are normally unblockable # to user space, ie SIGKILL and SIGSTOP. # # Make nfsd and autofs use the new interface, as an example to others. # -------------------------------------------- # 03/02/09 torvalds@home.transmeta.com 1.958 # Fix missing break, causing sigprocmask(SIG_SETMASK ...) to always # return an error. # # Interestingly, nobody much seems to care. Apparently few programs # check the error value. # -------------------------------------------- # 03/02/09 torvalds@home.transmeta.com 1.959 # Merge http://linux-isdn.bkbits.net/linux-2.5.make # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.960 # [PATCH] Documentation_Changes # # From: Frank Davis # # this was already mentioned on l-k by ramune@net-ronin.org, but isn't in # 2.5.59. Placing on the trivial queue for inclusion. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.961 # [PATCH] Remove superflous 'either' # # From: John Bradford # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.962 # [PATCH] fix comment in module.c # # From: John Levon # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.963 # [PATCH] remove check_region from drivers_net_irda_irport.c # # From: william stinson # # this patch for drivers/net/irda/irport.c IRDA driver removes one call # to check_region using request_region instead. The patch also moves # the call to request_region to before the allocation of the driver # instance. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.964 # [PATCH] parport_pc and !CONFIG_PNP # # From: Geert Uytterhoeven # # parport_pc_pnp_driver is const if !CONFIG_PNP, while pnp_register_driver() # takes a non-const pointer as parameter. # # An alternative fix is to change the prototype of the dummy # pnp_register_driver(), but this may affect other drivers. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.965 # [PATCH] Change "char _version" to "char in drivers_lcs.c # # From: Pablo Menichini # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.966 # [PATCH] add one help text to drivers_atm_Kconfig # # From: Steven Cole # # Here is a help text from 2.4.21-pre4 Configure.help which is # needed in 2.5.59 drivers/atm/Kconfig. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.967 # [PATCH] scripts_ver_linux # # From: Frank Davis # # The ver_linux script is still using rmmod to determine # module-init-tools version. The following patch uses depmod, # which produces the appropriate result. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.968 # [PATCH] Change "char _version" to "char in drivers_net_mac8390.c # # From: Pablo Menichini # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.969 # [PATCH] add two help texts to drivers_i2c_Kconfig # # From: Steven Cole # # Here are some help texts from 2.4.21-pre3 Configure.help which are # needed in 2.5.59 drivers/i2c/Kconfig. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.970 # [PATCH] Remove compile warning from fs_xfs_support_move.c # # From: Bob Miller # # Include string.h to remove a compiler warning. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.971 # [PATCH] make i2c-core driver_lock static # # From: Muli Ben-Yehuda # # The i2c driver_lock is needlessly exported. # This makes it static. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.972 # [PATCH] Memory leak in drivers_net_arlan.c (1) # # From: Pablo Menichini # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.973 # [PATCH] RTC alarm and wildcards # # (Included in 2.4) # From: Paul Gortmaker # # Summary: Wildcards in RTC alarm settings failed to work # # Description: # The RTC has provision for wildcards when setting the alarm; to # use them you have to write a value higher than 0xc0 to the # appropriate hr/min/sec entry. The driver used 0xff, which is # fine, but it mistakenly fed the 0xff through BIN_TO_BCD before # writing them (which is < 0xc0) and so wildcards didn't work. # (Thanks to Gerhard Kurz for reporting the bug.) # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.974 # [PATCH] fix typo of members name in drivers_mtd_ftl.c # # From: Pablo Menichini # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.975 # [PATCH] Fix return code of init_module in drivers_net_arlan.c (2) # # From: Pablo Menichini # # This patch returns correct error codes if init_modules fail. # Because of this, we can take the printks indicating the error as these # corrected error codes return miningfull information. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.976 # [PATCH] Kill unused code # # From: Pavel Machek # # Second part of this patch never got in (and I was told it was not bug # in ASUS but in linux), so it is useless junk... Please apply, # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.977 # [PATCH] remove LinuxVersionCode from de4x5.h # # From: Adrian Bunk # # drivers/net/tulip/de4x5.h in 2.5.54 contains a definition of # LinuxVersionCode. LinuxVersionCode isn't used and it's anyway obsoleted # by KERNEL_VERSION in version.h. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.978 # [PATCH] nfs_write.c warning # # From: William Lee Irwin III # # This trivially corrects an unused variable warning in nfs/write.c: # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.979 # [PATCH] Squash unused function in fs_nfs_mount_clnt.c # # From: David Gibson # # is never used, so this patch removes it. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.980 # [PATCH] fix spelling of kernel in arch_v850_kernel_mach.h # # From: Steven Cole # # This fixes the only instance of "kernal" in 2.5.59. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.981 # [PATCH] fix linewrap in Documentation_arm_SA1100_CERF # # [ Verified that no text changed with tr and cmp --RR ] # From: ookhoi@humilis.net # # With this patch I tried to make Documentation/arm/SA1100/CERF more # readible by fixing the linewrap. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.982 # [PATCH] swsusp: do not panic on bad signature with noresume # # From: Pavel Machek # # This patch makes kernel ignore bad signature on suspend device when # "noresume" is given, and cleans things up a little bit. Please apply, # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.983 # [PATCH] add six help texts to drivers_ide_Kconfig # # From: Steven Cole # # Here are some help texts from 2.4.21-pre3 Configure.help which are # needed in 2.5.59 drivers/ide/Kconfig. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.984 # [PATCH] add four help texts to drivers_char_watchdog_Kconfig # # From: Steven Cole # # Here are some help texts from 2.4.21-pre3 Configure.help which are # needed in 2.5.59 drivers/char/watchdog/Kconfig. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.985 # [PATCH] Change "char version" to initdata in drivers_net_tulip_de4x5.c # # From: Pablo Menichini # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.986 # [PATCH] add two help texts to drivers_media_video_Kconfig # # From: Steven Cole # # Here are some help texts from 2.4.21-pre3 Configure.help which are # needed in 2.5.59 drivers/media/video/Kconfig. # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.987 # [PATCH] Write with buffer>2GB returns broken errno (2) # # [ Acked by AKPM --RR ] # From: Kazuto MIYOSHI # # On 64-bit platforms, issuing write(2) with buffer larger than # 2GB will return -1 and broken errno (such as 2147483640) # Requested data itself is written correctly. # # That is because generic_file_write() and other relating functions # store 'ssize_t written' into 'int err'. Written byte is trimmed to # int and then sign-extended to a negative ssize_t value, which # wrongly indicates an error. # # (On 64bit platform, current glibc defines SSIZE_MAX as 'LONG_MAX') # -------------------------------------------- # 03/02/09 rusty@rustcorp.com.au 1.988 # [PATCH] Change all .o to .ko in Kconfig files # # From: GertJan Spoelman # # OK, here is a new patch, I edited the old patch and took out the .ko's # so now the extension is trimmed instead. # -------------------------------------------- # diff -Nru a/Documentation/Changes b/Documentation/Changes --- a/Documentation/Changes Sun Feb 9 21:13:36 2003 +++ b/Documentation/Changes Sun Feb 9 21:13:36 2003 @@ -52,7 +52,7 @@ o Gnu make 3.78 # make --version o binutils 2.9.5.0.25 # ld -v o util-linux 2.10o # fdformat --version -o module-init-tools 0.9.8 # rmmod -V +o module-init-tools 0.9.9 # depmod -V o e2fsprogs 1.29 # tune2fs o jfsutils 1.0.14 # fsck.jfs -V o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs diff -Nru a/Documentation/DocBook/journal-api.tmpl b/Documentation/DocBook/journal-api.tmpl --- a/Documentation/DocBook/journal-api.tmpl Sun Feb 9 21:13:28 2003 +++ b/Documentation/DocBook/journal-api.tmpl Sun Feb 9 21:13:28 2003 @@ -141,17 +141,14 @@ Or if you've asked for access to a buffer you now know is now longer required to be pushed back on the device you can call journal_forget() in much the same way as you might have used bforget() in the past. - - - A journal_flush() may be called at any time to commit and checkpoint all your transactions. - + Then at umount time , in your put_super() (2.4) or write_super() (2.5) you can then call journal_destroy() to clean up your in-core journal object. @@ -168,8 +165,8 @@ across differing journals, and another filesystem other than yours (say ext3) may be modified in a later syscall. - + The second case to bear in mind is that journal_start() can block if there isn't enough space in the journal for your transaction (based on the passed nblocks param) - when it blocks it merely(!) needs to @@ -180,10 +177,14 @@ deadlocks. Note that journal_extend() has similar blocking behaviour to journal_start() so you can deadlock here just as easily as on journal_start(). - -Try to reserve the right number of blocks the first time. ;-). + +Try to reserve the right number of blocks the first time. ;-). This will +be the maximum number of blocks you are going to touch in this transaction. +I advise having a look at at least ext3_jbd.h to see the basis on which +ext3 uses to make these decisions. + Another wriggle to watch out for is your on-disk block allocation strategy. why? Because, if you undo a delete, you need to ensure you haven't reused any @@ -211,6 +212,30 @@ if you allow unprivileged userspace to trigger codepaths containing these calls. + + +A new feature of jbd since 2.5.25 is commit callbacks with the new +journal_callback_set() function you can now ask the journalling layer +to call you back when the transaction is finally commited to disk, so that +you can do some of your own management. The key to this is the journal_callback +struct, this maintains the internal callback information but you can +extend it like this:- + + + struct myfs_callback_s { + //Data structure element required by jbd.. + struct journal_callback for_jbd; + // Stuff for myfs allocated together. + myfs_inode* i_commited; + + } + + + +this would be useful if you needed to know when data was commited to a +particular inode. + + diff -Nru a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers --- a/Documentation/SubmittingDrivers Sun Feb 9 21:13:34 2003 +++ b/Documentation/SubmittingDrivers Sun Feb 9 21:13:34 2003 @@ -62,7 +62,7 @@ in Documentation/CodingStyle. If you have sections of code that need to be in other formats, for example because they are shared with a windows driver kit and you want to - maintain them just once seperate them out nicely and note + maintain them just once separate them out nicely and note this fact. Portability: Pointers are not always 32bits, not all computers are little diff -Nru a/Documentation/arm/SA1100/CERF b/Documentation/arm/SA1100/CERF --- a/Documentation/arm/SA1100/CERF Sun Feb 9 21:13:28 2003 +++ b/Documentation/arm/SA1100/CERF Sun Feb 9 21:13:28 2003 @@ -1,23 +1,28 @@ -The Intrinsyc CerfBoard is a StrongARM 1110-based computer on a board that measures -approximately 2" square. It includes an Ethernet controller, an RS232-compatible serial port, a -USB function port, and one CompactFlash+ slot on the back. Pictures can be found at the +The Intrinsyc CerfBoard is a StrongARM 1110-based computer on a board +that measures approximately 2" square. It includes an Ethernet +controller, an RS232-compatible serial port, a USB function port, and +one CompactFlash+ slot on the back. Pictures can be found at the Intrinsyc website, http://www.intrinsyc.com. -This document describes the support in the Linux kernel for the Intrinsyc CerfBoard as of -version 2.4.0-test4-np1. +This document describes the support in the Linux kernel for the +Intrinsyc CerfBoard as of version 2.4.0-test4-np1. Supported in this version: - - CompactFlash+ slot (select PCMCIA in General Setup and any options that may be required) - - Onboard Crystal CS8900 Ethernet controller (Cerf CS8900A support in Network Devices) + - CompactFlash+ slot (select PCMCIA in General Setup and any options + that may be required) + - Onboard Crystal CS8900 Ethernet controller (Cerf CS8900A support in + Network Devices) - Serial ports with a serial console (hardcoded to 38400 8N1) Not supported in this version (yet): - LCD driver/touchscreen interface - - UDC (a driver exists right now, but is unstable and slow and only works with the Linux USB) + - UDC (a driver exists right now, but is unstable and slow and only + works with the Linux USB) -In order to get this kernel onto your Cerf, you need a server that runs both BOOTP and -TFTP. Detailed instructions should have come with your evaluation kit on how to use the -bootloader. This series of commands will suffice: +In order to get this kernel onto your Cerf, you need a server that runs +both BOOTP and TFTP. Detailed instructions should have come with your +evaluation kit on how to use the bootloader. This series of commands +will suffice: make cerf_config make xconfig @@ -25,10 +30,9 @@ make zImage cp arch/arm/boot/zImage -The default config uses a 4MB RAM disk located at 0xc0500000 as root. Setting the board to -mount root from a NFS partition works, too. +The default config uses a 4MB RAM disk located at 0xc0500000 as root. +Setting the board to mount root from a NFS partition works, too. I-Gene Leong, Intrinsyc Software Inc. ileong@intrinsyc.com - diff -Nru a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt --- a/Documentation/filesystems/ext3.txt Sun Feb 9 21:13:31 2003 +++ b/Documentation/filesystems/ext3.txt Sun Feb 9 21:13:31 2003 @@ -78,7 +78,7 @@ filesystem code will inform the JBD of modifications it is performing (Call a transaction). the journal support the transactions start and stop, and in case of crash, the journal can replayed the transactions -to put the partition on a consistant state fastly. +to put the partition on a consistent state fastly. handles represent a single atomic update to a filesystem. JBD can handle external journal on a block device. diff -Nru a/Documentation/filesystems/jfs.txt b/Documentation/filesystems/jfs.txt --- a/Documentation/filesystems/jfs.txt Sun Feb 9 21:13:33 2003 +++ b/Documentation/filesystems/jfs.txt Sun Feb 9 21:13:33 2003 @@ -28,8 +28,6 @@ Plans for our near term development items - enhance support for logfile on dedicated partition - - get access control list functionality operational - - get extended attributes functionality operational Longer term work items @@ -37,7 +35,7 @@ - add quota support - add support for block sizes (512,1024,2048) -Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com. +Please send bugs, comments, cards and letters to shaggy@austin.ibm.com. The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe" at our web page http://oss.software.ibm.com/jfs/. diff -Nru a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt --- a/Documentation/filesystems/proc.txt Sun Feb 9 21:13:30 2003 +++ b/Documentation/filesystems/proc.txt Sun Feb 9 21:13:30 2003 @@ -911,7 +911,7 @@ The four values in printk denote * console_loglevel, * default_message_loglevel, -* minimum_console_level and +* minimum_console_loglevel and * default_console_loglevel respectively. diff -Nru a/Documentation/ia64/README b/Documentation/ia64/README --- a/Documentation/ia64/README Sun Feb 9 21:13:36 2003 +++ b/Documentation/ia64/README Sun Feb 9 21:13:36 2003 @@ -4,40 +4,40 @@ platform. This document provides information specific to IA-64 ONLY, to get additional information about the Linux kernel also read the original Linux README provided with the kernel. - + INSTALLING the kernel: - IA-64 kernel installation is the same as the other platforms, see original README for details. - - + + SOFTWARE REQUIREMENTS Compiling and running this kernel requires an IA-64 compliant GCC compiler. And various software packages also compiled with an IA-64 compliant GCC compiler. - + CONFIGURING the kernel: Configuration is the same, see original README for details. - - + + COMPILING the kernel: - Compiling this kernel doesn't differ from other platform so read the original README for details BUT make sure you have an IA-64 compliant GCC compiler. - + IA-64 SPECIFICS - General issues: - + o Hardly any performance tuning has been done. Obvious targets include the library routines (IP checksum, etc.). Less obvious targets include making sure we don't flush the TLB needlessly, etc. - + o SMP locks cleanup/optimization - + o IA32 support. Currently experimental. It mostly works. diff -Nru a/Documentation/ia64/fsys.txt b/Documentation/ia64/fsys.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/ia64/fsys.txt Sun Feb 9 21:13:38 2003 @@ -0,0 +1,231 @@ +-*-Mode: outline-*- + + Light-weight System Calls for IA-64 + ----------------------------------- + + Started: 13-Jan-2003 + Last update: 24-Jan-2003 + + David Mosberger-Tang + + +Using the "epc" instruction effectively introduces a new mode of +execution to the ia64 linux kernel. We call this mode the +"fsys-mode". To recap, the normal states of execution are: + + - kernel mode: + Both the register stack and the memory stack have been + switched over to kernel memory. The user-level state is saved + in a pt-regs structure at the top of the kernel memory stack. + + - user mode: + Both the register stack and the kernel stack are in + user memory. The user-level state is contained in the + CPU registers. + + - bank 0 interruption-handling mode: + This is the non-interruptible state which all + interruption-handlers start execution in. The user-level + state remains in the CPU registers and some kernel state may + be stored in bank 0 of registers r16-r31. + +In contrast, fsys-mode has the following special properties: + + - execution is at privilege level 0 (most-privileged) + + - CPU registers may contain a mixture of user-level and kernel-level + state (it is the responsibility of the kernel to ensure that no + security-sensitive kernel-level state is leaked back to + user-level) + + - execution is interruptible and preemptible (an fsys-mode handler + can disable interrupts and avoid all other interruption-sources + to avoid preemption) + + - neither the memory nor the register stack can be trusted while + in fsys-mode (they point to the user-level stacks, which may + be invalid) + +In summary, fsys-mode is much more similar to running in user-mode +than it is to running in kernel-mode. Of course, given that the +privilege level is at level 0, this means that fsys-mode requires some +care (see below). + + +* How to tell fsys-mode + +Linux operates in fsys-mode when (a) the privilege level is 0 (most +privileged) and (b) the stacks have NOT been switched to kernel memory +yet. For convenience, the header file provides +three macros: + + user_mode(regs) + user_stack(task,regs) + fsys_mode(task,regs) + +The "regs" argument is a pointer to a pt_regs structure. The "task" +argument is a pointer to the task structure to which the "regs" +pointer belongs to. user_mode() returns TRUE if the CPU state pointed +to by "regs" was executing in user mode (privilege level 3). +user_stack() returns TRUE if the state pointed to by "regs" was +executing on the user-level stack(s). Finally, fsys_mode() returns +TRUE if the CPU state pointed to by "regs" was executing in fsys-mode. +The fsys_mode() macro is equivalent to the expression: + + !user_mode(regs) && user_stack(task,regs) + +* How to write an fsyscall handler + +The file arch/ia64/kernel/fsys.S contains a table of fsyscall-handlers +(fsyscall_table). This table contains one entry for each system call. +By default, a system call is handled by fsys_fallback_syscall(). This +routine takes care of entering (full) kernel mode and calling the +normal Linux system call handler. For performance-critical system +calls, it is possible to write a hand-tuned fsyscall_handler. For +example, fsys.S contains fsys_getpid(), which is a hand-tuned version +of the getpid() system call. + +The entry and exit-state of an fsyscall handler is as follows: + +** Machine state on entry to fsyscall handler: + + - r10 = 0 + - r11 = saved ar.pfs (a user-level value) + - r15 = system call number + - r16 = "current" task pointer (in normal kernel-mode, this is in r13) + - r32-r39 = system call arguments + - b6 = return address (a user-level value) + - ar.pfs = previous frame-state (a user-level value) + - PSR.be = cleared to zero (i.e., little-endian byte order is in effect) + - all other registers may contain values passed in from user-mode + +** Required machine state on exit to fsyscall handler: + + - r11 = saved ar.pfs (as passed into the fsyscall handler) + - r15 = system call number (as passed into the fsyscall handler) + - r32-r39 = system call arguments (as passed into the fsyscall handler) + - b6 = return address (as passed into the fsyscall handler) + - ar.pfs = previous frame-state (as passed into the fsyscall handler) + +Fsyscall handlers can execute with very little overhead, but with that +speed comes a set of restrictions: + + o Fsyscall-handlers MUST check for any pending work in the flags + member of the thread-info structure and if any of the + TIF_ALLWORK_MASK flags are set, the handler needs to fall back on + doing a full system call (by calling fsys_fallback_syscall). + + o Fsyscall-handlers MUST preserve incoming arguments (r32-r39, r11, + r15, b6, and ar.pfs) because they will be needed in case of a + system call restart. Of course, all "preserved" registers also + must be preserved, in accordance to the normal calling conventions. + + o Fsyscall-handlers MUST check argument registers for containing a + NaT value before using them in any way that could trigger a + NaT-consumption fault. If a system call argument is found to + contain a NaT value, an fsyscall-handler may return immediately + with r8=EINVAL, r10=-1. + + o Fsyscall-handlers MUST NOT use the "alloc" instruction or perform + any other operation that would trigger mandatory RSE + (register-stack engine) traffic. + + o Fsyscall-handlers MUST NOT write to any stacked registers because + it is not safe to assume that user-level called a handler with the + proper number of arguments. + + o Fsyscall-handlers need to be careful when accessing per-CPU variables: + unless proper safe-guards are taken (e.g., interruptions are avoided), + execution may be pre-empted and resumed on another CPU at any given + time. + + o Fsyscall-handlers must be careful not to leak sensitive kernel' + information back to user-level. In particular, before returning to + user-level, care needs to be taken to clear any scratch registers + that could contain sensitive information (note that the current + task pointer is not considered sensitive: it's already exposed + through ar.k6). + +The above restrictions may seem draconian, but remember that it's +possible to trade off some of the restrictions by paying a slightly +higher overhead. For example, if an fsyscall-handler could benefit +from the shadow register bank, it could temporarily disable PSR.i and +PSR.ic, switch to bank 0 (bsw.0) and then use the shadow registers as +needed. In other words, following the above rules yields extremely +fast system call execution (while fully preserving system call +semantics), but there is also a lot of flexibility in handling more +complicated cases. + +* Signal handling + +The delivery of (asynchronous) signals must be delayed until fsys-mode +is exited. This is acomplished with the help of the lower-privilege +transfer trap: arch/ia64/kernel/process.c:do_notify_resume_user() +checks whether the interrupted task was in fsys-mode and, if so, sets +PSR.lp and returns immediately. When fsys-mode is exited via the +"br.ret" instruction that lowers the privilege level, a trap will +occur. The trap handler clears PSR.lp again and returns immediately. +The kernel exit path then checks for and delivers any pending signals. + +* PSR Handling + +The "epc" instruction doesn't change the contents of PSR at all. This +is in contrast to a regular interruption, which clears almost all +bits. Because of that, some care needs to be taken to ensure things +work as expected. The following discussion describes how each PSR bit +is handled. + +PSR.be Cleared when entering fsys-mode. A srlz.d instruction is used + to ensure the CPU is in little-endian mode before the first + load/store instruction is executed. PSR.be is normally NOT + restored upon return from an fsys-mode handler. In other + words, user-level code must not rely on PSR.be being preserved + across a system call. +PSR.up Unchanged. +PSR.ac Unchanged. +PSR.mfl Unchanged. Note: fsys-mode handlers must not write-registers! +PSR.mfh Unchanged. Note: fsys-mode handlers must not write-registers! +PSR.ic Unchanged. Note: fsys-mode handlers can clear the bit, if needed. +PSR.i Unchanged. Note: fsys-mode handlers can clear the bit, if needed. +PSR.pk Unchanged. +PSR.dt Unchanged. +PSR.dfl Unchanged. Note: fsys-mode handlers must not write-registers! +PSR.dfh Unchanged. Note: fsys-mode handlers must not write-registers! +PSR.sp Unchanged. +PSR.pp Unchanged. +PSR.di Unchanged. +PSR.si Unchanged. +PSR.db Unchanged. The kernel prevents user-level from setting a hardware + breakpoint that triggers at any privilege level other than 3 (user-mode). +PSR.lp Unchanged. +PSR.tb Lazy redirect. If a taken-branch trap occurs while in + fsys-mode, the trap-handler modifies the saved machine state + such that execution resumes in the gate page at + syscall_via_break(), with privilege level 3. Note: the + taken branch would occur on the branch invoking the + fsyscall-handler, at which point, by definition, a syscall + restart is still safe. If the system call number is invalid, + the fsys-mode handler will return directly to user-level. This + return will trigger a taken-branch trap, but since the trap is + taken _after_ restoring the privilege level, the CPU has already + left fsys-mode, so no special treatment is needed. +PSR.rt Unchanged. +PSR.cpl Cleared to 0. +PSR.is Unchanged (guaranteed to be 0 on entry to the gate page). +PSR.mc Unchanged. +PSR.it Unchanged (guaranteed to be 1). +PSR.id Unchanged. Note: the ia64 linux kernel never sets this bit. +PSR.da Unchanged. Note: the ia64 linux kernel never sets this bit. +PSR.dd Unchanged. Note: the ia64 linux kernel never sets this bit. +PSR.ss Lazy redirect. If set, "epc" will cause a Single Step Trap to + be taken. The trap handler then modifies the saved machine + state such that execution resumes in the gate page at + syscall_via_break(), with privilege level 3. +PSR.ri Unchanged. +PSR.ed Unchanged. Note: This bit could only have an effect if an fsys-mode + handler performed a speculative load that gets NaTted. If so, this + would be the normal & expected behavior, so no special treatment is + needed. +PSR.bn Unchanged. Note: fsys-mode handlers may clear the bit, if needed. + Doing so requires clearing PSR.i and PSR.ic as well. +PSR.ia Unchanged. Note: the ia64 linux kernel never sets this bit. diff -Nru a/Documentation/isdn/HiSax.cert b/Documentation/isdn/HiSax.cert --- a/Documentation/isdn/HiSax.cert Sun Feb 9 21:13:29 2003 +++ b/Documentation/isdn/HiSax.cert Sun Feb 9 21:13:29 2003 @@ -27,7 +27,7 @@ the layer 1. Because all hardware based on these chips are complete ISDN solutions in one chip all cards and USB-TAs using these chips are to be regarded as approved for those tests. Some additional electrical tests -of the layer 1 which are independant of the driver and related to a +of the layer 1 which are independent of the driver and related to a special hardware used will be regarded as approved if at least one solution has been tested including those electrical tests. So if cards or tas have been completely approved for any other os, the approval diff -Nru a/Documentation/kbuild/00-INDEX b/Documentation/kbuild/00-INDEX --- a/Documentation/kbuild/00-INDEX Sun Feb 9 21:13:29 2003 +++ b/Documentation/kbuild/00-INDEX Sun Feb 9 21:13:29 2003 @@ -1,10 +1,10 @@ 00-INDEX - this file: info on the kernel build process -bug-list.txt - - known bugs in kbuild programs commands.txt - overview of kbuild commands kconfig-language.txt - specification of Config Language, the language in Kconfig files +random.txt + - description of generic config targets makefiles.txt - developer information for linux kernel makefiles diff -Nru a/Documentation/kbuild/bug-list.txt b/Documentation/kbuild/bug-list.txt --- a/Documentation/kbuild/bug-list.txt Sun Feb 9 21:13:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,22 +0,0 @@ -Bug List -21 January 1999 -Michael Elizabeth Chastain, - -- If a variable has a value of "m" in the previous .config file, - and a type of bool in the Config script, then all the interpreters - get confused. This happens frequently when someone changes a - tristate option to a bool option and people in the field have - .config files with a value of 'm'. For example: CONFIG_PSMOUSE. - -- CONFIG_MODVERSIONS has incorrect dependencies. If you have a - problem building the kernel, and you have CONFIG_MODVERSIONS turned - on, do a 'make dep' followed by 'make clean' before you try anything - else. - -- 'make dep' uses multistage dependencies, so the .hdepend file contains - 'touch' commands. As a result, building a kernel often touches files - in include/linux/*.h. This messes up CVS and other systems which like - to rely on file dates. - -- 'make dep' fails for C files which include other C files, such as - drivers/cdrom/sbpcd2.c. diff -Nru a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt --- a/Documentation/kbuild/makefiles.txt Sun Feb 9 21:13:34 2003 +++ b/Documentation/kbuild/makefiles.txt Sun Feb 9 21:13:34 2003 @@ -1,74 +1,76 @@ Linux Kernel Makefiles -2000-September-14 -Michael Elizabeth Chastain, - - - -=== Table of Contents This document describes the Linux kernel Makefiles. - 1 Overview - 2 Who does what - 3 Makefile language - 4 Variables passed down from the top - 5 The structure of an arch Makefile - 5.1 Architecture-specific variables - 5.2 Vmlinux build variables - 5.3 Post-vmlinux goals - 5.4 Mandatory arch-specific goals - 6 The structure of a subdirectory Makefile - 6.1 Comments - 6.2 Goal definitions - 6.3 Adapter section - 6.4 Rules.make section - 6.5 Special rules - 7 Rules.make variables - 7.1 Subdirectories - 7.2 Object file goals - 7.3 Library file goals - 7.4 Loadable module goals - 7.5 Multi-part modules - 7.6 Compilation flags - 7.7 Miscellaneous variables - 8 New-style variables - 8.1 New variables - 8.2 Converting to old-style - 9 Credits +=== Table of Contents + === 1 Overview + === 2 Who does what + === 3 The kbuild Makefiles + --- 3.1 Goal definitions + --- 3.2 Built-in object goals - obj-y + --- 3.3 Loadable module goals - obj-m + --- 3.4 Objects which export symbols - export-objs + --- 3.5 Library file goals - L_TARGET + --- 3.6 Descending down in directories + --- 3.7 Compilation flags + --- 3.8 Command line dependency + --- 3.9 Dependency tracking + --- 3.10 Special Rules + + === 4 Host Program support + --- 4.1 Simple Host Program + --- 4.2 Composite Host Programs + --- 4.3 Defining shared libraries + --- 4.4 Using C++ for host programs + --- 4.5 Controlling compiler options for host programs + --- 4.6 When host programs are actually built + + === 5 Kbuild clean infrastructure + + === 6 Architecture Makefiles + --- 6.1 Set variables to tweak the build to the architecture + --- 6.2 Add prerequisites to prepare: + --- 6.3 List directories to visit when descending + --- 6.4 Architecture specific boot images + --- 6.5 Building non-kbuild targets + --- 6.6 Commands useful for building a boot image + --- 6.7 Custom kbuild commands + + === 7 Kbuild Variables + === 8 Makefile language + === 9 Credits + === 10 TODO === 1 Overview The Makefiles have five parts: - Makefile: the top Makefile. - .config: the kernel configuration file. - arch/*/Makefile: the arch Makefiles. - Subdirectory Makefiles: there are about 300 of these. - Rules.make: the common rules for all subdirectory Makefiles. + Makefile the top Makefile. + .config the kernel configuration file. + arch/$(ARCH)/Makefile the arch Makefile. + scripts/Makefile.* common rules etc. for all kbuild Makefiles. + kbuild Makefiles there are about 500 of these. -The top Makefile reads the .config file, which comes from the -kernel configuration process. +The top Makefile reads the .config file, which comes from the kernel +configuration process. The top Makefile is responsible for building two major products: vmlinux -(the resident kernel image) and modules (any module files). It builds -these goals by recursively descending into the subdirectories of the -kernel source tree. The list of subdirectories which are visited depends -upon the kernel configuration. - -The top Makefile textually includes an arch Makefile with the name -arch/$(ARCH)/Makefile. The arch Makefile supplies architecture-specific -information to the top Makefile. - -Each subdirectory has a Makefile which carries out the commands passed -down from above. The subdirectory Makefile uses information from the -.config file to construct various file lists, and then it textually -includes the common rules in Rules.make. - -Rules.make defines rules which are common to all the subdirectory -Makefiles. It has a public interface in the form of certain variable -lists. It then declares rules based on those lists. +(the resident kernel image) and modules (any module files). +It builds these goals by recursively descending into the subdirectories of +the kernel source tree. +The list of subdirectories which are visited depends upon the kernel +configuration. The top Makefile textually includes an arch Makefile +with the name arch/$(ARCH)/Makefile. The arch Makefile supplies +architecture-specific information to the top Makefile. + +Each subdirectory has a kbuild Makefile which carries out the commands +passed down from above. The kbuild Makefile uses information from the +.config file to construct various file lists used by kbuild to build +any built-in or modular targets. +scripts/Makefile.* contains all the definitions/rules etc. that +are used to build the kernel based on the kbuild makefiles. === 2 Who does what @@ -76,19 +78,19 @@ People have four different relationships with the kernel Makefiles. *Users* are people who build kernels. These people type commands such as -"make menuconfig" or "make bzImage". They usually do not read or edit +"make menuconfig" or "make". They usually do not read or edit any kernel Makefiles (or any other source files). *Normal developers* are people who work on features such as device drivers, file systems, and network protocols. These people need to -maintain the subdirectory Makefiles for the subsystem that they are +maintain the kbuild Makefiles for the subsystem that they are working on. In order to do this effectively, they need some overall knowledge about the kernel Makefiles, plus detailed knowledge about the -public interface for Rules.make. +public interface for kbuild. *Arch developers* are people who work on an entire architecture, such -as sparc or ia64. Arch developers need to know about the arch Makefiles -as well as subdirectory Makefiles. +as sparc or ia64. Arch developers need to know about the arch Makefile +as well as kbuild Makefiles. *Kbuild developers* are people who work on the kernel build system itself. These people need to know about all aspects of the kernel Makefiles. @@ -96,883 +98,895 @@ This document is aimed towards normal developers and arch developers. +=== 3 The kbuild Makefiles -=== 3 Makefile language - -The kernel Makefiles are designed to run with GNU Make. The Makefiles -use only the documented features of GNU Make, but they do use many -GNU extensions. - -GNU Make supports elementary list-processing functions. The kernel -Makefiles use a novel style of list building and manipulation with few -"if" statements. - -GNU Make has two assignment operators, ":=" and "=". ":=" performs -immediate evaluation of the right-hand side and stores an actual string -into the left-hand side. "=" is like a formula definition; it stores the -right-hand side in an unevaluated form and then evaluates this form each -time the left-hand side is used. - -There are some cases where "=" is appropriate. Usually, though, ":=" -is the right choice. - -All of the examples in this document were drawn from actual kernel -sources. The examples have been reformatted (white space changed, lines -split), but are otherwise exactly the same. - - - -=== 4 Variables passed down from the top - -The top Makefile exports the following variables: - - VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION - - These variables define the current kernel version. A few arch - Makefiles actually use these values directly; they should use - $(KERNELRELEASE) instead. - - $(VERSION), $(PATCHLEVEL), and $(SUBLEVEL) define the basic - three-part version number, such as "2", "4", and "0". These three - values are always numeric. - - $(EXTRAVERSION) defines an even tinier sublevel for pre-patches - or additional patches. It is usually some non-numeric string - such as "-pre4", and is often blank. - - KERNELRELEASE - - $(KERNELRELEASE) is a single string such as "2.4.0-pre4", suitable - for constructing installation directory names or showing in - version strings. Some arch Makefiles use it for this purpose. - - ARCH - - This variable defines the target architecture, such as "i386", - "arm", or "sparc". Many subdirectory Makefiles test $(ARCH) - to determine which files to compile. - - By default, the top Makefile sets $(ARCH) to be the same as the - host system system architecture. For a cross build, a user may - override the value of $(ARCH) on the command line: - - make ARCH=m68k ... - - TOPDIR, HPATH - - $(TOPDIR) is the path to the top of the kernel source tree. - Subdirectory Makefiles need this so that they can include - $(TOPDIR)/Rules.make. - - $(HPATH) is equal to $(TOPDIR)/include. A few arch Makefiles - need to use this to do special things using include files. - - SUBDIRS - - $(SUBDIRS) is a list of directories which the top Makefile - enters in order to build either vmlinux or modules. The actual - directories in $(SUBDIRS) depend on the kernel configuration. - The top Makefile defines this variable, and the arch Makefile - extends it. - - HEAD, CORE_FILES, NETWORKS, DRIVERS, LIBS - LINKFLAGS - - $(HEAD), $(CORE_FILES), $(NETWORKS), $(DRIVERS), and $(LIBS) - specify lists of object files and libraries to be linked into - vmlinux. - - The files in $(HEAD) are linked first in vmlinux. - - $(LINKFLAGS) specifies the flags to build vmlinux. - - The top Makefile and the arch Makefile jointly define these - variables. The top Makefile defines $(CORE_FILES), $(NETWORKS), - $(DRIVERS), and $(LIBS). The arch Makefile defines $(HEAD) - and $(LINKFLAGS), and extends $(CORE_FILES) and $(LIBS). - - Note: there are more variables here than necessary. $(NETWORKS), - $(DRIVERS), and even $(LIBS) could be subsumed into $(CORE_FILES). - - CPP, CC, AS, LD, AR, NM, STRIP, OBJCOPY, OBJDUMP - CPPFLAGS, CFLAGS, CFLAGS_KERNEL, MODFLAGS, AFLAGS, LDFLAGS - PERL - GENKSYMS - - These variables specify the commands and flags that Rules.make - uses to build goal files from source files. - - $(CFLAGS_KERNEL) contains extra C compiler flags used to compile - resident kernel code. - - $(MODFLAGS) contains extra C compiler flags used to compile code - for loadable kernel modules. In the future, this flag may be - renamed to the more regular name $(CFLAGS_MODULE). - - $(AFLAGS) contains assembler flags. - - $(GENKSYMS) contains the command used to generate kernel symbol - signatures when CONFIG_MODVERSIONS is enabled. The genksyms - command comes from the module-init-tools package. - - CROSS_COMPILE - - This variable is a prefix path for other variables such as $(CC), - $(AS), and $(LD). The arch Makefiles sometimes use and set this - variable explicitly. Subdirectory Makefiles don't need to worry - about it. - - The user may override $(CROSS_COMPILE) on the command line if - desired. - - HOSTCC, HOSTCFLAGS - - These variables define the C compiler and C compiler flags to - be used for compiling host side programs. These are separate - variables because the target architecture can be different from - the host architecture. - - If your Makefile compiles and runs a program that is executed - during the course of building the kernel, then it should use - $(HOSTCC) and $(HOSTCFLAGS). +Most Makefiles within the kernel are kbuild Makefiles that use the +kbuild infrastructure. This chapter introduce the syntax used in the +kbuild makefiles. - For example, the subdirectory drivers/pci has a helper program - named gen-devlist.c. This program reads a list of PCI ID's and - generates C code in the output files classlist.h and devlist.h. +Section 3.1 "Goal definitions" is a quick intro, further chapters provide +more details, with real examples. - Suppose that a user has an i386 computer and wants to build a - kernel for an ia64 machine. Then the user would use an ia64 - cross-compiler for most of the compilation, but would use a - native i386 host compiler to compile drivers/pci/gen-devlist.c. +--- 3.1 Goal definitions - For another example, kbuild helper programs such as - scripts/mkdep.c and scripts/lxdialog/*.c are compiled with - $(HOSTCC) rather than $(CC). + Goal definitions are the main part (heart) of the kbuild Makefile. + These lines define the files to be built, any special compilation + options, and any subdirectories to be entered recursively. - ROOT_DEV, SVGA_MODE, RAMDISK + The most simple kbuild makefile contains one line: - End users edit these variables to specify certain information - about the configuration of their kernel. These variables - are ancient! They are also specific to the i386 architecture. - They really should be replaced with CONFIG_* options. - - MAKEBOOT - - This variable is defined and used only inside the main arch - Makefiles. The top Makefile should not export it. - - INSTALL_PATH - - This variable defines a place for the arch Makefiles to install - the resident kernel image and System.map file. + Example: + obj-y += foo.o - INSTALL_MOD_PATH, MODLIB + This tell kbuild that there is one object in that directory named + foo.o. foo.o will be build from foo.c or foo.S. - $(INSTALL_MOD_PATH) specifies a prefix to $(MODLIB) for module - installation. This variable is not defined in the Makefile but - may be passed in by the user if desired. + If foo.o shall be built as a module, the variable obj-m is used. + Therefore the following pattern is often used: - $(MODLIB) specifies the directory for module installation. - The top Makefile defines $(MODLIB) to - $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may - override this value on the command line if desired. + Example: + obj-$(CONFIG_FOO) += foo.o - CONFIG_SHELL + $(CONFIG_FOO) evaluates to either y (for built-in) or m (for module). + If CONFIG_FOO is neither y nor m, then the file will not be compiled + nor linked. - This variable is private between Makefile and Rules.make. - Arch makefiles and subdirectory Makefiles should never use this. +--- 3.2 Built-in object goals - obj-y - MODVERFILE + The kbuild Makefile specifies object files for vmlinux + in the lists $(obj-y). These lists depend on the kernel + configuration. - An internal variable. This doesn't need to be exported, as it - is never used outside of the top Makefile. + Kbuild compiles all the $(obj-y) files. It then calls + "$(LD) -r" to merge these files into one built-in.o file. + built-in.o is later linked into vmlinux by the parent Makefile. - MAKE, MAKEFILES + The order of files in $(obj-y) is significant. Duplicates in + the lists are allowed: the first instance will be linked into + built-in.o and succeeding instances will be ignored. - Some variables internal to GNU Make. + Link order is significant, because certain functions + (module_init() / __initcall) will be called during boot in the + order they appear. So keep in mind that changing the link + order may e.g. change the order in which your SCSI + controllers are detected, and thus you disks are renumbered. - $(MAKEFILES) in particular is used to force the arch Makefiles - and subdirectory Makefiles to read $(TOPDIR)/.config without - including it explicitly. (This was an implementational hack - and could be fixed). + Example: + #drivers/isdn/i4l/Makefile + # Makefile for the kernel ISDN subsystem and device drivers. + # Each configuration option enables a list of files. + obj-$(CONFIG_ISDN) += isdn.o + obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o +--- 3.3 Loadable module goals - obj-m + $(obj-m) specify object files which are built as loadable + kernel modules. -=== 5 The structure of an arch Makefile + A module may be built from one source file or several source + files. In the case of one source file, the kbuild makefile + simply adds the file to $(obj-m). + Example: + #drivers/isdn/i4l/Makefile + obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o + Note: In this example $(CONFIG_ISDN_PPP_BSDCOMP) evaluates to 'm' ---- 5.1 Architecture-specific variables + If a kernel module is built from several source files, you specify + that you want to build a module in the same way as above. -The top Makefile includes one arch Makefile file, arch/$(ARCH)/Makefile. -This section describes the functions of the arch Makefile. + Kbuild needs to know which the parts that you want to build your + module from, so you have to tell it by setting an + $(-objs) variable. -An arch Makefile extends some of the top Makefile's variables with -architecture-specific values. + Example: + #drivers/isdn/i4l/Makefile + obj-$(CONFIG_ISDN) += isdn.o + isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o - SUBDIRS + In this example, the module name will be isdn.o. Kbuild will + compile the objects listed in $(isdn-objs) and then run + "$(LD) -r" on the list of these files to generate isdn.o. - The top Makefile defines $(SUBDIRS). The arch Makefile extends - $(SUBDIRS) with a list of architecture-specific directories. + Kbuild recognises objects used for composite objects by the suffix + -objs, and the suffix -y. This allows the Makefiles to use + the value of a CONFIG_ symbol to determine if an object is part + of a composite object. Example: + #fs/ext2/Makefile + obj-$(CONFIG_EXT2_FS) += ext2.o + ext2-y := balloc.o bitmap.o + ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o + + In this example xattr.o is only part of the composite object + ext2.o, if $(CONFIG_EXT2_FS_XATTR) evaluates to 'y'. - # arch/alpha/Makefile - - SUBDIRS := $(SUBDIRS) arch/alpha/kernel arch/alpha/mm \ - arch/alpha/lib arch/alpha/math-emu - - This list may depend on the configuration: + Note: Of course, when you are building objects into the kernel, + the syntax above will also work. So, if you have CONFIG_EXT2_FS=y, + kbuild will build an ext2.o file for you out of the individual + parts and then link this into built-in.o, as you would expect. - # arch/arm/Makefile +--- 3.4 Objects which export symbols - export-objs - ifeq ($(CONFIG_ARCH_ACORN),y) - SUBDIRS += drivers/acorn - ... - endif + When using loadable modules, not every global symbol in the + kernel / other modules is automatically available, only those + explicitly exported are available for your module. - CPP, CC, AS, LD, AR, NM, STRIP, OBJCOPY, OBJDUMP - CPPFLAGS, CFLAGS, CFLAGS_KERNEL, MODFLAGS, AFLAGS, LDFLAGS + To make a symbol available for use in modules, to "export" it, + use the EXPORT_SYMBOL() directive in your source. In + addition, you need to list all object files which export symbols + (i.e. their source contains an EXPORT_SYMBOL() directive) in the + Makefile variable $(export-objs). - The top Makefile defines these variables, and the arch Makefile - extends them. + Example: + #drivers/isdn/i4l/Makefile + # Objects that export symbols. + export-objs := isdn_common.o - Many arch Makefiles dynamically run the target C compiler to - probe supported options: + since isdn_common.c contains - # arch/i386/Makefile + EXPORT_SYMBOL(register_isdn); - # prevent gcc from keeping the stack 16 byte aligned - CFLAGS += $(shell if $(CC) -mpreferred-stack-boundary=2 \ - -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ - then echo "-mpreferred-stack-boundary=2"; fi) + which makes the function register_isdn available to + low-level ISDN drivers. + There exist a EXPORT_SYMBOL_GPL() variant with similar functionality, + but more restrictive with what may use that symbol. The requirement + to list the .o file in export-objs is the same. - And, of course, $(CFLAGS) can depend on the configuration: +--- 3.5 Library file goals - L_TARGET - # arch/i386/Makefile + Instead of building a built-in.o file, you may also + build an archive which again contains objects listed in $(obj-y). + This is normally not necessary and only used in lib/ and + arch/$(ARCH)/lib directories. + Only the name lib.a is allowed. - ifdef CONFIG_M386 - CFLAGS += -march=i386 - endif + Example: + #arch/i386/lib/Makefile + L_TARGET := lib.a + obj-y := checksum.o delay.o - ifdef CONFIG_M486 - CFLAGS += -march=i486 - endif + This will create a library lib.a based on checksum.o and delay.o. - ifdef CONFIG_M586 - CFLAGS += -march=i586 - endif +--- 3.6 Descending down in directories - Some arch Makefiles redefine the compilation commands in order - to add architecture-specific flags: + A Makefile is only responsible for building objects in its own + directory. Files in subdirectories should be taken care of by + Makefiles in these subdirs. The build system will automatically + invoke make recursively in subdirectories, provided you let it know of + them. - # arch/s390/Makefile + To do so obj-y and obj-m are used. + ext2 lives in a separate directory, and the Makefile present in fs/ + tells kbuild to descend down using the following assignment. - LD=$(CROSS_COMPILE)ld -m elf_s390 - OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S + Example: + #fs/Makefile + obj-$(CONfIG_EXT2_FS) += ext2/ + If CONFIG_EXT2_FS is set to either 'y' (built-in) or 'm' (modular) + the corresponding obj- variable will be set, and kbuild will descend + down in the ext2 directory. + Kbuild only uses this information to decide that it needs to visit + the directory, it is the Makefile in the subdirectory that + specifies what is modules and what is built-in. + It is good practice to use a CONFIG_ variable when assigning directory + names. This allows kbuild to totally skip the directory if the + corresponding CONFIG_ option is neither 'y' nor 'm'. ---- 5.2 Vmlinux build variables +--- 3.7 Compilation flags -An arch Makefile cooperates with the top Makefile to define variables -which specify how to build the vmlinux file. Note that there is no -corresponding arch-specific section for modules; the module-building -machinery is all architecture-independent. + EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS - HEAD, CORE_FILES, LIBS - LINKFLAGS + All the EXTRA_ variables apply only to the kbuild makefile + where they are assigned. The EXTRA_ variables apply to all + commands executed in the kbuild makefile. - The top Makefile defines the architecture-independent core of - thse variables, and the arch Makefile extends them. Note that the - arch Makefile defines (not just extends) $(HEAD) and $(LINKFLAGS). + $(EXTRA_CFLAGS) specifies options for compiling C files with + $(CC). Example: - - # arch/m68k/Makefile - - ifndef CONFIG_SUN3 - LINKFLAGS = -T $(TOPDIR)/arch/m68k/vmlinux.lds - else - LINKFLAGS = -T $(TOPDIR)/arch/m68k/vmlinux-sun3.lds -N - endif - - ... - - ifndef CONFIG_SUN3 - HEAD := arch/m68k/kernel/head.o - else - HEAD := arch/m68k/kernel/sun3-head.o + # drivers/sound/emu10k1/Makefile + EXTRA_CFLAGS += -I$(obj) + ifdef DEBUG + EXTRA_CFLAGS += -DEMU10K1_DEBUG endif - SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/lib - CORE_FILES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(CORE_FILES) - LIBS += arch/m68k/lib/lib.a + This variable is necessary because the top Makefile owns the + variable $(CFLAGS) and uses it for compilation flags for the + entire tree. + $(EXTRA_AFLAGS) is a similar string for per-directory options + when compiling assembly language source. ---- 5.3 Post-vmlinux goals + Example: + #arch/x86_64/kernel/Makefile + EXTRA_AFLAGS := -traditional -An arch Makefile specifies goals that take the vmlinux file, compress -it, wrap it in bootstrapping code, and copy the resulting files somewhere. -This includes various kinds of installation commands. -These post-vmlinux goals are not standardized across different -architectures. Here is a list of these goals and the architectures -that support each of them (as of kernel version 2.4.0-test6-pre5): + $(EXTRA_LDFLAGS) and $(EXTRA_ARFLAGS) are similar strings for + per-directory options to $(LD) and $(AR). - balo mips - bootimage alpha - bootpfile alpha, ia64 - bzImage i386, m68k - bzdisk i386 - bzlilo i386 - compressed i386, m68k, mips, mips64, sh - dasdfmt s390 - Image arm - image s390 - install arm, i386 - lilo m68k - msb alpha, ia64 - my-special-boot alpha, ia64 - orionboot mips - rawboot alpha - silo s390 - srmboot alpha - tftpboot.img sparc, sparc64 - vmlinux.64 mips64 - vmlinux.aout sparc64 - zImage arm, i386, m68k, mips, mips64, ppc, sh - zImage.initrd ppc - zdisk i386, mips, mips64, sh - zinstall arm - zlilo i386 - znetboot.initrd ppc + Example: + #arch/m68k/fpsp040/Makefile + EXTRA_LDFLAGS := -x + CFLAGS_$@, AFLAGS_$@ + CFLAGS_$@ and AFLAGS_$@ only apply to commands in current + kbuild makefile. ---- 5.4 Mandatory arch-specific goals + $(CFLAGS_$@) specifies per-file options for $(CC). The $@ + part has a literal value which specifies the file that it is for. -An arch Makefile must define the following arch-specific goals. -These goals provide arch-specific actions for the corresponding goals -in the top Makefile: + Example: + # drivers/scsi/Makefile + CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF + CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \ + -DGDTH_STATISTICS + CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM - archclean clean - archdep dep - archmrproper mrproper + These three lines specify compilation flags for aha152x.o, + gdth.o, and seagate.o + $(AFLAGS_$@) is a similar feature for source files in assembly + languages. + Example: + # arch/arm/kernel/Makefile + AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional + AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional -=== 6 The structure of a subdirectory Makefile +--- 3.9 Dependency tracking -A subdirectory Makefile has four sections. + Kbuild track dependencies on the following: + 1) All prerequisite files (both *.c and *.h) + 2) CONFIG_ options used in all prerequisite files + 3) Command-line used to compile target + Thus, if you change an option to $(CC) all affected files will + be re-compiled. +--- 3.10 Special Rules ---- 6.1 Comments + Special rules are used when the kbuild infrastructure does + not provide the required support. A typical example is + header files generated during the build process. + Another example is the architecture specific Makefiles which + needs special rules to prepare boot images etc. -The first section is a comment header. Historically, many anonymous -people have edited kernel Makefiles without leaving any change -histories in the header; comments from them would have been valuable. + Special rules are written as normal Make rules. + Kbuild is not executing in the directory where the Makefile is + located, so all special rules shall provide a relative + path to prerequisite files and target files. + Two variables are used when defining special rules: + $(src) + $(src) is a relative path which points to the directory + where the Makefile is located. Always use $(src) when + referring to files located in the src tree. ---- 6.2 Goal definitions + $(obj) + $(obj) is a relative path which points to the directory + where the target is saved. Always use $(obj) when + referring to generated files. -The second section is a bunch of definitions that are the heart of the -subdirectory Makefile. These lines define the files to be built, any -special compilation options, and any subdirectories to be recursively -entered. The declarations in these lines depend heavily on the kernel -configuration variables (CONFIG_* symbols). + Example: + #drivers/scsi/Makefile + $(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl + $(CPP) -DCHIP=810 - < $< | ... $(src)/script_asm.pl -The second section looks like this: + This is a special rule, following the normal syntax + required by make. + The target file depends on two prerequisite files. References + to the target file are prefixed with $(obj), references + to prerequisites are referenced with $(src) (because they are not + generated files). - # drivers/block/Makefile - obj-$(CONFIG_MAC_FLOPPY) += swim3.o - obj-$(CONFIG_BLK_DEV_FD) += floppy.o - obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o - obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o +=== 4 Host Program support ---- 6.4 Rules.make section +Kbuild supports building executables on the host for use during the +compilation stage. +Two steps are required in order to use a host executable. -The third section is the single line: +The first step is to tell kbuild that a host program exists. This is +done utilising the variable host-prog. - include $(TOPDIR)/Rules.make +The second step is to add an explicit dependency to the executable. +This can be done in two ways. Either add the dependency in a rule, +or utilise the variable build-targets. +Both possibilities are described in the following. +--- 4.1 Simple Host Program + In some cases there is a need to compile and run a program on the + computer where the build is running. + The following line tells kbuild that the program bin2hex shall be + built on the build host. ---- 6.5 Special rules + Example: + host-progs := bin2hex -The fourth section contains any special Makefile rules needed that are -not available through the common rules in Rules.make. + Kbuild assumes in the above example that bin2hex is made from a single + c-source file named bin2hex.c located in the same directory as + the Makefile. + +--- 4.2 Composite Host Programs + Host programs can be made up based on composite objects. + The syntax used to define composite objetcs for host programs is + similar to the syntax used for kernel objects. + $(-objs) list all objects used to link the final + executable. + Example: + #scripts/lxdialog/Makefile + host-progs := lxdialog + lxdialog-objs := checklist.o lxdialog.o -=== 7 Rules.make variables + Objects with extension .o are compiled from the corresponding .c + files. In the above example checklist.c is compiled to checklist.o + and lxdialog.c is compiled to lxdialog.o. + Finally the two .o files are linked to the executable, lxdialog. + Note: The syntax -y is not permitted for host-programs. -The public interface of Rules.make consists of the following variables: +--- 4.3 Defining shared libraries + + Objects with extension .so are considered shared libraries, and + will be compiled as position independent objects. + Kbuild provides support for shared libraries, but the usage + shall be restricted. + In the following example the libkconfig.so shared library is used + to link the executable conf. + Example: + #scripts/kconfig/Makefile + host-progs := conf + conf-objs := conf.o libkconfig.so + libkconfig-objs := expr.o type.o + + Shared libraries always require a corresponding -objs line, and + in the example above the shared library libkconfig is composed by + the two objects expr.o and type.o. + expr.o and type.o will be built as position independent code and + linked as a shared library libkconfig.so. C++ is not supported for + shared libraries. +--- 4.4 Using C++ for host programs ---- 7.1 Subdirectories + kbuild offers support for host programs written in C++. This was + introduced solely to support kconfig, and is not recommended + for general use. -A Makefile is only responsible for building objects in its own -directory. Files in subdirectories should be taken care of by -Makefiles in the these subdirs. The build system will automatically -invoke make recursively in subdirectories, provided you let it know of -them. + Example: + #scripts/kconfig/Makefile + host-progs := qconf + qconf-cxxobjs := qconf.o -To do so, use the subdir-{y,m,n,} variables: + In the example above the executable is composed of the C++ file + qconf.cc - identified by $(qconf-cxxobjs). + + If qconf is composed by a mixture of .c and .cc files, then an + additional line can be used to identify this. - subdir-$(CONFIG_ISDN) += i4l - subdir-$(CONFIG_ISDN_CAPI) += capi + Example: + #scripts/kconfig/Makefile + host-progs := qconf + qconf-cxxobjs := qconf.o + qconf-objs := check.o + +--- 4.5 Controlling compiler options for host programs -When building the actual kernel, i.e. vmlinux ("make -{vmlinux,bzImage,...}"), make will recursively descend into -directories listed in $(subdir-y). + When compiling host programs, it is possible to set specific flags. + The programs will always be compiled utilising $(HOSTCC) passed + the options specified in $(HOSTCFLAGS). + To set flags that will take effect for all host programs created + in that Makefile use the variable HOST_EXTRACFLAGS. -When building modules ("make modules"), make will recursively descend -into directories listed in $(subdir-m). + Example: + #scripts/lxdialog/Makefile + HOST_EXTRACFLAGS += -I/usr/include/ncurses + + To set specific flags for a single file the following construction + is used: -When building the dependencies ("make dep") make needs to visit every -subdir, so it'll descend into every directory listed in -$(subdir-y), $(subdir-m), $(subdir-n), $(subdir-). + Example: + #arch/ppc64/boot/Makefile + HOSTCFLAGS_piggyback.o := -DKERNELBASE=$(KERNELBASE) + + It is also possible to specify additional options to the linker. + + Example: + #scripts/kconfig/Makefile + HOSTLOADLIBES_qconf := -L$(QTDIR)/lib -You may encounter the case where a config option may be set to "y", but -you still want to possibly build modules in that subdirectory. + When linking qconf it will be passed the extra option "-L$(QTDIR)/lib". + +--- 4.6 When host programs are actually built -For example, drivers/isdn/capi/Makefile has + Kbuild will only build host-programs when they are referenced + as a prerequisite. + This is possible in two ways: - obj-$(CONFIG_ISDN_CAPI) += kernelcapi.o capiutil.o - obj-$(CONFIG_ISDN_CAPI_CAPI20) += capi.o + (1) List the prerequisite explicitly in a special rule. -where it's possible that CONFIG_ISDN_CAPI=y, but -CONFIG_ISDN_CAPI_CAPI20=m. + Example: + #drivers/pci/Makefile + host-progs := gen-devlist + $(obj)/devlist.h: $(src)/pci.ids $(obj)/gen-devlist + ( cd $(obj); ./gen-devlist ) < $< -This is expressed by the following construct in the parent Makefile -drivers/isdn/Makefile: + The target $(obj)/devlist.h will not be built before + $(obj)/gen-devlist is updated. Note that references to + the host programs in special rules must be prefixed with $(obj). - mod-subdirs := i4l hisax capi eicon - subdir-$(CONFIG_ISDN_CAPI) += capi + (2) Use $(build-targets) + When there is no suitable special rule, and the host program + shall be built when a makefile is entered, the $(build-targets) + variable shall be used. -Having a subdir ("capi") listed in the variable $(mod-subdirs) will -make the build system enter the specified subdirectory during "make -modules" also, even though the subdir ("capi") is listed only in -$(subdir-y), not $(subdir-m). + Example: + #scripts/lxdialog/Makefile + host-progs := lxdialog + build-targets := $(host-progs) + This will tell kbuild to build lxdialog even if not referenced in + any rule. ---- 7.2 Object file goals +=== 5 Kbuild clean infrastructure - O_TARGET, obj-y +"make clean" deletes most generated files in the src tree where the kernel +is compiled. This includes generated files such as host programs. +Kbuild knows targets listed in $(host-progs) and $(EXTRA_TARGETS) and +they are all deleted during "make clean". +Files matching the patterns "*.[oas]", "*.ko", plus some additional files +generated by kbuild are deleted all over the kernel src tree when +"make clean" is executed. - The subdirectory Makefile specifies object files for vmlinux - in the lists $(obj-y). These lists depend on the kernel - configuration. +Additional files can be specified by means of $(clean-files). - Rules.make compiles all the $(obj-y) files. It then calls - "$(LD) -r" to merge these files into one .o file with the name - $(O_TARGET). This $(O_TARGET) is later linked into vmlinux by - a parent Makefile. + Example: + #drivers/pci/Makefile + clean-files := devlist.h classlist.h - The order of files in $(obj-y) is significant. Duplicates in - the lists are allowed: the first instance will be linked into - $(O_TARGET) and succeeding instances will be ignored. +When executing "make clean", the two files "devlist.h classlist.h" will +be deleted. Kbuild knows that files specified by $(clean-files) are +located in the same directory as the makefile. - Link order is significant, because certain functions - (module_init() / __initcall) will be called during boot in the - order they appear. So keep in mind that changing the link - order may e.g. change the order in which your SCSI - controllers are detected, and thus you disks are renumbered. +Usually kbuild descends down in subdirectories due to "obj-* := dir/", +but in the architecture makefiles where the kbuild infrastructure +is not sufficent this sometimes needs to be explicit. Example: + #arch/i386/boot/Makefile + subdir- := compressed/ - # Makefile for the kernel ISDN subsystem and device drivers. - - # The target object and module list name. - - O_TARGET := vmlinux-obj.o +The above assignment instructs kbuild to descend down in the +directory compressed/ when "make clean" is executed. - # Each configuration option enables a list of files. +To support the clean infrastructure in the Makefiles that builds the +final bootimage there is an optional target named archclean: - obj-$(CONFIG_ISDN) += isdn.o - obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o + Example: + #arch/i386/Makefile + archclean: + $(Q)$(MAKE) $(clean)=arch/i386/boot - # The global Rules.make. +When "make clean" is executed, make will descend down in arch/i386/boot, +and clean as usual. The Makefile located in arch/i386/boot/ may use +the subdir- trick to descend further down. - include $(TOPDIR)/Rules.make +Note 1: arch/$(ARCH)/Makefile cannot use "subdir-", because that file is +included in the top level makefile, and the kbuild infrastructure +is not operational at that point. ---- 7.3 Library file goals +Note 2: All directories listed in core-y, libs-y, drivers-y and net-y will +be visited during "make clean". - L_TARGET +=== 6 Architecture Makefiles - Instead of building an O_TARGET object file, you may also - build an archive which again contains objects listed in - $(obj-y). This is normally not necessary and only used in - the lib, arch/$(ARCH)/lib directories. +The top level Makefile sets up the environment and does the preparation, +before starting to descend down in the individual directories. +The top level makefile contains the generic part, whereas the +arch/$(ARCH)/Makefile contains what is required to set-up kbuild +to the said architecture. +To do so arch/$(ARCH)/Makefile sets a number of variables, and defines +a few targets. +When kbuild executes the following steps are followed (roughly): +1) Configuration of the kernel => produced .config +2) Store kernel version in include/linux/version.h +3) Symlink include/asm to include/asm-$(ARCH) +4) Updating all other prerequisites to the target prepare: + - Additional prerequisites are specified in arch/$(ARCH)/Makefile +5) Recursively descend down in all directories listed in + init-* core* drivers-* net-* libs-* and build all targets. + - The value of the above variables are extended in arch/$(ARCH)/Makefile. +6) All object files are then linked and the resulting file vmlinux is + located at the root of the src tree. + The very first objects linked are listed in head-y, assigned by + arch/$(ARCH)/Makefile. +7) Finally the architecture specific part does any required post processing + and builds the final bootimage. + - This includes building boot records + - Preparing initrd images and the like ---- 7.4 Loadable module goals - obj-m +--- 6.1 Set variables to tweak the build to the architecture - $(obj-m) specify object files which are built as loadable - kernel modules. + LDFLAGS Generic $(LD) options - A module may be built from one source file or several source - files. In the case of one source file, the subdirectory - Makefile simply adds the file to $(obj-m) + Flags used for all invocations of the linker. + Often specifying the emulation is sufficient. Example: + #arch/s390/Makefile + LDFLAGS := -m elf_s390 + Note: EXTRA_LDFLAGS and LDFLAGS_$@ can be used to further customise + the flags used. See chapter 7. + + LDFLAGS_MODULE Options for $(LD) when linking modules - obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o + LDFLAGS_MODULE is used to set specific flags for $(LD) when + linking the .ko files used for modules. + Default is "-r", for relocatable output. - If a kernel module is built from several source files, you specify - that you want to build a module in the same way as above. + LDFLAGS_vmlinux Options for $(LD) when linking vmlinux - However, the build system of course needs to know which the parts - are that you want to build your module of, so you have to tell it - by setting an $(-objs) variable. + LDFLAGS_vmlinux is used to specify additional flags to pass to + the linker when linking the final vmlinux. + LDFLAGS_vmlinux uses the LDFLAGS_$@ support. Example: + #arch/i386/Makefile + LDFLAGS_vmlinux := -e stext - obj-$(CONFIG_ISDN) += isdn.o - - isdn-objs := isdn_net.o isdn_tty.o isdn_v110.o isdn_common.o - - In this example, the module name will be isdn.o. Rules.make - will compile the objects listed in $(isdn-objs) and then run - "$(LD) -r" on the list of these files to generate isdn.o - - Note: Of course, when you are building objects into the kernel, - the syntax above will also work. So, if you have CONFIG_ISDN=y, - the build system will build an isdn.o for you out of the individual - parts and then link this into the $(O_TARGET), as you'd expect. - + LDFLAGS_BLOB Options for $(LD) when linking the initramfs blob ---- 7.5 Objects which export symbols - - export-objs + The image used for initramfs is made during the build process. + LDFLAGS_BLOB is used to specify additional flags to be used when + creating the initramfs_data.o file. + Example: + #arch/i386/Makefile + LDFLAGS_BLOB := --format binary --oformat elf32-i386 - When using loadable modules, not every global symbol in the - kernel / other modules is automatically available, only those - explicitly exported are available for your module. + OBJCOPYFLAGS objcopy flags - To make a symbol available for use in modules, to "export" it, - use the EXPORT_SYMBOL() directive in your source. In - addition, you need to list all object files which export symbols - (i.e. their source contains an EXPORT_SYMBOL() directive) in the - Makefile variable $(export-objs). + When $(call if_changed,objcopy) is used to translate a .o file, + then the flags specified in OBJCOPYFLAGS will be used. + $(call if_changed,objcopy) is often used to generate raw binaries on + vmlinux. Example: + #arch/s390/Makefile + OBJCOPYFLAGS := -O binary - # Objects that export symbols. + #arch/s390/boot/Makefile + $(obj)/image: vmlinux FORCE + $(call if_changed,objcopy) - export-objs := isdn_common.o + In this example the binary $(obj)/image is a binary version of + vmlinux. The usage of $(call if_changed,xxx) will be described later. - since isdn_common.c contains + AFLAGS $(AS) assembler flags - EXPORT_SYMBOL(register_isdn); + Default value - see top level Makefile + Append or modify as required per architecture. - which makes the function register_isdn available to - low-level ISDN drivers. - + Example: + #arch/sparc64/Makefile + AFLAGS += -m64 -mcpu=ultrasparc ---- 7.6 Compilation flags + CFLAGS $(CC) compiler flags - EXTRA_CFLAGS, EXTRA_AFLAGS, EXTRA_LDFLAGS, EXTRA_ARFLAGS + Default value - see top level Makefile + Append or modify as required per architecture. - $(EXTRA_CFLAGS) specifies options for compiling C files with - $(CC). The options in this variable apply to all $(CC) commands - for files in the current directory. + Often the CFLAGS variable depends on the configuration. Example: + #arch/i386/Makefile + cflags-$(CONFIG_M386) += -march=i386 + CFLAGS += $(cflags-y) - # drivers/sound/emu10k1/Makefile - EXTRA_CFLAGS += -I. - ifdef DEBUG - EXTRA_CFLAGS += -DEMU10K1_DEBUG - endif + Many arch Makefiles dynamically run the target C compiler to + probe supported options: - $(EXTRA_CFLAGS) does not apply to subdirectories of the current - directory. Also, it does not apply to files compiled with - $(HOSTCC). + #arch/i386/Makefile + check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc \ + /dev/null\ > /dev/null 2>&1; then echo "$(1)"; \ + else echo "$(2)"; fi) + cflags-$(CONFIG_MCYRIXIII) += $(call check_gcc,\ + -march=c3,-march=i486) - This variable is necessary because the top Makefile owns the - variable $(CFLAGS) and uses it for compilation flags for the - entire tree. + CFLAGS += $(cflags-y) - $(EXTRA_AFLAGS) is a similar string for per-directory options - when compiling assembly language source. + The above examples both utilise the trick that a config option expands + to 'y' when selected. - Example: at the time of writing, there were no examples of - $(EXTRA_AFLAGS) in the kernel corpus. + CFLAGS_KERNEL $(CC) options specific for built-in - $(EXTRA_LDFLAGS) and $(EXTRA_ARFLAGS) are similar strings for - per-directory options to $(LD) and $(AR). + $(CFLAGS_KERNEL) contains extra C compiler flags used to compile + resident kernel code. - Example: at the time of writing, there were no examples of - $(EXTRA_LDFLAGS) or $(EXTRA_ARFLAGS) in the kernel corpus. + CFLAGS_MODULE $(CC) options specific for modules - CFLAGS_$@, AFLAGS_$@ + $(CFLAGS_MODULE) contains extra C compiler flags used to compile code + for loadable kernel modules. - $(CFLAGS_$@) specifies per-file options for $(CC). The $@ - part has a literal value which specifies the file that it's for. + +--- 6.2 Add prerequisites to prepare: - Example: + The prepare: rule is used to list prerequisites that needs to be + built before starting to descend down in the subdirectories. + This is usual header files containing assembler constants. - # drivers/scsi/Makefile - CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF - CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \ - -DGDTH_STATISTICS - CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM + Example: + #arch/s390/Makefile + prepare: include/asm-$(ARCH)/offsets.h - These three lines specify compilation flags for aha152x.o, - gdth.o, and seagate.o + In this example the file include/asm-$(ARCH)/offsets.h will + be built before descending down in the subdirectories. + See also chapter XXX-TODO that describe how kbuild supports + generating offset header files. - $(AFLAGS_$@) is a similar feature for source files in assembly - languages. - Example: +--- 6.3 List directories to visit when descending - # arch/arm/kernel/Makefile - AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional - AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional + An arch Makefile cooperates with the top Makefile to define variables + which specify how to build the vmlinux file. Note that there is no + corresponding arch-specific section for modules; the module-building + machinery is all architecture-independent. - Rules.make has a feature where an object file depends on the - value of $(CFLAGS_$@) that was used to compile it. (It also - depends on the values of $(CFLAGS) and $(EXTRA_CFLAGS)). Thus, - if you change the value of $(CFLAGS_$@) for a file, either by - editing the Makefile or overriding the value some other way, - Rules.make will do the right thing and re-compile your source - file with the new options. + + head-y, init-y, core-y, libs-y, drivers-y, net-y - Note: because of a deficiency in Rules.make, assembly language - files do not have flag dependencies. If you edit $(AFLAGS_$@) - for such a file, you will have to remove the object file in order - to re-build from source. + $(head-y) list objects to be linked first in vmlinux. + $(libs-y) list directories where a libs.a archive can be located. + The rest list directories where a built-in.o object file can be located. - LD_RFLAG + $(init-y) objects will be located after $(head-y). + Then the rest follows in this order: + $(core-y), $(libs-y), $(drivers-y) and $(net-y). - This variable is used, but never defined. It appears to be a - vestige of some abandoned experiment. + The top level Makefile define values for all generic directories, + and arch/$(ARCH)/Makefile only adds architecture specific directories. + Example: + #arch/sparc64/Makefile + core-y += arch/sparc64/kernel/ + libs-y += arch/sparc64/prom/ arch/sparc64/lib/ + drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/ ---- 7.7 Miscellaneous variables +--- 6.4 Architecture specific boot images - IGNORE_FLAGS_OBJS + An arch Makefile specifies goals that take the vmlinux file, compress + it, wrap it in bootstrapping code, and copy the resulting files + somewhere. This includes various kinds of installation commands. + The actual goals are not standardized across architectures. - $(IGNORE_FLAGS_OBJS) is a list of object files which will not have - their flag dependencies automatically tracked. This is a hackish - feature, used to kludge around a problem in the implementation - of flag dependencies. (The problem is that flag dependencies - assume that a %.o file is built from a matching %.S or %.c file. - This is sometimes not true). + It is common to locate any additional processing in a boot/ + directory below arch/$(ARCH)/. - USE_STANDARD_AS_RULE + Kbuild does not provide any smart way to support building a + target specified in boot/. Therefore arch/$(ARCH)/Makefile shall + call make manually to build a target in boot/. - This is a transition variable. If $(USE_STANDARD_AS_RULE) - is defined, then Rules.make will provide standard rules for - assembling %.S files into %.o files or %.s files (%.s files - are useful only to developers). + The recommended approach is to include shortcuts in + arch/$(ARCH)/Makefile, and use the full path when calling down + into the arch/$(ARCH)/boot/Makefile. - If $(USE_STANDARD_AS_RULE) is not defined, then Rules.make - will not provide these standard rules. In this case, the - subdirectory Makefile must provide its own private rules for - assembling %.S files. + Example: + #arch/i386/Makefile + boot := arch/i386/boot + bzImage: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ - In the past, all Makefiles provided private %.S rules. Newer - Makefiles should define USE_STANDARD_AS_RULE and use the standard - Rules.make rules. As soon as all the Makefiles across all - architectures have been converted to USE_STANDARD_AS_RULE, then - Rules.make can drop the conditional test on USE_STANDARD_AS_RULE. - After that, all the other Makefiles can drop the definition of - USE_STANDARD_AS_RULE. + "$(Q)$(MAKE) $(build)=" is the recommended way to invoke + make in a subdirectory. + There are no rules for naming of the architecture specific targets, + but executing "make help" will list all relevant targets. + To support this $(archhelp) must be defined. + Example: + #arch/i386/Makefile + define archhelp + echo '* bzImage - Image (arch/$(ARCH)/boot/bzImage)' + endef -=== 8 New-style variables + When make is executed without arguments, the first goal encountered + will be built. In the top level Makefile the first goal present + is all:. + An architecture shall always per default build a bootable image. + In "make help" the default goal is highlighted with a '*'. + Add a new prerequisite to all: to select a default goal different + from vmlinux. -[ This sections dates back from a time where the way to write Makefiles - described above was "new-style". I'm leaving it in as it describes the - same thing in other words, so it may be of some use ] + Example: + #arch/i386/Makefile + all: bzImage -The "new-style variables" are simpler and more powerful than the -"old-style variables". As a result, many subdirectory Makefiles shrank -more than 60%. This author hopes that, in time, all arch Makefiles and -subdirectory Makefiles will convert to the new style. + When "make" is executed without arguments, bzImage will be built. -Rules.make does not understand new-style variables. Thus, each new-style -Makefile has a section of boilerplate code that converts the new-style -variables into old-style variables. There is also some mixing, where -people define most variables using "new style" but then fall back to -"old style" for a few lines. +--- 6.5 Building non-kbuild targets ---- 8.1 New variables + EXTRA_TARGETS - obj-y obj-m obj-n obj- + EXTRA_TARGETS specify additional targets created in current + directory, in addition to any targets specified by obj-*. - These variables replace $(O_OBJS), $(OX_OBJS), $(M_OBJS), - and $(MX_OBJS). + Listing all targets in EXTRA_TARGETS is required for three purposes: + 1) Avoid that the target is linked in as part of built-in.o + 2) Enable kbuild to check changes in command lines + - When $(call if_changed,xxx) is used + 3) kbuild knows what file to delete during "make clean" Example: + #arch/i386/kernel/Makefile + EXTRA_TARGETS := head.o init_task.o - # drivers/block/Makefile - obj-$(CONFIG_MAC_FLOPPY) += swim3.o - obj-$(CONFIG_BLK_DEV_FD) += floppy.o - obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o - obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o + In this example EXTRA_TARGETS is used to list object files that + shall be built, but shall not be linked as part of built-in.o. - Notice the use of $(CONFIG_...) substitutions on the left hand - side of an assignment operator. This gives GNU Make the power - of associative indexing! Each of these assignments replaces - eight lines of code in an old-style Makefile. - - After executing all of the assignments, the subdirectory - Makefile has built up four lists: $(obj-y), $(obj-m), $(obj-n), - and $(obj-). + Example: + #arch/i386/boot/Makefile + EXTRA_TARGETS := vmlinux.bin bootsect bootsect.o - $(obj-y) is a list of files to include in vmlinux. - $(obj-m) is a list of files to build as single-file modules. - $(obj-n) and $(obj-) are ignored. + In this example EXTRA_TARGETS is used to list all intermediate + targets, and all final targets. + The targets are added to EXTRA_TARGETS to enable 2) and 3) above. + +--- 6.6 Commands useful for building a boot image - Each list may contain duplicates items; duplicates are - automatically removed later. Duplicates in both $(obj-y) and - $(obj-m) will automatically be removed from the $(obj-m) list. + Kbuild provide a few macros that are useful when building a + boot image. - Example: + if_changed - # drivers/net/Makefile + if_changed is the infrastructure used for the following commands. - ... - obj-$(CONFIG_OAKNET) += oaknet.o 8390.o - ... - obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o - ... - obj-$(CONFIG_STNIC) += stnic.o 8390.o - ... - obj-$(CONFIG_MAC8390) += daynaport.o 8390.o - ... + Usage: + target: source(s) FORCE + $(call if_changed,ld/objcopy/gzip) + + When the rule is evaluated it is checked to see if any files + needs an update, or the commandline has changed since last + invocation. The latter will force a rebuild if any options + to the executable have changed. + Any target that utilises if_changed must be listed in EXTRA_TARGETS, + otherwise the command line check will fail, and the target will + always be built. + if_changed may be used in conjunction with custom commands as + defined in 6.7 "Custom kbuild commands". + Note: It is a typical mistake to forget the FORCE prerequisite. - In this example, four different drivers require the code in - 8390.o. If one or more of these four drivers are built into - vmlinux, then 8390.o will also be built into vmlinux, and will - *not* be built as a module -- even if another driver which needs - 8390.o is built as a module. (The modular driver is able to - use services of the 8390.o code in the resident vmlinux image). + ld + Link target. Often LDFLAGS_$@ is used to set specific options to ld. + + objcopy + Copy binary. Uses OBJCOPYFLAGS usually specified in + arch/$(ARCH)/Makefile. - export-objs + gzip + Compress target. Use maximum compression to compress target. - $(export-objs) is a list of all the files in the subdirectory - which potentially export symbols. The canonical way to construct - this list is: - grep -l EXPORT_SYMBOL *.c +--- 6.7 Custom kbuild commands - (but watch out for sneaky files that call EXPORT_SYMBOL from an - included header file!) + When kbuild is executing with KBUILD_VERBOSE=0 then only a shorthand + of a command is normally displayed. + To enable this behaviour for custom commands kbuild requires + two variables to be set: + quiet_cmd_ - what shall be echoed + cmd_ - the command to execute - This is a potential list, independent of the kernel configuration. - All files that export symbols go into $(export-objs). The - boilerplate code then uses the $(export-objs) list to separate - the real file lists into $(*_OBJS) and $(*X_OBJS). + Example: + # + quiet_cmd_image = BUILD $@ + cmd_image = $(obj)/tools/build $(BUILDFLAGS) \ + $(obj)/vmlinux.bin > $@ - Experience has shown that maintaining the proper X's in an - old-style Makefile is difficult and error-prone. Maintaining the - $(export-objs) list in a new-style Makefile is simpler and easier - to audit. + $(obj)/bzImage: $(obj)/vmlinux.bin $(obj)/tools/build FORCE + $(call if_changed,image) + @echo 'Kernel: $@ is ready' - $(foo)-objs + When updating the $(obj)/bzImage target the line: - Some kernel modules are composed of multiple object files linked - together. + BUILD arch/i386/boot/bzImage - For each multi-part kernel modul there is a list of all the - object files which make up that module. For a kernel module - named foo.o, its object file list is foo-objs. + will be displayed with "make KBUILD_VERBOSE=0". + - Example: +=== 7 Kbuild Variables - # drivers/scsi/Makefile - list-multi := scsi_mod.o sr_mod.o initio.o a100u2w.o +The top Makefile exports the following variables: - ... + VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION - scsi_mod-objs := hosts.o scsi.o scsi_ioctl.o constants.o \ - scsicam.o scsi_proc.o scsi_error.o \ - scsi_obsolete.o scsi_queue.o scsi_lib.o \ - scsi_merge.o scsi_dma.o scsi_scan.o \ - scsi_syms.o - sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o - initio-objs := ini9100u.o i91uscsi.o - a100u2w-objs := inia100.o i60uscsi.o + These variables define the current kernel version. A few arch + Makefiles actually use these values directly; they should use + $(KERNELRELEASE) instead. - The subdirectory Makefile puts the modules onto obj-* lists in - the usual configuration-dependent way: + $(VERSION), $(PATCHLEVEL), and $(SUBLEVEL) define the basic + three-part version number, such as "2", "4", and "0". These three + values are always numeric. - obj-$(CONFIG_SCSI) += scsi_mod.o - obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o - obj-$(CONFIG_SCSI_INITIO) += initio.o - obj-$(CONFIG_SCSI_INIA100) += a100u2w.o + $(EXTRAVERSION) defines an even tinier sublevel for pre-patches + or additional patches. It is usually some non-numeric string + such as "-pre4", and is often blank. - Suppose that CONFIG_SCSI=y. Then vmlinux needs to link in all - 14 components of scsi_mod.o. + KERNELRELEASE - Suppose that CONFIG_BLK_DEV_SR=m. Then the 3 components - of sr_mod.o will be linked together with "$(LD) -r" to make the - kernel module sr_mod.o. + $(KERNELRELEASE) is a single string such as "2.4.0-pre4", suitable + for constructing installation directory names or showing in + version strings. Some arch Makefiles use it for this purpose. - Also suppose CONFIG_SCSI_INITIO=n. Then initio.o goes onto - the $(obj-n) list and that's the end of it. Its component - files are not compiled, and the composite file is not created. + ARCH + This variable defines the target architecture, such as "i386", + "arm", or "sparc". Some kbuild Makefiles test $(ARCH) to + determine which files to compile. - subdir-y subdir-m subdir-n subdir- + By default, the top Makefile sets $(ARCH) to be the same as the + host system architecture. For a cross build, a user may + override the value of $(ARCH) on the command line: - These variables replace $(ALL_SUB_DIRS), $(SUB_DIRS) and - $(MOD_SUB_DIRS). + make ARCH=m68k ... - Example: - # drivers/Makefile - subdir-$(CONFIG_PCI) += pci - subdir-$(CONFIG_PCMCIA) += pcmcia - subdir-$(CONFIG_MTD) += mtd - subdir-$(CONFIG_SBUS) += sbus + INSTALL_PATH - These variables work similar to obj-*, but are used for - subdirectories instead of object files. + This variable defines a place for the arch Makefiles to install + the resident kernel image and System.map file. + Use this for architecture specific install targets. - After executing all assignments, the subdirectory Makefile has - built up four lists: $(subdir-y), $(subdir-m), $(subdir-n), - and $(subdir-). + INSTALL_MOD_PATH, MODLIB - $(subdir-y) is a list of directories that should be entered - for making vmlinux. - $(subdir-m) is a list of directories that should be entered - for making modules. - $(subdir-n) and $(subdir-) are only used for collecting a list - of all subdirectories of this directory. + $(INSTALL_MOD_PATH) specifies a prefix to $(MODLIB) for module + installation. This variable is not defined in the Makefile but + may be passed in by the user if desired. - Each list besides subdir-y may contain duplicates items; duplicates - are automatically removed later. + $(MODLIB) specifies the directory for module installation. + The top Makefile defines $(MODLIB) to + $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may + override this value on the command line if desired. - mod-subdirs +=== 8 Makefile language - $(mod-subdirs) is a list of all the subdirectories that should - be added to $(subdir-m), too if they appear in $(subdir-y) +The kernel Makefiles are designed to run with GNU Make. The Makefiles +use only the documented features of GNU Make, but they do use many +GNU extensions. - Example: +GNU Make supports elementary list-processing functions. The kernel +Makefiles use a novel style of list building and manipulation with few +"if" statements. - # fs/Makefile - mod-subdirs := nls +GNU Make has two assignment operators, ":=" and "=". ":=" performs +immediate evaluation of the right-hand side and stores an actual string +into the left-hand side. "=" is like a formula definition; it stores the +right-hand side in an unevaluated form and then evaluates this form each +time the left-hand side is used. - This means nls should be added to (subdir-y) and $(subdir-m) if - CONFIG_NFS = y. +There are some cases where "=" is appropriate. Usually, though, ":=" +is the right choice. === 9 Credits -Thanks to the members of the linux-kbuild mailing list for reviewing -drafts of this document, with particular thanks to Peter Samuelson -and Thomas Molina. +Original version made by Michael Elizabeth Chastain, +Updates by Kai Germaschewski +Updates by Sam Ravnborg + +=== 10 TODO + +- Describe how kbuild support shipped files with _shipped. +- Generating offset header files. +- Add more variables to section 7? + diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt Sun Feb 9 21:13:37 2003 +++ b/Documentation/kernel-parameters.txt Sun Feb 9 21:13:37 2003 @@ -1,4 +1,4 @@ -November 2002 Kernel Parameters v2.5.49 +February 2003 Kernel Parameters v2.5.59 ~~~~~~~~~~~~~~~~~ The following is a consolidated list of the kernel parameters as implemented @@ -60,6 +60,7 @@ V4L Video For Linux support is enabled. VGA The VGA console has been enabled. VT Virtual terminal support is enabled. + WDT Watchdog support is enabled. XT IBM PC/XT MFM hard disk support is enabled. In addition, the following text indicates that the option: @@ -98,6 +99,9 @@ advansys= [HW,SCSI] See header of drivers/scsi/advansys.c. + advwdt= [HW,WDT] Advantech WDT + Format: , + aedsp16= [HW,OSS] Audio Excel DSP 16 Format: ,,,,, See also header of sound/oss/aedsp16.c. @@ -111,6 +115,9 @@ aic7xxx= [HW,SCSI] See Documentation/scsi/aic7xxx.txt. + aic79xx= [HW,SCSI] + See Documentation/scsi/aic79xx.txt. + allowdma0 [ISAPNP] AM53C974= [HW,SCSI] @@ -230,20 +237,12 @@ cs89x0_media= [HW,NET] Format: { rj45 | aui | bnc } - - ctc= [HW,NET] - See drivers/s390/net/ctcmain.c, comment before function - ctc_setup(). cyclades= [HW,SERIAL] Cyclades multi-serial port adapter. dasd= [HW,NET] See header of drivers/s390/block/dasd_devmap.c. - dasd_discipline= - [HW,NET] - See header of drivers/s390/block/dasd.c. - db9= [HW,JOY] db9_2= db9_3= @@ -254,9 +253,6 @@ Format: [,] See also Documentation/networking/decnet.txt. - decr_overclock= [PPC] - decr_overclock_proc0= - devfs= [DEVFS] See Documentation/filesystems/devfs/boot-options. @@ -305,6 +301,9 @@ This option is obsoleted by the "netdev=" option, which has equivalent usage. See its documentation for details. + eurwdt= [HW,WDT] Eurotech CPU-1220/1410 onboard watchdog. + Format: [,] + fd_mcs= [HW,SCSI] See header of drivers/scsi/fd_mcs.c. @@ -350,7 +349,9 @@ hisax= [HW,ISDN] See Documentation/isdn/README.HiSax. - hugepages= [HW,IA-32] Maximal number of HugeTLB pages + hugepages= [HW,IA-32,IA-64] Maximal number of HugeTLB pages. + + noirqbalance [IA-32,SMP,KNL] Disable kernel irq balancing i8042_direct [HW] Non-translated mode i8042_dumbkbd @@ -394,6 +395,10 @@ inttest= [IA64] + io7= [HW] IO7 for Marvel based alpha systems + See comment before marvel_specify_io7 in + arch/alpha/kernel/core_marvel.c. + ip= [IP_PNP] See Documentation/nfsroot.txt. @@ -495,6 +500,7 @@ mdacon= [MDA] Format: , + Specifies range of consoles to be captured by the MDA. mem=exactmap [KNL,BOOT,IA-32] Enable setting of an exact E820 memory map, as specified by the user. @@ -576,6 +582,8 @@ nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects. + noexec [IA-64] + nofxsr [BUGS=IA-32] nohighio [BUGS=IA-32] Disable highmem block I/O. @@ -599,7 +607,9 @@ noresume [SWSUSP] Disables resume and restore original swap space. - no-scroll [VGA] + no-scroll [VGA] Disables scrollback. + This is required for the Braillex ib80-piezo Braille + reader made by F.H. Papenmeier (Germany). nosbagart [IA-64] @@ -809,6 +819,9 @@ See a comment before function sbpcd_setup() in drivers/cdrom/sbpcd.c. + sc1200wdt= [HW,WDT] SC1200 WDT (watchdog) driver + Format: [,[,]] + scsi_debug_*= [SCSI] See drivers/scsi/scsi_debug.c. @@ -997,9 +1010,6 @@ spia_pedr= spia_peddr= - spread_lpevents= - [PPC] - sscape= [HW,OSS] Format: ,,,, @@ -1009,6 +1019,19 @@ st0x= [HW,SCSI] See header of drivers/scsi/seagate.c. + sti= [HW] + Format: + Set the STI (builtin display/keyboard on the HP-PARISC + machines) console (graphic card) which should be used + as the initial boot-console. + See also comment in drivers/video/console/sticore.c. + + sti_font= [HW] + See comment in drivers/video/console/sticore.c. + + stifb= [HW] + Format: bpp:[:[:...]] + stram_swap= [HW,M68k] swiotlb= [IA-64] Number of I/O TLB slabs @@ -1079,7 +1102,7 @@ wd7000= [HW,SCSI] See header of drivers/scsi/wd7000.c. - wdt= [HW] Watchdog + wdt= [WDT] Watchdog See Documentation/watchdog.txt. xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks. diff -Nru a/Documentation/md.txt b/Documentation/md.txt --- a/Documentation/md.txt Sun Feb 9 21:13:34 2003 +++ b/Documentation/md.txt Sun Feb 9 21:13:34 2003 @@ -9,7 +9,7 @@ for old raid arrays without persistent superblocks: md=,,,,dev0,dev1,...,devn -for raid arrays with persistant superblocks +for raid arrays with persistent superblocks md=,dev0,dev1,...,devn md device no. = the number of the md device ... @@ -21,7 +21,7 @@ raid level = -1 linear mode 0 striped mode - other modes are only supported with persistant super blocks + other modes are only supported with persistent super blocks chunk size factor = (raid-0 and raid-1 only) Set the chunk size as 4k << n. diff -Nru a/Documentation/modules.txt b/Documentation/modules.txt --- a/Documentation/modules.txt Sun Feb 9 21:13:28 2003 +++ b/Documentation/modules.txt Sun Feb 9 21:13:28 2003 @@ -9,20 +9,13 @@ that the kernel now supports. The current required version is listed in the file linux/Documentation/Changes. -* * * NOTE * * * -The kernel has been changed to remove kerneld support and use -the new kmod support. Keep this in mind when reading this file. Kmod -does the exact same thing as kerneld, but doesn't require an external -program (see Documentation/kmod.txt) - In the beginning... ------------------- Anyway, your first step is to compile the kernel, as explained in the file linux/README. It generally goes like: - make config - make dep + make *config <= usually menuconfig or xconfig make clean make zImage or make zlilo @@ -39,15 +32,16 @@ plus those things that you just can't live without... The set of modules is constantly increasing, and you will be able to select -the option "m" in "make config" for those features that the current kernel +the option "m" in "make menuconfig" for those features that the current kernel can offer as loadable modules. You also have a possibility to create modules that are less dependent on -the kernel version. This option can be selected during "make config", by +the kernel version. This option can be selected during "make *config", by enabling CONFIG_MODVERSIONS, and is most useful on "stable" kernel versions, -such as the kernels from the 1.2 and 2.0 series. +such as the kernels from the 2. series. If you have modules that are based on sources that are not included in the official kernel sources, you will certainly like this option... +See below how to compile modules outside the official kernel. Here is a sample of the available modules included in the kernel sources: @@ -83,22 +77,45 @@ make modules -This will compile all modules and update the linux/modules directory. -In this directory you will then find a bunch of symbolic links, -pointing to the various object files in the kernel tree. +This will compile all modules. A module is identified by the +extension .ko, for kernel object. Now, after you have created all your modules, you should also do: make modules_install This will copy all newly made modules into subdirectories under "/lib/modules/kernel_release/", where "kernel_release" is something -like 2.0.1, or whatever the current kernel version is... +like 2.5.54, or whatever the current kernel version is. +Note: Installing modules may require root privileges. As soon as you have rebooted the newly made kernel, you can install and remove modules at will with the utilities: "insmod" and "rmmod". After reading the man-page for insmod, you will also know how easy it is to configure a module when you do "insmod" (hint: symbol=value). +Installing modules in a non-standard location +--------------------------------------------- +When the modules needs to be installed under another directory +the INSTALL_MOD_PATH can be used to prefix "/lib/modules" as seen +in the following example: + +make INSTALL_MOD_PATH=/frodo modules_install + +This will install the modules in the directory /frodo/lib/modules. +/frodo can be a NFS mounted filesystem on another machine, allowing +out-of-the-box support for installation on remote machines. + + +Compiling modules outside the official kernel +--------------------------------------------- +Often modules are developed outside the official kernel. +To keep up with changes in the build system the most portable way +to compile a module outside the kernel is to use the following command-line: + +make -C path/to/kernel/src SUBDIRS=$PWD modules + +This requires that a makefile exits made in accordance to +Documentation/kbuild/makefiles.txt. Nifty features: --------------- diff -Nru a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt --- a/Documentation/networking/bonding.txt Sun Feb 9 21:13:30 2003 +++ b/Documentation/networking/bonding.txt Sun Feb 9 21:13:30 2003 @@ -258,7 +258,7 @@ Specifies the ip addresses to use when arp_interval is > 0. These are the targets of the ARP request sent to determine the health of the link to the targets. Specify these values in ddd.ddd.ddd.ddd format. - Multiple ip adresses must be seperated by a comma. At least one ip + Multiple ip adresses must be separated by a comma. At least one ip address needs to be given for ARP monitoring to work. The maximum number of targets that can be specified is set at 16. @@ -309,7 +309,7 @@ case of just one target, the target itself may go down or have a problem making it unresponsive to ARP requests. Having an additional target (or several) would increase the reliability of the ARP monitoring. -Multiple ARP targets must be seperated by commas as follows: +Multiple ARP targets must be separated by commas as follows: # example options for ARP monitoring with three targets alias bond0 bonding diff -Nru a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt --- a/Documentation/networking/ip-sysctl.txt Sun Feb 9 21:13:31 2003 +++ b/Documentation/networking/ip-sysctl.txt Sun Feb 9 21:13:31 2003 @@ -281,6 +281,14 @@ assassination. Default: 0 +tcp_low_latency - BOOLEAN + If set, the TCP stack makes decisions that prefer lower + latency as opposed to higher throughput. By default, this + option is not set meaning that higher throughput is preferred. + An example of an application where this default should be + changed would be a Beowulf compute cluster. + Default: 0 + ip_local_port_range - 2 INTEGERS Defines the local port range that is used by TCP and UDP to choose the local port. The first number is the first, the diff -Nru a/Documentation/s390/s390dbf.txt b/Documentation/s390/s390dbf.txt --- a/Documentation/s390/s390dbf.txt Sun Feb 9 21:13:34 2003 +++ b/Documentation/s390/s390dbf.txt Sun Feb 9 21:13:34 2003 @@ -8,7 +8,7 @@ ------------ The goal of this feature is to provide a kernel debug logging API where log records can be stored efficiently in memory, where each component -(e.g. device drivers) can have one seperate debug log. +(e.g. device drivers) can have one separate debug log. One purpose of this is to inspect the debug logs after a production system crash in order to analyze the reason for the crash. If the system still runs but only a subcomponent which uses dbf failes, diff -Nru a/Documentation/scsi/ChangeLog.sym53c8xx b/Documentation/scsi/ChangeLog.sym53c8xx --- a/Documentation/scsi/ChangeLog.sym53c8xx Sun Feb 9 21:13:35 2003 +++ b/Documentation/scsi/ChangeLog.sym53c8xx Sun Feb 9 21:13:35 2003 @@ -529,7 +529,7 @@ * version pre-sym53c8xx-0.13 - Some rewrite of the device detection code. This code had been patched too much and needed to be face-lifted a bit. - Remove all platform dependant fix-ups that was not needed or + Remove all platform dependent fix-ups that was not needed or conflicted with some other driver code as work-arounds. Reread the NVRAM before the calling of ncr_attach(). This spares stack space and so allows to handle more boards. diff -Nru a/Documentation/scsi/aic79xx.txt b/Documentation/scsi/aic79xx.txt --- a/Documentation/scsi/aic79xx.txt Sun Feb 9 21:13:34 2003 +++ b/Documentation/scsi/aic79xx.txt Sun Feb 9 21:13:34 2003 @@ -1,5 +1,5 @@ ==================================================================== -= Adaptec Ultra320 Family Manager Set v1.1.1 = += Adaptec Ultra320 Family Manager Set v1.3.0 = = = = README for = = The Linux Operating System = @@ -27,6 +27,10 @@ Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to Ultra320 SCSI Card (two external VHDC and one internal 68-pin) + Adaptec SCSI Card 39320D Dual Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI Card (two external VHDC + and one internal 68-pin) based on the + AIC-7902B ASIC Adaptec SCSI Card 29320 Single Channel 64-bit PCI-X 133MHz to Ultra320 SCSI Card (one external 68-pin, two internal 68-pin, one @@ -39,12 +43,28 @@ Ultra320 SCSI ASIC AIC-7902A4 Dual Channel 64-bit PCI-X 133MHz to Ultra320 SCSI ASIC - + AIC-7902B Dual Channel 64-bit PCI-X 133MHz to + Ultra320 SCSI ASIC 2. Version History + (V1.3.0, January 2003) Full regression testing for all U320 products + completed. + + (V1.3.0 ALPHA, November 2002) Initial Alpha release. + Added abort and target/lun reset error recovery handler and + interrupt coalessing. + + (V1.2.0, November 2002) Added support for Domain Validation and + Hewlett-Packard version of the 39320D and AIC-7902 adapters. + Support for previous adapters has not been fully tested and should + only be used at the customer's own risk. + (V1.1.1, September 2002) Added support for the Linux 2.5.X kernel series + (V1.1.0, August 2002) Added support for four additional SCSI + products: ASC-39320, ASC-29320, ASC-29320LP, AIC-7901. + (V1.1, August 2002) Added support for four additional SCSI products: ASC-39320, ASC-29320, ASC-29320LP, AIC-7901. @@ -56,20 +76,21 @@ - 320MB/s transfer rates - Packetized SCSI Protocol at 160MB/s and 320MB/s - Quick Arbitration Selection (QAS) - - Initiator Mode (target mode not currently - supported) - - Support for the PCI-x standard up to 133MHz - - Support for the PCI v2.2 standard + - Retained Training Information (Rev B. ASIC only) + - Interrupt Coalessing + - Initiator Mode (target mode not currently + supported) + - Support for the PCI-X standard up to 133MHz + - Support for the PCI v2.2 standard 2.2. Operating System Support: - - Redhat Linux 7.2, 7.3, Advanced Server 2.1 - - SuSE Linux 7.3, 8.0, Enterprise Server 7 + - Redhat Linux 7.2, 7.3, 8.0, Advanced Server 2.1 + - SuSE Linux 7.3, 8.0, 8.1, Enterprise Server 7 - only Intel and AMD x86 supported at this time - - >4GB memory configurations supported. + - >4GB memory configurations supported. Refer to the User's Guide for more details on this. - 3. Command Line Options WARNING: ALTERING OR ADDING THESE DRIVER PARAMETERS @@ -77,7 +98,7 @@ USE THEM WITH CAUTION. Edit the file "modules.conf" in the directory /etc and add/edit a - line containing 'options aic79xx=[command[,command...]]' where + line containing 'options aic79xx aic79xx=[command[,command...]]' where 'command' is one or more of the following: ----------------------------------------------------------------- Option: verbose @@ -88,6 +109,9 @@ ----------------------------------------------------------------- Option: debug:[value] Definition: Enables various levels of debugging information + The bit definitions for the debugging mask can + be found in drivers/scsi/aic7xxx/aic79xx.h under + the "Debug" heading. Possible Values: 0x0000 = no debugging, 0xffff = full debugging Default Value: 0x0000 ----------------------------------------------------------------- @@ -114,120 +138,140 @@ Possible Values: This option is a flag Default Value: disabled ----------------------------------------------------------------- - Option: global_tag_depth + Option: global_tag_depth Definition: Global tag depth for all targets on all busses. - This option sets the default tag depth which - may be selectively overridden vi the tag_info - option. + This option sets the default tag depth which + may be selectively overridden vi the tag_info + option. Possible Values: 1 - 253 Default Value: 32 ----------------------------------------------------------------- Option: tag_info:{{value[,value...]}[,{value[,value...]}...]} Definition: Set the per-target tagged queue depth on a - per controller basis. Both controllers and targets - may be ommitted indicating that they should retain - the default tag depth. + per controller basis. Both controllers and targets + may be ommitted indicating that they should retain + the default tag depth. Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32} - On Controller 0 - specifies a tag depth of 16 for target 0 - specifies a tag depth of 64 for target 3 - specifies a tag depth of 8 for targets 4 and 5 - leaves target 6 at the default - specifies a tag depth of 32 for targets 1,2,7-15 - All other targets retain the default depth. - - tag_info:{{},{32,,32}} - On Controller 1 - specifies a tag depth of 32 for targets 0 and 2 - All other targets retain the default depth. - + On Controller 0 + specifies a tag depth of 16 for target 0 + specifies a tag depth of 64 for target 3 + specifies a tag depth of 8 for targets 4 and 5 + leaves target 6 at the default + specifies a tag depth of 32 for targets 1,2,7-15 + All other targets retain the default depth. + + tag_info:{{},{32,,32}} + On Controller 1 + specifies a tag depth of 32 for targets 0 and 2 + All other targets retain the default depth. + Possible Values: 1 - 253 Default Value: 32 ----------------------------------------------------------------- Option: rd_strm: {rd_strm_bitmask[,rd_strm_bitmask...]} Definition: Enable read streaming on a per target basis. The rd_strm_bitmask is a 16 bit hex value in which - each bit represents a target. Setting the target's + each bit represents a target. Setting the target's bit to '1' enables read streaming for that target. Controllers may be ommitted indicating that - they should retain the default read streaming setting. - Example: rd_strm:{0x0041} - On Controller 0 - enables read streaming for targets 0 and 6. - disables read streaming for targets 1-5,7-15. - All other targets retain the default read - streaming setting. - Example: rd_strm:{0x0023,,0xFFFF} - On Controller 0 - enables read streaming for targets 1,2, and 5. - disables read streaming for targets 3,4,6-15. - On Controller 2 - enables read streaming for all targets. - All other targets retain the default read - streaming setting. - + they should retain the default read streaming setting. + Example: rd_strm:{0x0041} + On Controller 0 + enables read streaming for targets 0 and 6. + disables read streaming for targets 1-5,7-15. + All other targets retain the default read + streaming setting. + Example: rd_strm:{0x0023,,0xFFFF} + On Controller 0 + enables read streaming for targets 1,2, and 5. + disables read streaming for targets 3,4,6-15. + On Controller 2 + enables read streaming for all targets. + All other targets retain the default read + streaming setting. + Possible Values: 0x0000 - 0xffff Default Value: 0x0000 ----------------------------------------------------------------- + Option: dv: {value[,value...]} + Definition: Set Domain Validation Policy on a per-controller basis. + Controllers may be ommitted indicating that + they should retain the default read streaming setting. + Example: dv:{-1,0,,1,1,0} + On Controller 0 leave DV at its default setting. + On Controller 1 disable DV. + Skip configuration on Controller 2. + On Controllers 3 and 4 enable DV. + On Controller 5 disable DV. + + Possible Values: < 0 Use setting from serial EEPROM. + 0 Disable DV + > 0 Enable DV + Default Value: DV Serial EEPROM configuration setting. + ----------------------------------------------------------------- + Option: seltime:[value] + Definition: Specifies the selection timeout value + Possible Values: 0 = 256ms, 1 = 128ms, 2 = 64ms, 3 = 32ms + Default Value: 0 + ----------------------------------------------------------------- + + *** The following three options should only be changed at *** + *** the direction of a technical support representative. *** + + ----------------------------------------------------------------- Option: precomp: {value[,value...]} Definition: Set IO Cell precompensation value on a per-controller - basis. + basis. Controllers may be ommitted indicating that - they should retain the default precompensation setting. - Example: precomp:{0x1} - On Controller 0 set precompensation to 1. - Example: precomp:{1,,7} - On Controller 0 set precompensation to 1. - On Controller 2 set precompensation to 8. - + they should retain the default precompensation setting. + Example: precomp:{0x1} + On Controller 0 set precompensation to 1. + Example: precomp:{1,,7} + On Controller 0 set precompensation to 1. + On Controller 2 set precompensation to 8. + Possible Values: 0 - 7 Default Value: Varies based on chip revision ----------------------------------------------------------------- Option: slewrate: {value[,value...]} Definition: Set IO Cell slew rate on a per-controller basis. Controllers may be ommitted indicating that - they should retain the default slew rate setting. - Example: slewrate:{0x1} - On Controller 0 set slew rate to 1. - Example: slewrate :{1,,8} - On Controller 0 set slew rate to 1. - On Controller 2 set slew rate to 8. - + they should retain the default slew rate setting. + Example: slewrate:{0x1} + On Controller 0 set slew rate to 1. + Example: slewrate :{1,,8} + On Controller 0 set slew rate to 1. + On Controller 2 set slew rate to 8. + Possible Values: 0 - 15 Default Value: Varies based on chip revision ----------------------------------------------------------------- Option: amplitude: {value[,value...]} Definition: Set IO Cell signal amplitude on a per-controller basis. Controllers may be ommitted indicating that - they should retain the default read streaming setting. - Example: amplitude:{0x1} - On Controller 0 set amplitude to 1. - Example: amplitude :{1,,7} - On Controller 0 set amplitude to 1. - On Controller 2 set amplitude to 7. - + they should retain the default read streaming setting. + Example: amplitude:{0x1} + On Controller 0 set amplitude to 1. + Example: amplitude :{1,,7} + On Controller 0 set amplitude to 1. + On Controller 2 set amplitude to 7. + Possible Values: 1 - 7 Default Value: Varies based on chip revision ----------------------------------------------------------------- - Option: seltime:[value] - Definition: Specifies the selection timeout value - Possible Values: 0 = 256ms, 1 = 128ms, 2 = 64ms, 3 = 32ms - Default Value: 0 - ----------------------------------------------------------------- - Example: 'options aic79xx=verbose,rd_strm:{{0x0041}}' - enables verbose output in the driver and turns read streaming on - for targets 0 and 6 of Controller 0. + Example: 'options aic79xx aic79xx=verbose,rd_strm:{{0x0041}}' + enables verbose output in the driver and turns read streaming on + for targets 0 and 6 of Controller 0. 4. Additional Notes 4.1. Known/Unresolved or FYI Issues - * Domain Validation is not implemented. - * Under SuSE Linux Enterprise 7, the driver may fail to operate - correctly due to a problem with PCI interrupt routing in the - Linux kernel. Please contact SuSE for an updated Linux - kernel. + * Under SuSE Linux Enterprise 7, the driver may fail to operate + correctly due to a problem with PCI interrupt routing in the + Linux kernel. Please contact SuSE for an updated Linux + kernel. 4.2. Third-Party Compatibility Issues @@ -240,6 +284,18 @@ * PCI Hot Plug is untested and may cause the operating system to stop responding. + * Luns that are not numbered contiguously starting with 0 might not + be automatically probed during system startup. This is a limitation + of the OS. Please contact your Linux vendor for instructions on + manually probing non-contiguous luns. + * Using the Driver Update Disk version of this package during OS + installation under RedHat might result in two versions of this + driver being installed into the system module directory. This + might cause problems with the /sbin/mkinitrd program and/or + other RPM packages that try to install system modules. The best + way to correct this once the system is running is to install + the latest RPM package version of this driver, available from + http://www.adaptec.com. 5. Contacting Adaptec @@ -316,7 +372,7 @@ ------------------------------------------------------------------- -(c) 2002 Adaptec, Inc. All Rights Reserved. No part of this +(c) 2003 Adaptec, Inc. All Rights Reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, electronic, mechanical, photocopying, recording or otherwise, without prior written consent diff -Nru a/Documentation/scsi/aic7xxx.txt b/Documentation/scsi/aic7xxx.txt --- a/Documentation/scsi/aic7xxx.txt Sun Feb 9 21:13:30 2003 +++ b/Documentation/scsi/aic7xxx.txt Sun Feb 9 21:13:30 2003 @@ -1,5 +1,5 @@ ==================================================================== -= Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v6.2.10 = += Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v6.2.28 = = README for = = The Linux Operating System = ==================================================================== @@ -7,8 +7,9 @@ The following information is available in this file: 1. Supported Hardware - 2. Command Line Options - 3. Contacting Adaptec + 2. Version History + 3. Command Line Options + 4. Contacting Adaptec 1. Supported Hardware @@ -44,52 +45,52 @@ 5. Block Move Instruction Support - Doubles the speed of certain sequencer operations. 6. `Bayonet' style Scatter Gather Engine - Improves S/G prefetch - performance. + performance. 7. Queuing Registers - Allows queuing of new transactions without - pausing the sequencer. + pausing the sequencer. 8. Multiple Target IDs - Allows the controller to respond to selection as a target on multiple SCSI IDs. Controller Chip Host-Bus Int-Connectors Ext-Connectors Notes -------------------------------------------------------------------------- - AHA-274X[A] aic7770 EISA SE-50M SE-HD50F - AHA-274X[A]W aic7770 EISA SE-HD68F SE-HD68F - SE-50M - AHA-274X[A]T aic7770 EISA 2 X SE-50M SE-HD50F - AHA-2842 aic7770 VL SE-50M SE-HD50F - AHA-2940AU aic7860 PCI/32 SE-50M SE-HD50F + AHA-274X[A] aic7770 EISA SE-50M SE-HD50F + AHA-274X[A]W aic7770 EISA SE-HD68F SE-HD68F + SE-50M + AHA-274X[A]T aic7770 EISA 2 X SE-50M SE-HD50F + AHA-2842 aic7770 VL SE-50M SE-HD50F + AHA-2940AU aic7860 PCI/32 SE-50M SE-HD50F AVA-2902I aic7860 PCI/32 SE-50M AVA-2902E aic7860 PCI/32 SE-50M - AVA-2906 aic7856 PCI/32 SE-50M SE-DB25F - APC-7850 aic7850 PCI/32 SE-50M 1 + AVA-2906 aic7856 PCI/32 SE-50M SE-DB25F + APC-7850 aic7850 PCI/32 SE-50M 1 AVA-2940 aic7860 PCI/32 SE-50M AHA-2920B aic7860 PCI/32 SE-50M AHA-2930B aic7860 PCI/32 SE-50M - AHA-2920C aic7856 PCI/32 SE-50M SE-HD50F + AHA-2920C aic7856 PCI/32 SE-50M SE-HD50F AHA-2930C aic7860 PCI/32 SE-50M AHA-2930C aic7860 PCI/32 SE-50M AHA-2910C aic7860 PCI/32 SE-50M AHA-2915C aic7860 PCI/32 SE-50M - AHA-2940AU/CN aic7860 PCI/32 SE-50M SE-HD50F - AHA-2944W aic7870 PCI/32 HVD-HD68F HVD-HD68F - HVD-50M - AHA-3940W aic7870 PCI/32 2 X SE-HD68F SE-HD68F 2 + AHA-2940AU/CN aic7860 PCI/32 SE-50M SE-HD50F + AHA-2944W aic7870 PCI/32 HVD-HD68F HVD-HD68F + HVD-50M + AHA-3940W aic7870 PCI/32 2 X SE-HD68F SE-HD68F 2 AHA-2940UW aic7880 PCI/32 SE-HD68F - SE-50M SE-HD68F - AHA-2940U aic7880 PCI/32 SE-50M SE-HD50F + SE-50M SE-HD68F + AHA-2940U aic7880 PCI/32 SE-50M SE-HD50F AHA-2940D aic7880 PCI/32 - AHA-2940 A/T aic7880 PCI/32 + aHA-2940 A/T aic7880 PCI/32 AHA-2940D A/T aic7880 PCI/32 - AHA-3940UW aic7880 PCI/32 2 X SE-HD68F SE-HD68F 3 + AHA-3940UW aic7880 PCI/32 2 X SE-HD68F SE-HD68F 3 AHA-3940UWD aic7880 PCI/32 2 X SE-HD68F 2 X SE-VHD68F 3 - AHA-3940U aic7880 PCI/32 2 X SE-50M SE-HD50F 3 - AHA-2944UW aic7880 PCI/32 HVD-HD68F HVD-HD68F - HVD-50M + AHA-3940U aic7880 PCI/32 2 X SE-50M SE-HD50F 3 + AHA-2944UW aic7880 PCI/32 HVD-HD68F HVD-HD68F + HVD-50M AHA-3944UWD aic7880 PCI/32 2 X HVD-HD68F 2 X HVD-VHD68F 3 AHA-4944UW aic7880 PCI/32 AHA-2930UW aic7880 PCI/32 - AHA-2940UW Pro aic7880 PCI/32 SE-HD68F SE-HD68F 4 - SE-50M + AHA-2940UW Pro aic7880 PCI/32 SE-HD68F SE-HD68F 4 + SE-50M AHA-2940UW/CN aic7880 PCI/32 AHA-2940UDual aic7895 PCI/32 AHA-2940UWDual aic7895 PCI/32 @@ -98,30 +99,30 @@ AHA-3940AUWD aic7895 PCI/32 AHA-3940AU aic7895 PCI/32 AHA-3944AUWD aic7895 PCI/32 2 X HVD-HD68F 2 X HVD-VHD68F - AHA-2940U2B aic7890 PCI/32 LVD-HD68F LVD-HD68F + AHA-2940U2B aic7890 PCI/32 LVD-HD68F LVD-HD68F AHA-2940U2 OEM aic7891 PCI/64 - AHA-2940U2W aic7890 PCI/32 LVD-HD68F LVD-HD68F - SE-HD68F - SE-50M - AHA-2950U2B aic7891 PCI/64 LVD-HD68F LVD-HD68F - AHA-2930U2 aic7890 PCI/32 LVD-HD68F SE-HD50F - SE-50M + AHA-2940U2W aic7890 PCI/32 LVD-HD68F LVD-HD68F + SE-HD68F + SE-50M + AHA-2950U2B aic7891 PCI/64 LVD-HD68F LVD-HD68F + AHA-2930U2 aic7890 PCI/32 LVD-HD68F SE-HD50F + SE-50M AHA-3950U2B aic7897 PCI/64 AHA-3950U2D aic7897 PCI/64 AHA-29160 aic7892 PCI/64-66 AHA-29160 CPQ aic7892 PCI/64-66 - AHA-29160N aic7892 PCI/32 LVD-HD68F SE-HD50F - SE-50M + AHA-29160N aic7892 PCI/32 LVD-HD68F SE-HD50F + SE-50M AHA-29160LP aic7892 PCI/64-66 AHA-19160 aic7892 PCI/64-66 AHA-29150LP aic7892 PCI/64-66 AHA-29130LP aic7892 PCI/64-66 AHA-3960D aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F - LVD-50M + LVD-50M AHA-3960D CPQ aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F - LVD-50M + LVD-50M AHA-39160 aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F - LVD-50M + LVD-50M 1. No BIOS support 2. DEC21050 PCI-PCI bridge with multiple controller chips on secondary bus @@ -129,14 +130,22 @@ 4. All three SCSI connectors may be used simultaneously without SCSI "stub" effects. -2. Command Line Options +2. Version History + + 6.2.28 - Domain Validation Fixes + PCI parity error disable + Enhanced Memory Mapped I/O probe + + 6.2.20 - Added Domain Validation + +3. Command Line Options WARNING: ALTERING OR ADDING THESE DRIVER PARAMETERS INCORRECTLY CAN RENDER YOUR SYSTEM INOPERABLE. USE THEM WITH CAUTION. Edit the file "modules.conf" in the directory /etc and add/edit a - line containing 'options aic7xxx=[command[,command...]]' where + line containing 'options aic7xxx aic7xxx=[command[,command...]]' where 'command' is one or more of the following: ----------------------------------------------------------------- Option: verbose @@ -150,6 +159,30 @@ Possible Values: 0x0000 = no debugging, 0xffff = full debugging Default Value: 0x0000 ----------------------------------------------------------------- + Option: no_probe + Definition: Do not probe for EISA/VLB controllers. + This is a toggle. If the driver is compiled + to not probe EISA/VLB controllers by default, + specifying "no_probe" will enable this probing. + If the driver is compiled to probe EISA/VLB + controllers by default, specifying "no_probe" + will disable this probing. + Possible Values: This option is a toggle + Default Value: EISA/VLB probing is disabled by default. + ----------------------------------------------------------------- + Option: pci_parity + Definition: Toggles the detection of PCI parity errors. + On many motherboards with VIA chipsets, + PCI parity is not generated correctly on the + PCI bus. It is impossible for the hardware to + differentiate between these "spurious" parity + errors and real parity errors. The symptom of + this problem is a stream of the message: + "scsi0: Data Parity Error Detected during address or write data phase" + output by the driver. + Possible Values: This option is a toggle + Default Value: PCI Parity Error reporting is disabled + ----------------------------------------------------------------- Option: no_reset Definition: Do not reset the bus during the initial probe phase @@ -173,33 +206,33 @@ Possible Values: This option is a flag Default Value: disabled ----------------------------------------------------------------- - Option: global_tag_depth + Option: global_tag_depth:[value] Definition: Global tag depth for all targets on all busses. - This option sets the default tag depth which - may be selectively overridden vi the tag_info - option. + This option sets the default tag depth which + may be selectively overridden vi the tag_info + option. Possible Values: 1 - 253 Default Value: 32 ----------------------------------------------------------------- Option: tag_info:{{value[,value...]}[,{value[,value...]}...]} Definition: Set the per-target tagged queue depth on a - per controller basis. Both controllers and targets - may be ommitted indicating that they should retain - the default tag depth. + per controller basis. Both controllers and targets + may be ommitted indicating that they should retain + the default tag depth. Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32} - On Controller 0 - specifies a tag depth of 16 for target 0 - specifies a tag depth of 64 for target 3 - specifies a tag depth of 8 for targets 4 and 5 - leaves target 6 at the default - specifies a tag depth of 32 for targets 1,2,7-15 - All other targets retain the default depth. - - tag_info:{{},{32,,32}} - On Controller 1 - specifies a tag depth of 32 for targets 0 and 2 - All other targets retain the default depth. - + On Controller 0 + specifies a tag depth of 16 for target 0 + specifies a tag depth of 64 for target 3 + specifies a tag depth of 8 for targets 4 and 5 + leaves target 6 at the default + specifies a tag depth of 32 for targets 1,2,7-15 + All other targets retain the default depth. + + tag_info:{{},{32,,32}} + On Controller 1 + specifies a tag depth of 32 for targets 0 and 2 + All other targets retain the default depth. + Possible Values: 1 - 253 Default Value: 32 ----------------------------------------------------------------- @@ -208,10 +241,30 @@ Possible Values: 0 = 256ms, 1 = 128ms, 2 = 64ms, 3 = 32ms Default Value: 0 ----------------------------------------------------------------- + Option: dv: {value[,value...]} + Definition: Set Domain Validation Policy on a per-controller basis. + Controllers may be ommitted indicating that + they should retain the default read streaming setting. + Example: dv:{-1,0,,1,1,0} + On Controller 0 leave DV at its default setting. + On Controller 1 disable DV. + Skip configuration on Controller 2. + On Controllers 3 and 4 enable DV. + On Controller 5 disable DV. + + Possible Values: < 0 Use setting from serial EEPROM. + 0 Disable DV + > 0 Enable DV + + Default Value: SCSI-Select setting on controllers with a SCSI Select + option for DV. Otherwise, on for controllers supporting + U160 speeds and off for all other controller types. + ----------------------------------------------------------------- - Example: 'options aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1" - enables verbose logging, Disable EISA/VLB probing, - and set tag depth on Controller 1/Target 2 to 10 tags. + Example: + 'options aic7xxx aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1" + enables verbose logging, Disable EISA/VLB probing, + and set tag depth on Controller 1/Target 2 to 10 tags. 3. Contacting Adaptec diff -Nru a/Documentation/scsi/ibmmca.txt b/Documentation/scsi/ibmmca.txt --- a/Documentation/scsi/ibmmca.txt Sun Feb 9 21:13:34 2003 +++ b/Documentation/scsi/ibmmca.txt Sun Feb 9 21:13:34 2003 @@ -346,7 +346,7 @@ This table is quite informative for interested users. It shows the load of commands on the subsystem and wether you are running the bypassed (software) or integrated (hardware) SCSI-command set (see below). The - amount of accesses is shown. Read, write, modeselect is shown seperately + amount of accesses is shown. Read, write, modeselect is shown separately in order to help debugging problems with CD-ROMs or tapedrives. The following table shows the list of 15 logical device numbers, that are @@ -906,7 +906,7 @@ to does not offer more space, invalid memory accesses destabilized the kernel. 3) version 4.0 is only valid for kernel 2.4.0 or later. This is necessary - to remove old kernel version dependant waste from the driver. 3.2d is + to remove old kernel version dependent waste from the driver. 3.2d is only distributed with older kernels but keeps compatibility with older kernel versions. 4.0 and higher versions cannot be used with older kernels anymore!! You must have at least kernel 2.4.0!! @@ -943,7 +943,7 @@ 4 To do ------- - - IBM SCSI-2 F/W external SCSI bus support in seperate mode! + - IBM SCSI-2 F/W external SCSI bus support in separate mode! - It seems that the handling of bad disks is really bad - non-existent, in fact. However, a low-level driver cannot help much, if such things happen. @@ -1382,7 +1382,7 @@ 9 Disclaimer ------------ - Beside the GNU General Public License and the dependant disclaimers and disclaimers + Beside the GNU General Public License and the dependent disclaimers and disclaimers concerning the Linux-kernel in special, this SCSI-driver comes without any warranty. Its functionality is tested as good as possible on certain machines and combinations of computer hardware, which does not exclude, diff -Nru a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt --- a/Documentation/sound/alsa/ALSA-Configuration.txt Sun Feb 9 21:13:29 2003 +++ b/Documentation/sound/alsa/ALSA-Configuration.txt Sun Feb 9 21:13:29 2003 @@ -213,6 +213,8 @@ mpu_port - 0x300 (default),0x310,0x320,0x330, -1 (diable) fm_port - 0x388 (default), -1 (disable) + soft_ac3 - Sofware-conversion of raw SPDIF packets (model 033 only) + (default = 1) Module supports autoprobe and multiple chips (max 8). @@ -748,7 +750,8 @@ Module snd-rme32 ---------------- - Module for RME Digi32, Digi32/8 and Digi32 PRO soundcards. + Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32, + Prodif96 and Prodif Gold) soundcards. Module supports up to 8 cards. diff -Nru a/Documentation/sound/alsa/CMIPCI.txt b/Documentation/sound/alsa/CMIPCI.txt --- a/Documentation/sound/alsa/CMIPCI.txt Sun Feb 9 21:13:28 2003 +++ b/Documentation/sound/alsa/CMIPCI.txt Sun Feb 9 21:13:28 2003 @@ -20,7 +20,7 @@ - The first DAC supports U8 and S16LE formats, while the second DAC supports only S16LE. -- The second DAC supports only two channel stereo. +- The seconde DAC supports only two channel stereo. Please note that the CM8x38 DAC doesn't support continuous playback rate but only fixed rates: 5512, 8000, 11025, 16000, 22050, 32000, @@ -65,15 +65,20 @@ "-MC" such like "CMI8738-MC6". You can check this name from /proc/asound/cards. -When the 4/6-ch output is enabled, the front DAC accepts up to 6 (or -4) channels. This is different from the dual DACs described in the -previous section. While the dual DAC supports two different rates or +When the 4/6-ch output is enabled, the second DAC accepts up to 6 (or +4) channels. While the dual DAC supports two different rates or formats, the 4/6-ch playback supports only the same condition for all -channels. +channels. Since the multi-channel playback mode uses both DACs, you +cannot operate with full-duplex. -For using 4/6 channel playback, you need to specify the PCM channels -as you like and set the format S16LE. For example, for playback with -4 channels, +The 4.0 and 5.1 modes are defined as the pcm "surround40" and "surround51" +in alsa-lib. For example, you can play a WAV file with 6 channels like + + % aplay -Dsurround51 sixchannels.wav + +For programmin the 4/6 channel playback, you need to specify the PCM +channels as you like and set the format S16LE. For example, for playback +with 4 channels, snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED); // or mmap if you like @@ -82,9 +87,15 @@ and use the interleaved 4 channel data. -There is a control switch, "Line-In As Bass". As you can imagine from -its name, the line-in jack is used for the bass (5th and 6th channels) -output. +There are some control switchs affecting to the speaker connections: + +"Line-In As Rear" - As mentioned above, the line-in jack is used + for the rear (3th and 4th channels) output. +"Line-In As Bass" - The line-in jack is used for the bass (5th + and 6th channels) output. +"Mic As Center/LFE" - The mic jack is used for the bass output. + If this switch is on, you cannot use a microphone as a capture + source, of course. Digital I/O @@ -134,8 +145,7 @@ (see the next section). "IEC958 In Select" - Select SPDIF input, the internal CD-in (false) - and the external input (true). This switch appears only on - the chip models 039 or later. + and the external input (true). "IEC958 Loop" - SPDIF input data is loop back into SPDIF output (aka bypass) @@ -169,6 +179,11 @@ Similarly the following switches are off: "IEC958 Mix Analog" and "IEC958 Loop". The switches are resumed after closing the SPDIF PCM device automatically to the previous state. + +On the model 033, AC3 is implemented by the software conversion in +the driver. This prevents the mmap support. If you need mmap +support, pass the "soft_ac3=0" module option. This doesn't matter +on the newer models. ANALOG MIXER INTERFACE diff -Nru a/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl b/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl Sun Feb 9 21:13:37 2003 @@ -0,0 +1,102 @@ + + + + + + + + + + The ALSA Driver API + + + + This document is free; 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 document 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 + + + + + + Management of Cards and Devices + Card Managment +!Esound/core/init.c + + Device Components +!Esound/core/device.c + + KMOD and Device File Entries +!Esound/core/sound.c + + Memory Management Helpers +!Esound/core/memory.c +!Iinclude/sound/sndmagic.h + + + PCM API + PCM Core +!Esound/core/pcm.c +!Esound/core/pcm_lib.c +!Esound/core/pcm_native.c + + PCM Format Helpers +!Esound/core/pcm_misc.c + + PCM Memory Managment +!Esound/core/pcm_memory.c + + SG-Buffer Helpers +!Esound/core/pcm_sgbuf.c + + + Control/Mixer API + General Control Interface +!Esound/core/control.c + + AC97 Codec API +!Esound/pci/ac97/ac97_codec.c + + + MIDI API + Raw MIDI API +!Esound/core/rawmidi.c + + MPU401-UART API +!Esound/drivers/mpu401/mpu401_uart.c + + + Proc Info API + Proc Info Interface +!Esound/core/info.c + + + Miscellaneous Functions + Hardware-Dependent Devices API +!Esound/core/hwdep.c + + ISA DMA Helpers +!Esound/core/isadma.c + + Other Helper Macros +!Iinclude/sound/core.h + + + + diff -Nru a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl Sun Feb 9 21:13:37 2003 @@ -0,0 +1,5222 @@ + + + + + + + + + + Writing an ALSA Driver + + Takashi + Iwai + +
+ tiwai@suse.de +
+
+
+ + Dec. 27, 2002 + 0.2 (reborn at Christmas) + + + + This document describes how to write an ALSA (Advanced Linux + Sound Architecture) driver. + + + + + + Copyright (c) 2002 Takashi Iwai tiwai@suse.de + + + + This document is free; 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 document 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 + + + +
+ + + + + + Preface + + This document describes how to write an + + ALSA (Advanced Linux Sound Architecture) + driver. The document focuses mainly on the PCI soundcard. + In the case of other device types, the API might + be different, too. However, at least the ALSA kernel API is + consistent, and therefore it would be still a bit help for + writing them. + + + + The target of this document is ones who already have enough + skill of C language and have the basic knowledge of linux + kernel programming. This document doesn't explain the general + topics of linux kernel codes and doesn't cover the detail of + implementation of each low-level driver. It describes only how is + the standard way to write a PCI sound driver on ALSA. + + + + If you are already familiar with the older ALSA ver.0.5.x, you + can check the drivers such as es1938.c or + maestro3.c which have also almost the same + code-base in the ALSA 0.5.x tree, so you can compare the differences. + + + + This document is still a draft version. Any feedbacks and + corrections, please!! + + + + + + + + + File Tree Structure + +
+ General + + The ALSA drivers are provided in the two ways. + + + + One is the the trees provided as a tarball or via cvs from the + ALSA's ftp site, and another is the 2.5 (or later) Linux kernel + tree. To synchronize both, the ALSA driver tree is split to + two different trees: alsa-kernel and alsa-driver. The former + contains purely the source codes for the Linux 2.5 (or later) + tree. This tree is designed only for compilation on 2.5 or + later environment. The latter, alsa-driver, contains many subtle + files for compiling the ALSA driver on the outside of Linux + kernel like configure script, the wrapper functions for older, + 2.2 and 2.4 kernels, to adapt the latest kernel API, + and additional drivers which are still in development or in + tests. The drivers in alsa-driver tree will be moved to + alsa-kernel (eventually 2.5 kernel tree) once when they are + finished and confirmed to work fine. + + + + The file tree structure of ALSA driver is depicted below. Both + alsa-kernel and alsa-driver have almost the same file + structure, except for core directory. It's + named as acore in alsa-driver tree. + + + ALSA File Tree Structure + + sound + /core + /oss + /seq + /oss + /instr + /ioctl32 + /include + /drivers + /mpu401 + /opl3 + /i2c + /l3 + /synth + /emux + /pci + /(cards) + /isa + /(cards) + /arm + /ppc + /sparc + /usb + /pcmcia /(cards) + /oss + + + +
+ +
+ core directory + + This directory contains the middle layer, that is, the heart + of ALSA drivers. In this directory, the native ALSA modules are + stored. The sub-directories contain different modules and are + dependent upon the kernel config. + + +
+ core/oss + + + The codes for PCM and mixer OSS emulation modules are stored + in this directory. The rawmidi OSS emulation is included in + the ALSA rawmidi code since it's quite small. The sequencer + code is stored in core/seq/oss directory (see + + below). + +
+ +
+ core/ioctl32 + + + This directory contains the 32bit-ioctl wrappers for 64bit + architectures such like x86-64, ppc64 and sparc64. For 32bit + and alpha architectures, these are not compiled. + +
+ +
+ core/seq + + This and its sub-directories are for the ALSA + sequencer. This directory contains the sequencer core and + primary sequencer modules such like snd-seq-midi, + snd-seq-virmidi, etc. They are compiled only when + CONFIG_SND_SEQUENCER is set in the kernel + config. + +
+ +
+ core/seq/oss + + This contains the OSS sequencer emulation codes. + +
+ +
+ core/seq/instr + + This directory contains the modules for the sequencer + instrument layer. + +
+
+ +
+ include directory + + This is the place for the public header files of ALSA drivers, + which are to be exported to the user-space, or included by + several files at different directories. Basically, the private + header files should not be placed in this directory, but you may + still find files there, due to historical reason :) + +
+ +
+ drivers directory + + This directory contains the non-architecture-specific + codes. For example, the dummy pcm driver and the serial MIDI + driver are found in this directory. In the sub-directories, + there are the codes for components which are independent from + bus and cpu architectures. + + +
+ drivers/mpu401 + + The MPU401 and MPU401-UART modules are stored here. + +
+ +
+ drivers/opl3 + + The OPL3 FM-synth stuff is found here. + +
+
+ +
+ i2c directory + + This contains the ALSA i2c components. + + + + Although there is a standard i2c layer on Linux, ALSA uses its + own i2c codes for some cards, because the soundcard needs only a + simple operation and the standard API is too complicated for + such a purpose. + + +
+ i2c/l3 + + This is a sub-directory for ARM L3 i2c. + +
+
+ +
+ synth directory + + This contains the synth middle-level modules. + + + + So far, there is only Emu8000/Emu10k1 synth driver under + synth/emux sub-directory. + +
+ +
+ pci directory + + This and its sub-directories hold the top-level card modules + for PCI soundcards. + + + + The drivers compiled from a single file is stored directly on + pci directory, while the drivers with several source files are + stored on its own sub-directory (e.g. emu10k1, ice1712). + +
+ +
+ isa directory + + This and its sub-directories hold the top-level card modules + for ISA soundcards. + +
+ +
+ arm, ppc, and sparc directories + + These are for the top-level card modules which are + architecture specific. + +
+ +
+ usb directory + + This contains the USB-audio driver. On the latest version, the + USB MIDI driver is integrated together with usb-audio driver. + +
+ +
+ pcmcia directory + + The PCMCIA, especially PCCard drivers will go here. CardBus + drivers will be on pci directory, because its API is identical + with the standard PCI cards. + + + + At this moment, only VX-pocket driver exists. + +
+ +
+ oss directory + + The OSS/Lite source files are stored here on Linux 2.5 (or + later) tree. (In the ALSA driver tarball, it's empty, of course :) + +
+
+ + + + + + + Basic Flow for PCI Drivers + +
+ Outline + + The minimum flow of PCI soundcard is like the following: + + + define the PCI ID table (see the section + PCI Entries + ). + create probe() callback. + create remove() callback. + create pci_driver table which contains the three pointers above. + create init() function just calling pci_module_init() to register the pci_driver table defined above. + create exit() function to call pci_unregister_driver() function. + + +
+ +
+ Full Code Example + + The code example is shown below. Some parts are kept + unimplemented at this moment but will be filled in the + succeeding sections. The numbers in comment lines of + snd_mychip_probe() function are the + markers. + + + Basic Flow for PCI Drivers Example + + + #include + #include + #include + #include + #define SNDRV_GET_ID + #include + + // module parameters (see "Module Parameters") + static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; + static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; + static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; + + // definition of the chip-specific record + typedef struct snd_mychip mychip_t; + struct snd_mychip { + snd_card_t *card; + // rest of implementation will be in the section + // "PCI Resource Managements" + }; + + // this should be go into + // (see "Management of Cards and Components") + #define mychip_t_magic 0xa15a4501 + + // chip-specific destructor + // (see "PCI Resource Managements") + static int snd_mychip_free(mychip_t *chip) + { + // will be implemented later... + } + + // component-destructor + // (see "Management of Cards and Components") + static int snd_mychip_dev_free(snd_device_t *device) + { + mychip_t *chip = snd_magic_cast(mychip_t, + device->device_data, return -ENXIO); + return snd_mychip_free(chip); + } + + // chip-specific constructor + // (see "Management of Cards and Components") + static int __devinit snd_mychip_create(snd_card_t *card, + struct pci_device *pci, + mychip_t *rchip) + { + mychip_t *chip; + int err; + static snd_device_ops_t ops = { + .dev_free = snd_mychip_dev_free, + }; + + *rchip = NULL; + + // check PCI availability here + // (see "PCI Resource Managements") + + // allocate a chip-specific data with magic-alloc + chip = snd_magic_kcalloc(mychip_t, 0, GFP_KERNEL); + if (chip == NULL) + return -ENOMEM; + + chip->card = card; + + // rest of initialization here; will be implemented + // later, see "PCI Resource Managements" + + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, + chip, &ops)) < 0) { + snd_mychip_free(chip); + return err; + } + *rchip = chip; + return 0; + } + + // constructor -- see "Constructor" sub-section + static int __devinit snd_mychip_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) + { + static int dev; + snd_card_t *card; + mychip_t *chip; + int err; + + // (1) + if (dev >= SNDRV_CARDS) + return -ENODEV; + if (!enable[dev]) { + dev++; + return -ENOENT; + } + + // (2) + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; + + // (3) + if ((err = snd_mychip_create(card, pci, &chip)) < 0) { + snd_card_free(card); + return err; + } + + // (4) + // implemented later + + // (5) + strcpy(card->driver, "My Chip"); + strcpy(card->shortname, "My Own Chip 123"); + sprintf(card->longname, "%s at 0x%lx irq %i", + card->shortname, chip->ioport, chip->irq); + + // (6) + if ((err = snd_card_register(card)) < 0) { + snd_card_free(card); + return err; + } + + // (7) + pci_set_drvdata(pci, chip); + dev++; + return 0; + } + + // destructor -- see "Destructor" sub-section + static void __devexit snd_mychip_remove(struct pci_dev *pci) + { + mychip_t *chip = snd_magic_cast(mychip_t, + pci_get_drvdata(pci), return); + if (chip) + snd_card_free(chip->card); + pci_set_drvdata(pci, NULL); + } +]]> + + + +
+ +
+ Constructor + + The real constructor of PCI drivers is probe callback. The + probe callback and other component-constructors which are called + from probe callback should be defined with + __devinit prefix. You + cannot use __init prefix for them, + because any PCI device could be a hotplug device. + + + + In the probe callback, the following scheme is often used. + + +
+ 1) Check and increment the device index. + + + += SNDRV_CARDS) + return -ENODEV; + if (!enable[dev]) { + dev++; + return -ENOENT; + } +]]> + + + + where enable[dev] is the module option. + + + + At each time probe callback is called, check the + availability of the device. If not available, simply increment + the device index and returns. dev will be incremented also + later (step + 7). + +
+ +
+ 2) Create a card instance + + + + + + + + + + The detail will be explained in the section + + Management of Cards and Components. + +
+ +
+ 3) Create a main component + + In this part, the PCI resources are allocated. + + + + + + + + The detail will be explained in the section PCI Resource + Managements. + +
+ +
+ 4) Create other components, such as mixer, MIDI, etc. + + Here you define the basic components such as + PCM, + mixer (e.g. AC97), + MIDI (e.g. MPU-401), + and other interfaces. + Also, if you want a proc + file, define it here, too. + +
+ +
+ 5) Set the driver ID and name strings. + + + +driver, "My Chip"); + strcpy(card->shortname, "My Own Chip 123"); + sprintf(card->longname, "%s at 0x%lx irq %i", + card->shortname, chip->ioport, chip->irq); +]]> + + + + The driver field holds the minimal ID string of the + chip. This is referred by alsa-lib's configurator, so keep it + simple but unique. + Even the same driver can have different driver IDs to + distinguish the functionality of each chip type. + + + + The shortname field is a string shown as more verbose + name. The longname field contains the information which is + shown in /proc/asound/cards. + +
+ +
+ 6) Register the card instance. + + + + + + + + + + Will be explained in the section Management + of Cards and Components, too. + +
+ +
+ 7) Set the PCI driver data and return zero. + + + + + + + + In the above, the chip record is stored. This pointer is + referred in the remove callback and power-management + callbacks, too. + If the card doesn't support the suspend/resume, you can store + the card pointer instead of the chip pointer, so that + snd_card_free can be called directly + without cast in the remove callback. But anyway, be sure + which pointer is used. + +
+
+ +
+ Destructor + + The destructor, remove callback, simply releases the card + instance. Then the ALSA middle layer will release all the + attached components automatically. + + + + It would be typically like the following: + + + +card); + pci_set_drvdata(pci, NULL); + } +]]> + + + + The above code assumes that the chip is allocated + with snd_magic stuff and + has the field to hold the card pointer (see the next + section). + +
+ +
+ Header Files + + For the above example, at least the following include files + are necessary. + + + + + #include + #include + #include + #include + #define SNDRV_GET_ID + #include +]]> + + + + where the last twos are necessary only when module options are + defined in the source file. If the codes are split to several + files, the file without module options don't need them. + + + + In addition to them, you'll need + <linux/interrupt.h> for the interrupt + handling, and <asm/io.h> for the i/o + access. If you use mdelay() or + udelay() functions, you'll need to include + <linux/delay.h>, too. + + + + The ALSA interfaces like PCM or control API are define in other + header files as <sound/xxx.h>. + They have to be included after + <sound/core.h>. + + +
+
+ + + + + + + Management of Cards and Components + +
+ Card Instance + + For each soundcard, a card record must be allocated. + + + + A card record is the headquarters of the soundcard. It manages + the list of whole devices (components) on the soundcard, such as + PCM, mixers, MIDI, synthesizer, and so on. Also, the card + record holds the ID and the name strings of the card, manages + the root of proc files, and controls the power-management states + and hotplug disconnections. The component list on the card + record is used to manage the proper releases of resources at + destruction. + + + + As mentioned above, to create a card instance, call + snd_card_new(). + + + + + + + + + + The function takes four arguments, the card-index number, the + id string, the module pointer (usually + THIS_MODULE), + and the size of extra-data space. The last argument is used to + allocate card->private_data for the + chip-specific data. Note that this data + is allocated by + snd_card_new(). + +
+ +
+ Components + + After the card is created, you can attach the components + (devices) to the card instance. On ALSA driver, a component is + represented as a snd_device_t object. + A component can be a PCM instance, a control interface, a raw + MIDI interface, etc. Each of such instances has one component + entry. + + + + A component can be created via + snd_device_new() function. + + + + + + + + + + This takes the card pointer, the device-level + (SNDRV_DEV_XXX), the data pointer, and the + callback pointers (&ops). The + device-level defines the type of components and the order of + registration and de-registration. For most of components, the + device-level is already defined. For a user-defined component, + you can use SNDRV_DEV_LOWLEVEL. + + + + This function itself doesn't allocate the data space. The data + must be allocated manually beforehand, and its pointer is passed + as the argument. This pointer is used as the identifier + (chip in the above example) for the + instance. + + + + Each ALSA pre-defined component such as ac97 or pcm calls + snd_device_new() inside its + constructor. The destructor for each component is defined in the + callback pointers. Hence, you don't need to take care of + calling a destructor for such a component. + + + + If you would like to create your own component, you need to + set the destructor function to dev_free callback in + ops, so that it can be released + automatically via snd_card_free(). The + example will be shown later as an implementation of a + chip-specific data. + +
+ +
+ Chip-Specific Data + + The chip-specific information, e.g. the i/o port address, its + resource pointer, or the irq number, is stored in the + chip-specific record. + Usually, the chip-specific record is typedef'ed as + xxx_t like the following: + + + + + + + + + + You might have objections against such a typedef, but this + typedef is necessary if you use a magic-cast + (explained later). + + + + In general, there are two ways to allocate the chip record. + + +
+ 1. Allocating via <function>snd_card_new()</function>. + + As mentioned above, you can pass the extra-data-length to the 4th argument of snd_card_new(), i.e. + + + + + + + + whether mychip_t is the type of the chip record. + + + + In return, the allocated record can be accessed as + + + +private_data; +]]> + + + + With this method, you don't have to allocate twice. But you + cannot use magic-cast for this record pointer, + instead. + +
+ +
+ 2. Allocating an extra device. + + + After allocating a card instance via + snd_card_new() (with + NULL on the 4th arg), call + snd_magic_kcalloc(). + + + + + + + + Once when the record is allocated via snd_magic stuff, you + can use magic-cast for the void pointer. + + + + The chip record should have the field to hold the card + pointer at least, + + + + + + + + + + Then, set the card pointer in the returned chip instance. + + + +card = card; +]]> + + + + + + Also, you need to define a magic-value for mychip_t. + + + + + + + (the detail will be described in the + + next subsection). + + + + Next, initialize the fields, and register this chip + record as a low-level device with a specified + ops, + + + + + + + + snd_mychip_dev_free() is the + device-destructor function, which will call the real + destructor. + + + + + +device_data, + return -ENXIO); + return snd_mychip_free(chip); + } +]]> + + + + where snd_mychip_free() is the real destructor. + +
+ +
+ Not a magic but a logic + + Now, you might have a question: What is the advantage of the + second method? Obviously, it looks far more complicated. + + As I wrote many times, the second method allows a + magic-cast for mychip_t. If you + have a void pointer (such as + pcm->private_data), the pointer type + is unknown at the compile time, and you cannot know even if a + wrong pointer type is passed. The compiler would accept + it. The magic-cast checks the pointer type at the runtime (and + whether it's a null pointer, too). Hence, the cast will be + much safer and good for debugging. + + + + As you have already seen, allocation with a magic-header can + be done via snd_magic_kmalloc() or + snd_magic_kcalloc(). + + + + + + + + The difference of these two functions is whether the area is + zero-cleared (kcalloc) or not + (kmalloc). + + + + The first argument of the allocator is the type of the + record. The magic-constant has to be defined for this type + beforehand. In this case, we'll need to define + mychip_t_magic, for example, as already + seen, + + + + + + + + The value is arbitrary but should be unique. + This is usually defined in + <include/sndmagic.h> or + <include/amagic.h> for alsa-driver tree, + but you may define it locally in the code at the early + development stage, since changing + sndmagic.h will lead to the recompilation + of the whole driver codes. + + + + The second argument is the extra-data length. It is usually + zero. The third argument is the flags to be passed to kernel + memory allocator, GFP_XXX. Normally, + GFP_KERNEL is passed. + + + + For casting a pointer, use + snd_magic_cast() macro: + + + + + + + + where source_pointer is the pointer to + be casted (e.g. pcm->private_data), and + action is the action to do if the cast + fails (e.g. return -EINVAL). + + + + For releasing the magic-allocated data, you need to call + snd_magic_kfree() function instead of + kfree(). + + + + + + + + + + If you call kfree() for the + magic-allocated value, it will lead to memory leaks. + When the ALSA drivers are compiled with + CONFIG_SND_DEBUG_MEMORY kernel config (or + configured with ), the + non-matching free will be checked and you'll see warning + messages. + + + + If you are 100% sure that your code is bug-free, you can + compile the driver without + CONFIG_SND_DEBUG_MEMORY kernel config, + so that the magic-allocator and the magic-cast will be + replaced to the normal kmalloc and cast. + +
+
+ +
+ Registration and Release + + After all components are assigned, register the card instance + by calling snd_card_register(). The access + to the device files are enabled at this point. That is, before + snd_card_register() is called, the + components are safely inaccessible from external side. If this + call fails, exit the probe function after releasing the card via + snd_card_free(). + + + + For releasing the card instance, you can call simply + snd_card_free(). As already mentioned, all + components are released automatically by this call. + + + + As further notes, the destructors (both + snd_mychip_dev_free and + snd_mychip_free) cannot be defined with + __devexit prefix, because they may be + called from the constructor, too, at the false path. + + + + For a device which allows hotplugging, you can use + snd_card_free_in_thread. This one will + postpone the destruction and wait in a kernel-thread until all + devices are closed. + + +
+ +
+ + + + + + + PCI Resource Managements + +
+ Full Code Example + + In this section, we'll finish the chip-specific constructor, + destructor and PCI entries. The example code is shown first, + below. + + + PCI Resource Managements Example + +res_port) { + release_resource(chip->res_port); + kfree_nocheck(chip->res_port); + } + // release the irq + if (chip->irq >= 0) + free_irq(chip->irq, (void *)chip); + // release the data + snd_magic_kfree(chip); + return 0; + } + + // chip-specific constructor + static int __devinit snd_mychip_create(snd_card_t *card, + struct pci_dev *pci, + mychip_t **rchip) + { + mychip_t *chip; + int err; + static snd_device_ops_t ops = { + .dev_free = snd_mychip_dev_free, + }; + + *rchip = NULL; + + // check PCI availability (28bit DMA) + if ((err = pci_enable_device(pci)) < 0) + return err; + if (!pci_dma_supported(pci, 0x0fffffff)) { + printk(KERN_ERR "error to set 28bit mask DMA\n"); + return -ENXIO; + } + pci_set_dma_mask(pci, 0x0fffffff); + + chip = snd_magic_kcalloc(mychip_t, 0, GFP_KERNEL); + if (chip == NULL) + return -ENOMEM; + + // initialize the stuff + chip->card = card; + chip->pci = pci; + chip->irq = -1; + + // (1) PCI resource allocation + chip->port = pci_resource_start(pci, 0); + if ((chip->res_port = request_region(chip->port, 8, + "My Chip")) == NULL) { + snd_mychip_free(chip); + printk(KERN_ERR "cannot allocate the port\n"); + return -EBUSY; + } + if (request_irq(pci->irq, snd_mychip_interrupt, + SA_INTERRUPT|SA_SHIRQ, "My Chip", + (void *)chip)) { + snd_mychip_free(chip); + printk(KERN_ERR "cannot grab irq\n"); + return -EBUSY; + } + chip->irq = pci->irq; + + // (2) initialization of the chip hardware + // (not implemented in this document) + + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, + chip, &ops)) < 0) { + snd_mychip_free(chip); + return err; + } + *rchip = chip; + return 0; + } + + // PCI IDs + static struct pci_device_id snd_mychip_ids[] __devinitdata = { + { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, + .... + { 0, } + }; + MODULE_DEVICE_TABLE(pci, snd_mychip_ids); + + // pci_driver definition + static struct pci_driver driver = { + .name = "My Own Chip", + .id_table = snd_mychip_ids, + .probe = snd_mychip_probe, + .remove = __devexit_p(snd_mychip_remove), + }; + + // initialization of the module + static int __init alsa_card_mychip_init(void) + { + int err; + + if ((err = pci_module_init(&driver)) < 0) { + #ifdef MODULE + printk(KERN_ERR "My chip soundcard not found " + "or device busy\n"); + #endif + return err; + } + return 0; + } + + // clean up the module + static void __exit alsa_card_mychip_exit(void) + { + pci_unregister_driver(&driver); + } + + module_init(alsa_card_mychip_init) + module_exit(alsa_card_mychip_exit) + + EXPORT_NO_SYMBOLS; /* for old kernels only */ +]]> + + + +
+ +
+ Some Hafta's + + The allocation of PCI resources is done in the + probe() function, and usually an extra + xxx_create() function is written for this + purpose. + + + + In the case of PCI devices, you have to call at first + pci_enable_device() function before + allocating resources. Also, you need to set the proper PCI DMA + mask to limit the accessed i/o range. In some cases, you might + need to call pci_set_master() function, + too. + + + + Suppose the 28bit mask, and the code to be added would be like: + + + + + + + +
+ +
+ Resource Allocation + + The allocation of ports and irqs are done via standard kernel + functions. Unlike ALSA ver.0.5.x., there are no helpers for + that. And these resources must be released in the destructor + function (see below). Also, on ALSA 0.9.x, you don't need + allocate (pseudo-)DMA for PCI like 0.5.x. + + + + Now assume that this PCI device has an I/O port with 8 bytes + and an interrupt. Then mychip_t will have the + following fields: + + + + + + + + + + For an i/o port (and also a memory region), you need to have + the resource pointer for the standard resource management. For + an irq, you have to keep only the irq number (integer). But you + need to initialize this number as -1 before actual allocation, + since irq 0 is valid. The port address and its resource pointer + can be initialized as null by + snd_magic_kcalloc() automatically, so you + don't have to take care of it. + + + + The allocation of an i/o port is done like this: + + + +port = pci_resource_start(pci, 0); + if ((chip->res_port = request_region(chip->port, 8, + "My Chip")) == NULL) { + printk(KERN_ERR "cannot allocate the port 0x%lx\n", + chip->port); + snd_mychip_free(chip); + return -EBUSY; + } +]]> + + + + + + It will reserve the i/o port region of 8 bytes of the given + PCI device. The returned value, chip->res_port, is allocated + via kmalloc() by + request_region(). The pointer must be + released via kfree(), but there is some + problem regarding this. This issue will be explained more below. + + + + The allocation of an interrupt source is done like this: + + + +irq, snd_mychip_interrupt, + SA_INTERRUPT|SA_SHIRQ, "My Chip", + (void *)chip)) { + snd_mychip_free(chip); + printk(KERN_ERR "cannot grab irq %d\n", pci->irq); + return -EBUSY; + } + chip->irq = pci->irq; +]]> + + + + where snd_mychip_interrupt() is the + interrupt handler defined later. + Note that chip->irq should be defined + only when request_irq() succeeded. + + + + On the PCI bus, the interrupts can be shared. Thus, + SA_SHIRQ is given as the interrupt flag of + request_irq(). + + + + The last argument of request_irq() is the + data pointer passed to the interrupt handler. Usually, the + chip-specific record is used for that, but you can use what you + like, too. + + + + I won't define the detail of the interrupt handler at this + point, but at least its appearance can be explained now. The + interrupt handler looks usually like the following: + + + + + + + + Again the magic-cast is used here to get the correct pointer + from the second argument. + + + + Now let's write the corresponding destructor for the resources + above. The role of destructor is simple: disable the hardware + (if already activated) and release the resources. So far, we + have no hardware part, so the disabling is not written here. + + + + For releasing the resources, check-and-release + method is a safer way. For the i/o port, do like this: + + + +res_port) { + release_resource(chip->res_port); + kfree_nocheck(chip->res_port); + } +]]> + + + + + + As you can see, the i/o resource pointer is also to be freed + via kfree_nocheck() after + release_resource() is called. You + cannot use kfree() here, because on ALSA, + kfree() may be a wrapper to its own + allocator with the memory debugging. Since the resource pointer + is allocated externally outside the ALSA, it must be released + via the native + kfree(). + kfree_nocheck() is used for that; it calls + the native kfree() without wrapper. + + + + For releasing the interrupt, do like this: + + + +irq >= 0) + free_irq(chip->irq, (void *)chip); +]]> + + + + And finally, release the chip-specific record. + + + + + + + + + + The chip instance is freed via + snd_magic_kfree(). Please use this function + for the object allocated by + snd_magic_kmalloc(). If you free it with + kfree(), it won't work properly and will + result in the memory leak. Also, again, remember that you cannot + set __devexit prefix for this destructor. + + + + We didn't implement the hardware-disabling part in the above. + If you need to do this, please note that the destructor may be + called even before the initialization of the chip is completed. + It would be better to have a flag to skip the hardware-disabling + if the hardware was not initialized yet. + + + + When the chip-data is assigned to the card using + snd_device_new() with + SNDRV_DEV_LOWLELVEL , its destructor is + called at the last. that is, it is assured that all other + components like PCMs and controls have been already released. + You don't have to call stopping PCMs, etc. explicitly, but just + stop the hardware in the low-level. + + + + The management of a memory-mapped region is almost as same as + the management of an i/o port. You'll need three fields like + the following: + + + + + + + + and the allocation would be (assuming its size is 512 bytes): + + + +iobase_phys = pci_resource_start(pci, 0); + chip->iobase_virt = (unsigned long) + ioremap_nocache(chip->iobase_phys, 512); + if ((chip->res_port = request_mem_region(chip->port, 512, + "My Chip")) == NULL) { + printk(KERN_ERR "cannot allocate the memory region\n"); + snd_mychip_free(chip); + return -EBUSY; + } +]]> + + + + and the corresponding destructor would be: + + + +iobase_virt) + iounmap((void *)chip->iobase_virt); + if (chip->res_iobase) { + release_resource(chip->res_iobase); + kfree_nocheck(chip->res_iobase); + } + .... + } +]]> + + + + +
+ +
+ PCI Entries + + So far, so good. Let's finish the rest of missing PCI + stuffs. At first, we need a + pci_device_id table for this + chipset. It's a table of PCI vendor/device ID number, and some + masks. + + + + For example, + + + + + + + + + + The first and second fields of + pci_device_id struct are the vendor and + device IDs. If you have nothing special to filter the matching + devices, you can use the rest of fields like above. The last + field of pci_device_id struct is a + private data for this entry. You can specify any value here, for + example, to tell the type of different operations per each + device IDs. Such an example is found in intel8x0 driver. + + + + The last entry of this list is the terminator. You must + specify this all-zero entry. + + + + Then, prepare the pci_driver record: + + + + + + + + + + The probe and + remove functions are what we already + defined in + the previous sections. The remove should + be defined with + __devexit_p() macro, so that it's not + defined for built-in (and non-hot-pluggable) case. The + name + field is the name string of this device. Note that you must not + use a slash / in this string. + + + + And at last, the module entries: + + + + + + + + + + Note that these module entries are tagged with + __init and + __exit prefixes, not + __devinit nor + __devexit. + + + + Oh, one thing was forgotten. If you have no exported symbols, + you need to declare it on 2.2 or 2.4 kernels (on 2.5 kernels + it's not necessary, though). + + + + + + + + That's all! + +
+
+ + + + + + + PCM Interface + +
+ General + + The PCM middle layer of ALSA is quite powerful and it is only + necessary for each driver to implement the low-level functions + to access its hardware. + + + + For accessing to the PCM layer, you need to include + <sound/pcm.h> above all. In addition, + <sound/pcm_params.h> might be needed + if you access to some functions related with hw_param. + + + + Each card device can have up to four pcm instances. A pcm + instance corresponds to a pcm device file. The limitation of + number of instances comes only from the available bit size of + the linux's device number. Once when 64bit device number is + used, we'll have more available pcm instances. + + + + A pcm instance consists of pcm playback and capture streams, + and each pcm stream consists of one or more pcm substreams. Some + soundcard supports the multiple-playback function. For example, + emu10k1 has a PCM playback of 32 stereo substreams. In this case, at + each open, a free substream is (usually) automatically chosen + and opened. Meanwhile, when only one substream exists and it was + already opened, the succeeding open will result in the blocking + or the error with EAGAIN according to the + file open mode. But you don't have to know the detail in your + driver. The PCM middle layer will take all such jobs. + +
+ +
+ Full Code Example + + The example code below does not include any hardware access + routines but shows only the skeleton, how to build up the PCM + interfaces. + + + PCM Example Code + + + .... + + #define chip_t mychip_t + .... + + /* hardware definition */ + static snd_pcm_hardware_t snd_mychip_playback_hw = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 32768, + .period_bytes_min = 4096, + .period_bytes_max = 32768, + .periods_min = 1, + .periods_max = 1024, + }; + + /* open callback */ + static int snd_mychip_pcm_open(snd_pcm_substream_t *subs) + { + mychip_t *chip = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + + runtime->hw = snd_mychip_playback_hw; + // more hardware-initialization will be done here + return 0; + } + + /* close callback */ + static int snd_mychip_pcm_close(snd_pcm_substream_t *substream) + { + mychip_t *chip = snd_pcm_substream_chip(substream); + // the hardware-specific codes will be here + return 0; + + } + + /* hw_params callback */ + static int snd_mychip_pcm_hw_params(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t * hw_params) + { + return snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); + } + + /* hw_free callback */ + static int snd_mychip_pcm_hw_free(snd_pcm_substream_t *substream) + { + return snd_pcm_lib_free_pages(substream); + } + + /* prepare callback */ + static int snd_mychip_pcm_prepare(snd_pcm_substream_t *substream) + { + mychip_t *chip = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + + // set up the hardware with the current configuration + // for example... + mychip_set_sample_format(chip, runtime->format); + mychip_set_sample_rate(chip, runtime->rate); + mychip_set_channels(chip, runtime->channels); + mychip_set_dma_setup(chip, runtime->dma_area, + chip->buffer_size, + chip->period_size); + return 0; + } + + /* trigger callback */ + static int snd_mychip_pcm_trigger(snd_pcm_substream_t *substream, + int cmd) + { + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + // do something to start the PCM engine + break; + case SNDRV_PCM_TRIGGER_STOP: + // do something to stop the PCM engine + break; + default: + return -EINVAL; + } + } + + /* pointer callback */ + static snd_pcm_uframes_t + snd_mychip_pcm_pointer(snd_pcm_substream_t *substream) + { + mychip_t *chip = snd_pcm_substream_chip(substream); + unsigned int current_ptr; + + // get the current hardware pointer + current_ptr = mychip_get_hw_pointer(chip); + return current_ptr; + } + + /* operators */ + static snd_pcm_ops_t snd_mychip_playback_ops = { + .open = snd_mychip_playback_open, + .close = snd_mychip_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_mychip_pcm_hw_params, + .hw_free = snd_mychip_pcm_hw_free, + .prepare = snd_mychip_pcm_prepare, + .trigger = snd_mychip_pcm_trigger, + .pointer = snd_mychip_pcm_pointer, + }; + + /* + * definitions of capture are omitted here... + */ + + /* create a pcm device */ + static int __devinit snd_mychip_new_pcm(mychip_t *chip) + { + snd_pcm_t *pcm; + int err; + + if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1, + &pcm)) < 0) + return err; + pcm->private_data = chip; + strcpy(pcm->name, "My Chip"); + chip->pcm = pcm; + /* set operators */ + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_mychip_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_mychip_capture_ops); + /* pre-allocation of buffers */ + snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, + 64*1024, 64*1024); + return 0; + } +]]> + + + +
+ +
+ Constructor + + A pcm instance is allocated snd_pcm_new() + function. It would be better to create a constructor for pcm, + namely, + + + +card, "My Chip", 0, 1, 1, + &pcm)) < 0) + return err; + pcm->private_data = chip; + strcpy(pcm->name, "My Chip"); + chip->pcm = pcm; + .... + return 0; + } +]]> + + + + + + The snd_pcm_new() function takes the four + arguments. The first argument is the card pointer to which this + pcm is assigned, and the second is the ID string. + + + + The third argument (index, 0 in the + above) is the index of this new pcm. It begins from zero. When + you will create more than one pcm instances, specify the + different numbers in this argument. For example, + index = 1 for the second PCM device. + + + + The fourth and fifth arguments are the number of substreams + for playback and capture, respectively. Here both 1 are given in + the above example. When no playback or no capture is available, + pass 0 to the corresponding argument. + + + + If a chip supports multiple playbacks or captures, you can + specify more numbers, but they must be handled properly in + open/close, etc. callbacks. When you need to know which + substream you are referring to, then it can be obtained from + snd_pcm_substream_t data passed to each callback + as follows: + + + +number; +]]> + + + + + + After the pcm is created, you need to set operators for each + pcm stream. + + + + + + + + + + The operators are defined typically like this: + + + + + + + + Each of callbacks is explained in the subsection + + Operators. + + + + After setting the operators, most likely you'd like to + pre-allocate the buffer. For the pre-allocation, simply call + the following: + + + +pci, pcm, + 64*1024, 64*1024); +]]> + + + + It will allocate up to 64kB buffer as default. The details of + buffer management will be described in the later section Buffer and Memory + Management. + + + + Additionally, you can set some extra information for this pcm + in pcm->info_flags. + The available values are defined as + SNDRV_PCM_INFO_XXX in + <sound/asound.h>, which is used for + the hardware definition (described later). When your soundchip + supports only half-duplex, specify like this: + + + +info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; +]]> + + + +
+ +
+ ... And the Destructor? + + The destructor for a pcm instance is not always + necessary. Since the pcm device will be released by the middle + layer code automatically, you don't have to call destructor + explicitly. + + + + The destructor would be necessary when you created some + special records internally and need to release them. In such a + case, set the destructor function to + pcm->private_free: + + + PCM Instance with a Destructor + +private_data, return); + // free your own data + kfree(chip->my_private_pcm_data); + // do what you like else... + } + + static int __devinit snd_mychip_new_pcm(mychip_t *chip) + { + snd_pcm_t *pcm; + .... + // allocate your own data + chip->my_private_pcm_data = kmalloc(...); + // set the destructor + pcm->private_data = chip; + pcm->private_free = mychip_pcm_free; + .... + } +]]> + + + +
+ +
+ Operators + + OK, now let me explain the detail of each pcm callback + (ops). In general, every callback must + return 0 if successful, or a negative number with the error + number such as -EINVAL at any + error. + + + + The callback function takes at least the argument with + snd_pcm_substream_t pointer. For retrieving the + chip record from the given substream instance, you can use the + following macro. + + + + + + + + + + It's expanded with a magic-cast, so the cast-error is + automatically checked. You should define chip_t at + the beginning of the code, since this will be referred in many + places of pcm and control interfaces. + + +
+ open callback + + + + + + + + This is called when a pcm substream is opened. + + + + At least, here you have to initialize the runtime hardware + record. Typically, this is done by like this: + + + +runtime; + + runtime->hw = snd_mychip_playback_hw; + return 0; + } +]]> + + + + where snd_mychip_playback_hw is the + pre-defined hardware record. + + + + + + + + + + The similar struct exists on ALSA 0.5.x driver, so you can + guess the values if you already wrote a driver. + + + + The info field contains the type and + capabilities of this pcm. The bit flags are defined in + <sound/asound.h> as + SNDRV_PCM_INFO_XXX. Here, at least, you + have to specify whether the mmap is supported and which + interleaved format is supported. + When the mmap is supported, add + SNDRV_PCM_INFO_MMAP flag here. When the + hardware supports the interleaved or the non-interleaved + format, SNDRV_PCM_INFO_INTERLEAVED or + SNDRV_PCM_INFO_NONINTERLEAVED flag must + be set, respectively. If both are supported, you can set both, + too. + + + + In the above example, MMAP_VALID and + BLOCK_TRANSFER are specified for OSS mmap + mode. Usually both are set. Of course, + MMAP_VALID is set only if the mmap is + really supported. + + + + The other possible flags are + SNDRV_PCM_INFO_PAUSE and + SNDRV_PCM_INFO_RESUME. The + PAUSE bit means that the pcm supports the + pause operation, while the + RESUME bit means that the pcm supports + the suspend/resume operation. If these flags + are set, the trigger callback below + must handle the corresponding commands. + + + + formats field contains the bit-flags + of supported formats (SNDRV_PCM_FMTBIT_XXX). + If the hardware supports more than one format, give all or'ed + bits. In the example above, the signed 16bit little-endian + format is specified. + + + + rates field contains the bit-flags of + supported rates (SNDRV_PCM_RATE_XXX). + When the chip supports continuous rates, pass + CONTINUOUS bit additionally. + The pre-defined rate bits are only for typical rates. If your + chip supports unconventional rates, you need to add + KNOT bit and set up the + constraint manually (explained later). + + + + There have been many changes of terminology between + ALSA 0.5.x and 0.9.x. + On the ALSA 0.9.x world, period means what is + known as fragment in the OSS. It's the least + size of (a part of) the buffer to generate an interrupt. + + + + Now, taking the new terminology into account, the other fields + are self-explanatory (I hope). Please note that here, both + min/max buffer and period sizes are specified in bytes. + + + + Some drivers allocate the private instance for each pcm + substream. It can be stored in + substream->runtime->private_data. + Since it's a void pointer, you + should use magic-kmalloc and magic-cast for such an object. + + + +runtime->private_data = data; + .... + } +]]> + + + + + + The allocated object must be released in the close callback below. + +
+ +
+ close callback + + + + + + + + Obviously, this is called when a pcm substream is closed. + + + + Any private instance for a pcm substream allocated in the + open callback will be released here. + + + +runtime->private_data); + .... + } +]]> + + + +
+ +
+ ioctl callback + + This is used for any special action to pcm ioctls. But + usually you can pass a generic ioctl callback, + snd_pcm_lib_ioctl. + +
+ +
+ hw_params callback + + + + + + + + This and hw_free callbacks exist + only on ALSA 0.9.x. + + + + This is called when the hardware parameter + (hw_params) is set + up by the application, + that is, once when the buffer size, the period size, the + format, etc. are defined for the pcm substream. + + + + Many hardware set-up should be done in this callback, + including the allocation of buffers. + + + + Parameters to be initialized are retrieved by + params_xxx() macros. For allocating a + buffer, you can call a helper function, + + + + + + + + snd_pcm_lib_malloc_pages() is available + only when the DMA buffers have been pre-allocated. + See the section + Buffer Types for more details. + + + + Note that this and prepare callbacks + may be called multiple times per initialization. + For example, the OSS emulation may + call these callbacks at each change via its ioctl. + + + + Thus, you need to take care not to allocate the same buffers + many times, which will lead to memory leak! Calling the + helper function above many times is OK. It will release the + previous buffer automatically when it was already allocated. + + + + Another note is that this callback is non-atomic + (schedulable). This is important, because the + prepare callback + is atomic (non-schedulable). That is, mutex or any + schedule-related functions are available only in + hw_params callback. + Please see the subsection + + Atomicity for details. + +
+ +
+ hw_free callback + + + + + + + + + + This is called to release the resources allocated via + hw_params. For example, releasing the + buffer via + snd_pcm_lib_malloc_pages() is done by + calling the following: + + + + + + + + + + This callback may be called multiple times, too. + Keep track whether the resource was already released. + +
+ +
+ prepare callback + + + + + + + + + + This callback is called when the pcm is + prepared. You can set the format type, sample + rate, etc. here. The difference from + hw_params is that the + prepare callback will be called at each + time + snd_pcm_prepare() is called, i.e. when + recovered after underruns, etc. + + + + As mentioned above, this callback is atomic. + + + + In this and the following callbacks, you can refer to the + values via the runtime record, + substream->runtime. + For example, to get the current + rate, format or channels, access to + runtime->rate, + runtime->format or + runtime->channels, respectively. + The physical address of the allocated buffer is set to + runtime->dma_area. The buffer and period sizes are + in runtime->buffer_size and runtime->period_size, + respectively. + + + + Note that the period and the buffer sizes are stored in + frames. In the ALSA world, 1 frame = channels + * samples-size. For conversion between frames and bytes, you + can use the helper functions, + frames_to_bytes() and + bytes_to_frames(). + + + +period_size); +]]> + + + + + + Be careful that this callback will be called many times at + each set up, too. + +
+ +
+ trigger callback + + + + + + + + This is called when the pcm is started, stopped or paused. + + + + Which action is specified in the second argument, + SNDRV_PCM_TRIGGER_XXX in + <sound/pcm.h>. At least, + START and STOP + commands must be defined in this callback. + + + + + + + + + + When the pcm supports the pause operation (given in info + field of the hardware table), PAUSE_PUSE + and PAUSE_RELEASE commands must be + handled here, too. The former is the command to pause the pcm, + and the latter to restart the pcm again. + + + + When the pcm supports the suspend/resume operation, + SUSPEND and RESUME + commands must be handled, too. Obviously it does suspend and + resume of the pcm substream. Usually, the + SUSPEND is identical with + STOP command and the + RESUME is identical with + START command. + + + + This callback is also atomic. + +
+ +
+ pointer callback + + + + + + + + This callback is called when the PCM middle layer inquires + the current hardware position on the buffer. The position must + be returned in frames (which was in bytes on ALSA 0.5.x), + ranged from 0 to buffer_size - 1. + + + + This is called usually from the buffer-update routine in the + pcm middle layer, which is invoked when + snd_pcm_period_elapsed() is called in the + interrupt routine. Then the pcm middle layer updates the + position and calculates the available space, and wakes up the + sleeping poll threads, etc. + + + + This callback is also atomic. + +
+ +
+ copy and silence callbacks + + These callbacks are not mandatory, and can be omitted in + most cases. These callbacks are used when the hardware buffer + cannot be on the normal memory space. Some chips have their + own buffer on the hardware which is not mappable. In such a + case, you have to transfer the data manually from the memory + buffer to the hardware buffer. Or, if the buffer is + non-contiguous on both physical and virtual memory spaces, + these callbacks must be defined, too. + + + + If these two callbacks are defined, copy and set-silence + operations are done by them. The detailed will be described in + the later section Buffer and Memory + Management. + +
+ +
+ page callback + + + This callback is also not mandatory. This callback is used + mainly for the non-contiguous buffer. The mmap calls this + callback to get the page address. Some examples will be + explained in the later section Buffer and Memory + Management, too. + +
+
+ +
+ Interrupt Handler + + The rest of pcm stuff is the PCM interrupt handler. The + role of PCM interrupt handler in the sound driver is to update + the buffer position and to tell the PCM middle layer when the + buffer position goes across the prescribed period size. To + inform this, call snd_pcm_period_elapsed() + function. + + + + There are several types of sound chips to generate the interrupts. + + +
+ Interrupts at the period (fragment) boundary + + This is the most frequently found type: the hardware + generates an interrupt at each period boundary. + In this case, you can call + snd_pcm_period_elapsed() at each + interrupt. + + + + snd_pcm_period_elapsed() takes the + substream pointer as its argument. Thus, you need to keep the + substream pointer accessible from the chip instance. For + example, define substream field in the chip record to hold the + current running substream pointer, and set the pointer value + at open callback (and reset at close callback). + + + + If you aquire a spinlock in the interrupt handler, and the + lock is used in other pcm callbacks, too, then you have to + release the lock before calling + snd_pcm_period_elapsed(), because + snd_pcm_period_elapsed() calls other pcm + callbacks inside. + + + + A typical coding would be like: + + + Interrupt Handler Case #1 + +lock); + .... + if (pcm_irq_invoked(chip)) { + // call updater, unlock before it + spin_unlock(&chip->lock); + snd_pcm_period_elapsed(chip->substream); + spin_lock(&chip->lock); + } + .... + spin_unlock(&chip->lock); + } +]]> + + + +
+ +
+ High-frequent timer interrupts + + This is the case when the hardware doesn't generate interrupts + at the period boundary but do timer-interrupts at the fixed + timer rate (e.g. es1968 or ymfpci drivers). + In this case, you need to check the current hardware + position and accumulates the processed sample length at each + interrupt. When the accumulated size overcomes the period + size, call + snd_pcm_period_elapsed() and reset the + accumulator. + + + + A typical coding would be like the following. + + + Interrupt Handler Case #2 + +lock); + .... + if (pcm_irq_invoked(chip)) { + unsigned int last_ptr, size; + // get the current hardware pointer (in frames) + last_ptr = get_hw_ptr(chip); + // calculate the processed frames since the + // last update + if (last_ptr < chip->last_ptr) + size = runtime->buffer_size + last_ptr + - chip->last_ptr; + else + size = last_ptr - chip->last_ptr; + // remember the last updated point + chip->last_ptr = last_ptr; + // accumulate the size + chip->size += size; + // over the period boundary? + if (chip->size >= runtime->period_size) { + // reset the accumulator + chip->size %= runtime->period_size; + // call updater + spin_unlock(&chip->lock); + snd_pcm_period_elapsed(substream); + spin_lock(&chip->lock); + } + } + .... + spin_unlock(&chip->lock); + } +]]> + + + +
+ +
+ On calling <function>snd_pcm_period_elapsed()</function> + + In both cases, even if more than one period are elapsed, you + don't have to call + snd_pcm_period_elapsed() many times. Call + only once. And the pcm layer will check the current hardware + pointer and update to the latest status. + +
+
+ +
+ Atomicity + + One of the most important (and thus difficult to debug) problem + on the kernel programming is the race condition. + On linux kernel, usually it's solved via spin-locks or + semaphores. In general, if the race condition may + happen in the interrupt handler, it's handled as atomic, and you + have to use spinlock for protecting the critical session. If it + never happens in the interrupt and it may take relatively long + time, you should use semaphore. + + + + As already seen, some pcm callbacks are atomic and some are + not. For example, hw_params callback is + non-atomic, while prepare callback is + atomic. This means, the latter is called already in a spinlock + held by the PCM middle layer. Please take this atomicity into + account when you use a spinlock or a semaphore in the callbacks. + + + + In the atomic callbacks, you cannot use functions which may call + schedule or go to + sleep. The semaphore and mutex do sleep, + and hence they cannot be used inside the atomic callbacks + (e.g. prepare callback). + For taking a certain delay in such a callback, please use + udelay() or mdelay(). + + + + This atomicity problem appears also in the initialization of the + hardware when the power-management is supported. The functions + for suspending and resuming the chip must be atomic, i.e. no + mutex nor sleep can be used in them. + + +
+
+ Constraints + + If your chip supports unconventional sample rates, or only the + limited samples, you need to set a constraint for the + condition. + + + + For example, in order to restrict the sample rates in the some + supported values, use + snd_pcm_hw_constraint_list(). + You need to call this function in the open callback. + + + Example of Hardware Constraints + +runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_rates); + if (err < 0) + return err; + .... + } +]]> + + + + + + There are many different constraints. You can even define your + own constraint rules. I won't explain the details here, rather I + would like to say, Luke, use the source. + +
+ +
+ + + + + + + Control Interface + +
+ General + + The control interface is used widely for many switches, + sliders, etc. which are accessed from the user-space. Its most + important use is the mixer interface. In other words, on ALSA + 0.9.x, all the mixer stuff is implemented on the control kernel + API (while there was an independent mixer kernel API on 0.5.x). + + + + ALSA has a well-defined AC97 control module. If your chip + supports only the AC97 and nothing else, you can skip this + section. + + + + The control API is defined in + <sound/control.h>. + Include this file if you add your own controls. + +
+ +
+ Definition of Controls + + For creating a new control, you need to define the three + callbacks: info, + get and + put. Then, define a + snd_kcontrol_new_t record, such as: + + + Definition of a Control + + + + + + + + Most likely the control is created via + snd_ctl_new1(), and in such a case, you can + add __devinitdata prefix to the + definition like above. + + + + The iface field specifies the type of + the control, + SNDRV_CTL_ELEM_IFACE_XXX. There are + MIXER, PCM, + CARD, etc. + + + + The name is the name identifier + string. On ALSA 0.9.x, the control name is very important, + because its role is classified from its name. There are + pre-defined standard control names. The details are described in + the subsection + + Control Names. + + + + The index field holds the index number + of this control. If there are several different controls with + the same name, they can be distinguished by the index + number. This is the case when + several codecs exist on the card. If the index is zero, you can + omit the definition above. + + + + The access field contains the access + type of this control. Give the combination of bit masks, + SNDRV_CTL_ELEM_ACCESS_XXX, there. + The detailed will be explained in the subsection + + Access Flags. + + + + The private_values field contains + an arbitrary long integer value for this record. When using + generic info, + get and + put callbacks, you can pass a value + through this field. If several small numbers are necessary, you can + combine them in bitwise. Or, it's possible to give a pointer + (casted to unsigned long) of some record to this field, too. + + + + The other three are + + callback functions. + +
+ +
+ Control Names + + There are some standards for defining the control names. A + control is usually defined from the three parts as + SOURCE DIRECTION FUNCTION. + + + + The first, SOURCE, specifies the source + of the control, and is a string such as Master, + PCM, CD or + Line. There are many pre-defined sources. + + + + The second, DIRECTION, is one of the + following strings according to the direction of the control: + Playback, Capture, Bypass + Playback and Bypass Capture. Or, it can + be omitted, meaning both playback and capture directions. + + + + The third, FUNCTION, is one of the + following strings according to the function of the control: + Switch, Volume and + Route. + + + + The example of control names are, thus, Master Capture + Switch or PCM Playback Volume. + + + + There are some exceptions: + + +
+ Global capture and playback + + Capture Source, Capture Switch + and Capture Volume are used for the global + capture (input) source, switch and volume. Similarly, + Playback Switch and Playback + Volume are used for the global output gain switch and + volume. + +
+ +
+ Tone-controls + + tone-control switch and volumes are specified like + Tone Control - XXX, e.g. Tone Control - + Switch, Tone Control - Bass, + Tone Control - Center. + +
+ +
+ 3D controls + + 3D-control switches and volumes are specified like 3D + Control - XXX, e.g. 3D Control - + Switch, 3D Control - Center, 3D + Control - Space. + +
+ +
+ Mic boost + + Mic-boost switch is set as Mic Boost or + Mic Boost (6dB). + + + + More precise information can be found in + alsa-kernel/Documentation/ControlNames.txt. + +
+
+ +
+ Access Flags + + + The access flag is the bit-flags which specifies the access type + of the given control. The default access type is + SNDRV_CTL_ELEM_ACCESS_READWRITE, + which means both read and write are allowed to this control. + When the access flag is omitted (i.e. = 0), it is + regarded as READWRITE access as default. + + + + When the control is read-only, pass + SNDRV_CTL_ELEM_ACCESS_READ instead. + In this case, you don't have to define + put callback. + Similarly, when the control is write-only (although it's a rare + case), you can use WRITE flag instead, and + you don't need get callback. + + + + If the control value changes frequently (e.g. the VU meter), + VOLATILE flag should be given. This means + that the control may be changed without + + notification. Applications should poll such + a control constantly. + + + + When the control is inactive, set + INACTIVE flag, too. + There are LOCK and + OWNER flags for changing the write + permissions. + + +
+ +
+ Callbacks + +
+ info callback + + The info callback is used to get + the detailed information of this control. This must store the + values of the given snd_ctl_elem_info_t + object. For example, for a boolean control with a single + element will be: + + + Example of info callback + +type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; + } +]]> + + + + + + The type field specifies the type + of the control. There are BOOLEAN, + INTEGER, ENUMERATED, + BYTES, IEC958 and + INTEGER64. The + count field specifies the + number of elements in this control. For example, a stereo + volume would have count = 2. The + value field is a union, and + the values stored are depending on the type. The boolean and + integer are identical. + + + + The enumerated type is a bit different from others. You'll + need to set the string for the currently given item index. + + + +value.enumerated.items = 4; + if (uinfo->value.enumerated.item > 3) + uinfo->value.enumerated.item = 3; + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); +]]> + + + +
+ +
+ get callback + + + This callback is used to read the current value of the + control and to return to the user-space. + + + + For example, + + + Example of get callback + +value.integer.value[0] = get_some_value(chip); + return 0; + } +]]> + + + + + + Here, the chip instance is retrieved via + snd_kcontrol_chip() macro. This macro + converts from kcontrol->private_data to the type defined by + chip_t. The + kcontrol->private_data field is + given as the argument of snd_ctl_new() + (see the later subsection + Constructor). + + + + The value field is depending on + the type of control as well as on info callback. For example, + the sb driver uses this field to store the register offset, + the bit-shift and the bit-mask. The + private_value is set like + + + + + + and is retrieved in callbacks like + + +private_value & 0xff; + int shift = (kcontrol->private_value >> 16) & 0xff; + int mask = (kcontrol->private_value >> 24) & 0xff; + .... + } +]]> + + + + + + In get callback, you have to fill all the elements if the + control has more than one elements, + i.e. count > 1. + In the example above, we filled only one element + (value.integer.value[0]) since it's + assumed as count = 1. + +
+ +
+ put callback + + + This callback is used to write a value from the user-space. + + + + For example, + + + Example of put callback + +current_value != + ucontrol->value.integer.value[0]) { + change_current_value(chip, + ucontrol->value.integer.value[0]); + changed = 1; + } + return changed; + } +]]> + + + + As seen above, you have to return 1 if the value is + changed. If the value is not changed, return 0 instead. + If any fatal error happens, return a negative error code as + usual. + + + + Like get callback, + when the control has more than one elements, + all elemehts must be evaluated in this callback, too. + +
+ +
+ Callbacks are not atomic + + All these three callbacks are basically not atomic. + +
+
+ +
+ Constructor + + When everything is ready, finally we can create a new + control. For creating a control, there are two functions to be + called, snd_ctl_new1() and + snd_ctl_add(). + + + + In the simplest way, you can do like this: + + + + + + + + where my_control is the + snd_kcontrol_new_t object defined above, and chip + is the object pointer to be passed to + kcontrol->private_data + which can be referred in callbacks. + + + + snd_ctl_new1() allocates a new + snd_kcontrol_t instance (that's why the definition + of my_control can be with + __devinitdata + prefix), and snd_ctl_add assigns the given + control component to the card. + +
+ +
+ Change Notification + + If you need to change and update a control in the interrupt + routine, you can call snd_ctl_notify(). For + example, + + + + + + + + This function takes the card pointer, the event-mask, and the + control id pointer for the notification. The event-mask + specifies the types of notification, for example, in the above + example, the change of control values is notified. + The id pointer is the pointer of snd_ctl_elem_id_t + to be notified. + You can find some examples in es1938.c or + es1968.c for hardware volume interrupts. + +
+ +
+ + + + + + + API for AC97 Codec + +
+ General + + The ALSA AC97 codec layer is a well-defined one, and you don't + have to write many codes to control it. Only low-level control + routines are necessary. The AC97 codec API is defined in + <sound/ac97_codec.h>. + +
+ +
+ Full Code Example + + + Example of AC97 Interface + +private_data, return 0); + .... + // read a register value here from the codec + return the_register_value; + } + + static void snd_mychip_ac97_write(ac97_t *ac97, + unsigned short reg, unsigned short val) + { + mychip_t *chip = snd_magic_cast(mychip_t, + ac97->private_data, return 0); + .... + // write the given register value to the codec + } + + static int snd_mychip_ac97(mychip_t *chip) + { + ac97_t ac97; + + memset(&ac97, 0, sizeof(ac97)); + ac97.write = snd_mychip_ac97_write; + ac97.read = snd_mychip_ac97_read; + ac97.private_data = chip; + return snd_ac97_mixer(card, &ac97, &chip->ac97); + } + +]]> + + + +
+ +
+ Constructor + + For creating an ac97 instance, call + snd_ac97_mixer() with an ac97_t + record, in which the callbacks and the private_data is set. + + + +ac97); +]]> + + + + where chip->ac97 is the pointer of a newly created + ac97_t instance. + This instance is not necessarily stored in the chip + record. When you need to change the register values from the + driver, or need the suspend/resume of ac97 codecs, keep this + pointer to pass to the corresponding functions. + +
+ +
+ Callbacks + + The standard callbacks are read and + write. Obviously they + correspond to the functions for read and write accesses to the + hardware low-level codes. + + + + The read callback returns the + register value specified in the argument. + + + +private_data, return 0); + .... + return the_register_value; + } +]]> + + + + Here, the chip can be cast from ac97->private_data. + + + + Meanwhile, the write callback is + used to set the register value. + + + + + + + + + + These callbacks are non-atomic like the callbacks of control API + unless they are called during suspend/resume phase. + + + + There are also other callbacks: + reset, + wait and + init. + + + + The reset callback is used to reset + the codec. If the chip requires a special way of reset, you can + define this callback. + This callback must be atomic when it's called in the suspend + mode. + + + + The wait callback is used for a + certain wait at the standard initialization of the codec. If the + chip requires the extra wait-time, define this callback. + This callback is always non-atomic, because it's never called + in the resume mode. + + + + The init callback is used for + additional initialization of the codec. This callback is called + after the reset, and should be atomic in the resume mode. + +
+ +
+ Updating Registers in The Driver + + If you need to access to the codec from the driver, you can + call the following functions: + snd_ac97_write(), + snd_ac97_read(), + snd_ac97_update() and + snd_ac97_update_bits(). + + + + Both snd_ac97_write() and + snd_ac97_update() functions are used to + set a value to the given register + (AC97_XXX). The different between them is + that snd_ac97_update() doesn't write a + value if the given value has been already set, while + snd_ac97_write() always rewrites the + value. + + + + + + + + + + snd_ac97_read() is used to read the value + of the given register. For example, + + + + + + + + + + snd_ac97_update_bits() is used to update + some bits of the given register. + + + + + + + + + + Also, there is a function to change the sample rate (of a + certain register such as + AC97_PCM_FRONT_DAC_RATE) when VRA is + supported by the codec: + snd_ac97_set_rate(). + + + + + + + + + + The following registers are available for setting the rate: + AC97_PCM_MIC_ADC_RATE, + AC97_PCM_FRONT_DAC_RATE, + AC97_PCM_LR_ADC_RATE, + AC97_SPDIF. When the + AC97_SPDIF is specified, the register is + not really changed but the corresponding IEC958 status bits will + be updated. + +
+ +
+ Clock Adjustment + + On some chip, the clock of the codec isn't 48000 but using a + PCI clock (to save a quartz!). In this case, change the field + ac97->clock to the corresponding + value. For example, intel8x0 + and es1968 drivers have the auto-measurement function of the + clock. + +
+ +
+ Proc Files + + The ALSA AC97 interface will create a proc file such as + /proc/asound/card0/ac97#0 and + ac97#0regs. You can refer to these files to + see the current status and registers of the codec. + +
+ +
+ Multiple Codecs + + When there are several codecs on the same card, you need to + call snd_ac97_new() multiple times with + ac97.num=1 or greater. The num field + specifies the codec + number. + + + + If you have set up multiple codecs, you need to either write + different callbacks for each codec or check + ac97->num in the + callback routines. + +
+ +
+ + + + + + + MIDI (MPU401-UART) Interface + +
+ General + + Many soundcards have built-in MIDI (MPU401-UART) + interfaces. When the soundcard supports the standard MPU401-UART + interface, most likely you can use the ALSA MPU401-UART API. The + MPU401-UART API is defined in + <sound/mpu401.h>. + + + + Some soundchips have similar but a little bit different + implementation of mpu401 stuff. For example, emu10k1 has its own + mpu401 routines. + + + + In this document, I won't explain the rawmidi interface API, + which is the basis of MPU401-UART implementation. + + + + For details, please check the source, + core/rawmidi.c, and examples such as + drivers/mpu401/mpu401_uart.c or + usb/usbmidi.c. + +
+ +
+ Constructor + + For creating a rawmidi object, call + snd_mpu401_uart_new(). + + + + + + + + + + The first argument is the card pointer, and the second is the + index of this component. You can create up to 8 rawmidi + devices. + + + + The third argument is the type of the hardware, + MPU401_HW_XXX. If it's not a special one, + you can use MPU401_HW_MPU401. + + + + The 4th argument is the i/o port address. Many + backward-compatible MPU401 has an i/o port such as 0x330. Or, it + might be a part of its own PCI i/o region. It depends on the + chip design. + + + + When the i/o port address above is a part of the PCI i/o + region, the MPU401 i/o port might have been already allocated + (reserved) by the driver itself. In such a case, pass non-zero + to the 5th argument + (integrated). Otherwise, pass 0 to it, + and + the mpu401-uart layer will allocate the i/o ports by itself. + + + + Usually, the port address corresponds to the command port and + port + 1 corresponds to the data port. If not, you may change + the cport field of + mpu401_t manually + afterward. However, mpu401_t pointer is not + returned explicitly by + snd_mpu401_uart_new(). You need to cast + rmidi->private_data to + mpu401_t explicitly, + + + +private_data, ); +]]> + + + + and reset the cport as you like: + + + +cport = my_own_control_port; +]]> + + + + + + The 6th argument specifies the irq number for UART. If the irq + is already allocated, pass 0 to the 7th argument + (irq_flags). Otherwise, pass the flags + for irq allocation + (SA_XXX bits) to it, and the irq will be + reserved by the mpu401-uart layer. If the card doesn't generates + UART interrupts, pass -1 as the irq number. Then a timer + interrupt will be invoked for polling. + +
+ +
+ Interrupt Handler + + When the interrupt is allocated in + snd_mpu401_uart_new(), the private + interrupt handler is used, hence you don't have to do nothing + else than creating the mpu401 stuff. Otherwise, you have to call + snd_mpu401_uart_interrupt() explicitly when + a UART interrupt is invoked and checked in your own interrupt + handler. + + + + In this case, you need to pass the private_data of the + returned rawmidi object from + snd_mpu401_uart_new() as the second + argument of snd_mpu401_uart_interrupt(). + + + +private_data, regs); +]]> + + + +
+ +
+ + + + + + + Miscellaneous Devices + +
+ FM OPL3 + + The FM OPL3 is still used on many chips (mainly for backward + compatibility). ALSA has a nice OPL3 FM control layer, too. The + OPL3 API is defined in + <sound/opl3.h>. + + + + FM registers can be directly accessed through direct-FM API, + defined in <sound/asound_fm.h>. In + ALSA native mode, FM registers are accessed through + Hardware-Dependant Device direct-FM extension API, whereas in + OSS compatible mode, FM registers can be accessed with OSS + direct-FM compatible API on /dev/dmfmX device. + + + + For creating the OPL3 component, you have two functions to + call. The first one is a constructor for opl3_t + instance. + + + + + + + + + + The first argument is the card pointer, the second one is the + left port address, and the third is the right port address. In + most cases, the right port is placed at the left port + 2. + + + + The fourth argument is the hardware type. + + + + When the left and right ports have been already allocated by + the card driver, pass non-zero to the fifth argument + (integrated). Otherwise, opl3 module will + allocate the specified ports by itself. + + + + If this function returns successfully with 0, then create a + hwdep device for this opl3. + + + + + + + + + + The first argument is the opl3_t instance you + created, and the second is the index number, usually 0. + + + + The third argument is the index-offset for the sequencer + client assigned to the OPL3 port. When there is an MPU401-UART, + give 1 for here (UART always takes 0). + +
+ +
+ Hardware-Dependent Devices + + Some chips need the access from the user-space for special + controls or for loading the micro code. In such a case, you can + create a hwdep (hardware-dependent) device. The hwdep API is + defined in <sound/hwdep.h>. You can + find examples in opl3 driver or + isa/sb/sb16_csp.c. + + + + Creation of the hwdep instance is done via + snd_hwdep_new(). + + + + + + + + where the third argument is the index number. + + + + You can then pass any pointer value to the + private_data. Again, it should be a + magic-allocated record, so that the cast can be checked more + safely. If you assign a private data, you should define the + destructor, too. The destructor function is set to + private_free field. + + + +private_data = p; + hw->private_free = mydata_free; +]]> + + + + and the implementation of destructor would be: + + + +private_data, return); + snd_magic_kfree(p); + } +]]> + + + + + + The arbitrary file operations can be defined for this + instance. The file operators are defined in + ops table. For example, assume that + this chip needs an ioctl. + + + +ops.open = mydata_open; + hw->ops.ioctl = mydata_ioctl; + hw->ops.release = mydata_release; +]]> + + + + And implement the callback functions as you like. + +
+ +
+ IEC958 (S/PDIF) + + Usually the controls for IEC958 devices are implemented via + control interface. There is a macro to compose a name string for + IEC958 controls, SNDRV_CTL_NAME_IEC958() + defined in <include/asound.h>. + + + + There are some standard controls for IEC958 status bits. These + controls use the type SNDRV_CTL_ELEM_TYPE_IEC958, + and the size of element is fixed as 4 bytes array + (value.iec958.status[x]). For info + callback, you don't specify + the value field for this type (the count field must be set, + though). + + + + IEC958 Playback Con Mask is used to return the + bit-mask for the IEC958 status bits of consumer mode. Similarly, + IEC958 Playback Pro Mask returns the bitmask for + professional mode. They are read-only controls, and are defined + as MIXER controls (iface = + SNDRV_CTL_ELEM_IFACE_MIXER). + + + + Meanwhile, IEC958 Playback Default control is + defined for getting and setting the current default IEC958 + bits. Note that this one is usually defined as a PCM control + (iface = SNDRV_CTL_ELEM_IFACE_PCM), + although in some places it's defined as a MIXER control. + + + + In addition, you can define the control switches to + enable/disable or to set the raw bit mode. The implementation + will depend on the chip, but the control should be named as + IEC958 xxx, preferably using + SNDRV_CTL_NAME_IEC958() macro. + + + + You can find several cases, for example, + pci/emu10k1, + pci/ice1712, or + pci/cmipci.c. + +
+ +
+ + + + + + + Buffer and Memory Management + +
+ Buffer Types + + ALSA provides several different buffer allocation functions + depending on the bus and the architecture. All these have a + consistent API. The allocation of physically-contiguous pages is + done via + snd_malloc_xxx_pages() function, where xxx + is the bus type. + + + + The allocation of pages with fallback is + snd_malloc_xxx_pages_fallback(). This + function tries to allocate the specified pages but if the pages + are not available, it tries to reduce the page sizes until the + enough space is found. + + + + For releasing the space, call + snd_free_xxx_pages() function. + + + + Usually, ALSA drivers try to allocate and reserve + a large contiguous physical space + at the time the module is loaded for the later use. + This is called pre-allocation. + As already written, you can call the following function at the + construction of pcm instance (in the case of PCI bus). + + + + + + + + where size is the byte size to be + pre-allocated and the max is the maximal + size to be changed via prealloc proc file. + The allocator will try to get as the large area as possible + within the given size. + There are different versions of pre-allocator for different + buses. + + + + Once when the buffer is pre-allocated, you can use the + allocator in the hw_params callback + + + + + + + + Note that you have to pre-allocate to use this function + (i.e. you cannot use this function for + + a scatter-gather buffer). + +
+ +
+ External Hardware Buffers + + Some chips have their own hardware buffers and the DMA + transfer from the host memory is not available. In such a case, + you need to either 1) copy/set the audio data directly to the + external hardware buffer, or 2) make an intermediate buffer and + copy/set the data from it to the external hardware buffer in + interrupts (or in tasklets, preferably). + + + + The first case works fine if the external hardware buffer is enough + large. This method doesn't need any extra buffers and thus is + more effective. You need to define the + copy and + silence callbacks for + the data transfer. However, there is a drawback: it cannot + be mmapped. The examples are GUS's GF1 PCM or emu8000's + wavetable PCM. + + + + The second case allows the mmap of the buffer, although you have + to handle an interrupt or a tasklet for transferring the data + from the intermediate buffer to the hardware buffer. You can find an + example in vxpocket driver. + + + + Another case is that the chip uses a PCI memory-map + region for the buffer instead of the host memory. In this case, + mmap is available only on certain architectures like intel. In + non-mmap mode, the data cannot be transferred as the normal + way. Thus you need to define copy and + silence callbacks as well + as in the cases above. The examples are found in + rme32.c and rme96.c. + + + + The implementation of copy and + silence callbacks depends upon + whether the hardware supports interleaved or non-interleaved + samples. The copy callback is + defined like below, a bit + differently depending whether the direction is playback or + capture: + + + + + + + + + + In the case of interleaved samples, the second argument + (channel) is not used. The third argument + (pos) points the + current position offset in frames. + + + + The meaning of the fourth argument is different between + playback and capture. For playback, it holds the source data + pointer, and for capture, it's the destination data pointer. + + + + The last argument is the number of frames to be copied. + + + + What you have to do in this callback is again different + between playback and capture directions. In the case of + playback, you do: copy the given amount of data + (count) at the specified pointer + (src) to the specified offset + (pos) on the hardware buffer. When + coded like memcpy-like way, the copy would be like: + + + + + + + + + + For the capture direction, you do: copy the given amount of + data (count) at the specified offset + (pos) on the hardware buffer to the + specified pointer (dst). + + + + + + + + Note that both of the position and the data amount are given + in frames. + + + + In the case of non-interleaved samples, the implementation + will be a bit more complicated. + + + + You need to check the channel argument, and if it's -1, copy + the whole channels. Otherwise, you have to copy only the + specified channel. Please check + isa/gus/gus_pcm.c as an example. + + + + The silence callback is also + implemented in a similar way. + + + + + + + + + + The meanings of arguments are identical with the + copy + callback, although there is no src/dst + argument. In the case of interleaved samples, the channel + argument has no meaning, as well as on + copy callback. + + + + The role of silence callback is to + set the given amount + (count) of silence data at the + specified offset (pos) on the hardware + buffer. Suppose that the data format is signed (that is, the + silent-data is 0), and the implementation using a memset-like + function would be like: + + + + + + + + + + In the case of non-interleaved samples, again, the + implementation becomes a bit more complicated. See, for example, + isa/gus/gus_pcm.c. + +
+ +
+ Non-Contiguous Buffers + + If your hardware supports the page table like emu10k1 or the + buffer descriptors like via82xx, you can use the scatter-gather + (SG) DMA. ALSA provides an interface for handling SG-buffers. + The API is provided in <sound/pcm_sgbuf.h>. + + + + For creating the SG-buffer handler, call + snd_pcm_lib_preallocate_sg_pages() or + snd_pcm_lib_preallocate_sg_pages_for_all() + in the PCM constructor like other PCI pre-allocator. + You need to pass the + pci_dev struct pointer of the chip. + The snd_sg_buf_t instance is created as + substream->dma_private. You can cast + the pointer like: + + + +dma_private, return -EINVAL); +]]> + + + + + + Then call snd_pcm_lib_malloc_pages() + in hw_params callback + as well as in the case of normal PCI buffer. + The SG-buffer handler will allocate the non-contiguous kernel + pages of the given size and map them onto the virtually contiguous + memory. The virtual pointer is addressed in runtime->dma_area. + The physical address (runtime->dma_addr) is set to zero, + because the buffer is physically non-contigous. + The physical address table is set up in sgbuf->table. + You can get the physical address at a certain offset via + snd_pcm_sgbuf_get_addr(). + + + + When a SG-handler is used, you need to set + snd_pcm_sgbuf_ops_page as + the page callback. + + + + For releasing the data, call + snd_pcm_lib_free_pages() in the + hw_free callback as usual. + +
+ +
+ Vmalloc'ed Buffers + + It's possible to use a buffer allocated via + vmalloc, for example, for an intermediate + buffer. Since the allocated pages are not contiguous, you need + to set the page callback to obtain + the physical address at every offset. + + + + The implementation of page callback + would be like this: + + + + + + /* get the physical page pointer on the given offset */ + static struct page *mychip_page(snd_pcm_substream_t *substream, + unsigned long offset) + { + void *pageptr = substream->runtime->dma_area + offset; + return vmalloc_to_page(pageptr); + } +]]> + + + +
+ +
+ + + + + + + Proc Interface + + ALSA provides an easy interface for procfs. The proc files are + very useful for debugging. I recommend you set up proc files if + you write a driver and want to get a running status or register + dumps. The API is found in + <sound/info.h>. + + + + For creating a proc file, call + snd_card_proc_new(). + + + + + + + + where the second argument specifies the proc-file name to be + created. The above example will create a file + my-file under the card directory, + e.g. /proc/asound/card0/my-file. + + + + Like other components, the proc entry created via + snd_card_proc_new() will be registered and + released automatically in the card registration and release + functions. + + + + When the creation is successful, the function stores a new + instance at the pointer given in the third argument. + It is initialized as a text proc file for read only. For using + this proc file as a read-only text file as it is, set the read + callback with a private data via + snd_info_set_text_ops(). + + + + + + + + where the second argument (chip) is the + private data to be used in the callbacks and the third + (my_proc_read) is the callback function, which + is defined like + + + + + + + + + + + In the read callback, use snd_iprintf() for + output strings, which works just like normal + printf(). For example, + + + +private_data, return); + + snd_iprintf(buffer, "This is my chip!\n"); + snd_iprintf(buffer, "Port = %ld\n", chip->port); + } +]]> + + + + + + The file permission can be changed afterwards. As default, it's + set as read only for all users. If you want to add the write + permission to the user (root as default), set like below: + + + +mode = S_IFREG | S_IRUGO | S_IWUSR; +]]> + + + + and set the write buffer size and the callback + + + +c.text.write_size = 256; + entry->c.text.write = my_proc_write; +]]> + + + + + + The buffer size for read is set to 1024 implicitly by + snd_info_set_text_ops(). It should suffice + in most cases (the size will be aligned to + PAGE_SIZE anyway), but if you need to handle + very large text files, you can set it explicitly, too. + + + +c.text.read_size = 65536; +]]> + + + + + + For the write callback, you can use + snd_info_get_line() to get a text line, and + snd_info_get_str() to retrieve a string from + the line. Some examples are found in + core/oss/mixer_oss.c, core/oss/and + pcm_oss.c. + + + + For a raw-data proc-file, set the attributes like the following: + + + +content = SNDRV_INFO_CONTENT_DATA; + entry->private_data = chip; + entry->c.ops = &my_file_io_ops; + entry->size = 4096; + entry->mode = S_IFREG | S_IRUGO; +]]> + + + + + + The callback is much more complicated than the text-file + version. You need to use a low-level i/o functions such as + copy_from/to_user() to transfer the + data. Also, you have to keep tracking the file position, too. + + + +f_pos + size > local_max_size) + size = local_max_size - file->f_pos; + if (copy_to_user(buf, local_data + file->f_pos, size)) + return -EFAULT; + file->f_pos += size; + return size; + } +]]> + + + + + + + + + + + + Power Management + + If the chip is supposed to work with with suspend/resume + functions, you need to add the power-management codes to the + driver. The additional codes for the power-management should be + ifdef'ed with + CONFIG_PM. + + + + Basic jobs of suspend/resume are done in + suspend and + resume callbacks of + pci_driver struct. Unfortunately, the + API of these callbacks was changed at the middle time of Linux + 2.4.x, if you want to keep the support for older kernels, you + have to write two different callbacks. The example below is the + skeleton callbacks which just call the real suspend and resume + functions. + + + + + + + + + + The scheme of the real suspend job is as following. + + + Check whether the power-state is already D3hot. If yes, skip the job. + Call snd_pcm_suspend_all() to suspend the running PCM streams. + Save the register values if necessary. + Stop the hardware if necessary. + Set the power-state as D3hot by calling snd_power_change_state(). + + + + + A typical code would be like: + + + +card; + // (1) + if (card->power_state == SNDRV_CTL_POWER_D3hot) + return; + // (2) + snd_pcm_suspend_all(chip->pcm); + // (3) + snd_mychip_save_registers(chip); + // (4) + snd_mychip_stop_hardware(chip); + // (5) + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + } +]]> + + + + + + The scheme of the real resume job is as following. + + + Check whether the power-state is already D0. + If yes, skip the job. + Enable the pci device again by calling + pci_enable_device(). + Re-initialize the chip. + Restore the saved registers if necessary. + Resume the mixer, e.g. calling + snd_ac97_resume(). + Restart the hardware (if any). + Set the power-state as D0 by calling + snd_power_change_state(). + + + + + A typical code would be like: + + + +card; + // (1) + if (card->power_state == SNDRV_CTL_POWER_D0) + return; + // (2) + pci_enable_device(chip->pci); + // (3) + snd_mychip_reinit_chip(chip); + // (4) + snd_mychip_restore_registers(chip); + // (5) + snd_ac97_resume(chip->ac97); + // (6) + snd_mychip_restart_chip(chip); + // (7) + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + } +]]> + + + + + + In addition to the callbacks above, you should define a callback + for the changes via the ALSA control interface. It's defined + like below: + + + +power_state_private_data, return -ENXIO); + switch (power_state) { + case SNDRV_CTL_POWER_D0: + case SNDRV_CTL_POWER_D1: + case SNDRV_CTL_POWER_D2: + mychip_resume(chip); + break; + case SNDRV_CTL_POWER_D3hot: + case SNDRV_CTL_POWER_D3cold: + mychip_suspend(chip); + break; + default: + return -EINVAL; + } + return 0; + } +]]> + + + + + + OK, we have all callbacks now. Let's set up them now. In the + initialization of the card, add the following: + + + +set_power_state = snd_mychip_set_power_state; + card->power_state_private_data = chip; + #endif + .... + } +]]> + + + + + + If you need a space for saving the registers, you'll need to + allocate the buffer for it here, too, since you cannot call + kmalloc() with + GFP_KERNEL flag or + vmalloc() in the suspend callback. + The allocated buffer should be released in the corresponding + destructor. + + + + And next, set suspend/resume callbacks to the pci_driver, + + + + + + + + + + Last but not least: Please keep in mind that you cannot call + schedule() during the suspend and the resume + callbacks. If any delay is necessary, you have to use + mdelay() or udelay() + instead of schedule_timeout()! + Of course, semaphores cannot be used, too, which will invoke sleep + inside. + + + + + + + + + Module Parameters + + There are standard module options for ALSA. At least, each + module should have index, + id and enable + options. + + + + If the module supports multiple cards (usually up to + 8 = SNDRV_CARDS cards), they should be + arrays. The default initial values are defined already as + constants for ease of programming: + + + + + + + + + + If the module supports only a single card, they could be single + variables, instead. enable option is not + always necessary in this case, but it wouldn't be so bad to have a + dummy option for compatibility. + + + + The module parameters must be declared with the standard + MODULE_PARM() and + MODULE_PARM_DESC() macros. The ALSA provides + an additional macro, MODULE_PARM_SYNTAX(), + for describing its syntax. The strings will be written to + /lib/modules/XXX/modules.generic_string + file. + + + + For convenience, the typical string arguments given to + MODULE_PARM_SYNTAX() are defined in + <sound/initval.h>, such as + SNDRV_ID_DESC or + SNDRV_ENABLED. + + + + The typical coding would be like below: + + + + + + + + + + Also, don't forget to define the module description, classes, + license and devices. Especially, the recent modprobe requires to + define the module license as GPL, etc., otherwise the system is + shown as tainted. + + + + + + + + + + For building the driver into kernel, you should define the + setup() function in addition, too. + ALSA provides get_id() function to retrieve + a string argument from the kernel boot parameters. + + + += SNDRV_CARDS) + return 0; + (void)(get_option(&str,&enable[nr_dev]) == 2 && + get_option(&str,&index[nr_dev]) == 2 && + get_id(&str,&id[nr_dev]) == 2); + nr_dev++; + return 1; + } + + __setup("snd-mychip=", alsa_card_mychip_setup); + + #endif /* ifndef MODULE */ +]]> + + + + + + + + + + + Useful Functions + +
+ <function>snd_printk()</function> and friends + + ALSA provides a verbose version of + printk() function. If a kernel config + CONFIG_SND_VERBOSE_PRINTK is set, this + function prints the given message together with the file name + and the line of the caller. The KERN_XXX + prefix is processed as + well as the original printk() does, so it's + recommended to add this prefix, e.g. + + + + + + + + + + There are also printk()'s for + debugging. snd_printd() can be used for + general debugging purposes. If + CONFIG_SND_DEBUG is set, this function is + compiled, and works just like + snd_printk(). If the ALSA is compiled + without the debugging flag, it's ignored. + + + + snd_printdd() is compiled in only when + CONFIG_SND_DEBUG_DETECT is set. Please note + that DEBUG_DETECT is not set as default + even if you configure the alsa-driver with + option. You need to give + explicitly option instead. + +
+ +
+ <function>snd_assert()</function> + + snd_assert() macro is similar with the + normal assert() macro. For example, + + + + + + + + + + The first argument is the expression to evaluate, and the + second argument is the action if it fails. When + CONFIG_SND_DEBUG, is set, it will show an + error message such as BUG? (xxx) (called from + yyy). When no debug flag is set, this is + ignored. + +
+ +
+ <function>snd_runtime_check()</function> + + This macro is quite similar with + snd_assert(). Unlike + snd_assert(), the expression is always + evaluated regardless of + CONFIG_SND_DEBUG. When + CONFIG_SND_DEBUG is set, the macro will + show a message like ERROR (xx) (called from + yyy). + +
+ +
+ <function>snd_BUG()</function> + + It calls snd_assert(0,) -- that is, just + prints the error message at the point. It's useful to show that + a fatal error happens there. + +
+
+ + + + + + + Acknowledgments + + I would like to thank Phil Kerr for his help for improvement and + corrections of this document. + + + Kevin Conder reformatted the original plain-text to the + DocBook format. + + + + +
diff -Nru a/Documentation/sound/alsa/OSS-Emulation.txt b/Documentation/sound/alsa/OSS-Emulation.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/sound/alsa/OSS-Emulation.txt Sun Feb 9 21:13:38 2003 @@ -0,0 +1,302 @@ + NOTES ON KERNEL OSS-EMULATION + ============================= + + Jan. 9, 2003 Takashi Iwai + + +Modules +======= + +ALSA provides a powerful OSS emulation on the kernel. +The OSS emulation for PCM, mixer and sequencer devices is implemented +as add-on kernel modules, snd-pcm-oss, snd-mixer-oss and snd-seq-oss. +When you need to access the OSS PCM, mixer or sequencer devices, the +corresponding module has to be loaded. + +For loading these modules automatically, define the aliases in +/etc/modules.conf like below: + + alias sound-service-0-0 snd-mixer-oss + alias sound-service-0-1 snd-seq-oss + alias sound-service-0-3 snd-pcm-oss + alias sound-service-0-8 snd-seq-oss + alias sound-service-0-12 snd-pcm-oss + +Then the access to an OSS device file such as /dev/dsp0 triggers to +load the necessary module via KMOD. + +For auto-loading the secondary card device like /dev/dsp1, the +following aliases are necessary in addition: + + alias sound-service-1-0 snd-mixer-oss + alias sound-service-1-3 snd-pcm-oss + alias sound-service-1-12 snd-pcm-oss + +Here you don't need to define service-1-1 and service-1-8 because +there is only one sequencer device. +Similarly, you can add definitions for the third or later cards as +sound-service-X-Y. + +The OSS-MIDI is emulated directly in the ALSA rawmidi module, +therefore no extra module exists for that purpose. + +The currently available OSS configuration is shown in +/proc/asound/oss/sndstat. This shows in the same syntax of +/dev/sndstat, which is available on the commercial OSS driver. +On ALSA, you can symlink /dev/sndstat to this proc file. + +Please note that the devices listed in this proc file appear only +after the corresponding OSS-emulation module is loaded. Don't worry +even if "NOT ENABLED IN CONFIG" is shown in it. + + +Device Mapping +============== + +ALSA supports the following OSS device files: + + PCM: + /dev/dspX + /dev/adspX + + Mixer: + /dev/mixerX + + MIDI: + /dev/midi0X + /dev/amidi0X + + Sequencer: + /dev/sequencer + /dev/sequencer2 (aka /dev/music) + +where X is the card number from 0 to 7. + +(NOTE: Some distributions have the device files like /dev/midi0 and + /dev/midi1. They are NOT for OSS but for tclmidi, which is + a totally different thing.) + +Unlike the real OSS, ALSA cannot use the device files more than the +assigned ones. For example, the first card cannot use /dev/dsp1 or +/dev/dsp2, but only /dev/dsp0 and /dev/adsp0. + +As seen above, PCM and MIDI may have two devices. Usually, the first +PCM device (hw:0,0 in ALSA) is mapped to /dev/dsp and the secondary +device (hw:0,1) to /dev/adsp (if available). For MIDI, /dev/midi and +/dev/amidi, respectively. + +You can change this device mapping via the module options of +snd-pcm-oss and snd-rawmidi. In the case of PCM, the following +options are available for snd-pcm-oss: + + dsp_map PCM device number assigned to /dev/dspX + (default = 0) + adsp_map PCM device number assigned to /dev/adspX + (default = 1) + +For example, to map the third PCM device (hw:0,2) to /dev/adsp0, +define like this: + + options snd-pcm-oss adsp_map=2 + +The options take arrays. For configuring the second card, specify +two entries separated by comma. For example, to map the third PCM +device on the second card to /dev/adsp1, define like below: + + options snd-pcm-oss adsp_map=0,2 + +To change the mapping of MIDI devices, the following options are +available for snd-rawmidi: + + midi_map MIDI device number assigned to /dev/midi0X + (default = 0) + amidi_map MIDI device number assigned to /dev/amidi0X + (default = 1) + +For example, to assign the third MIDI device on the first card to +/dev/midi00, define as follows: + + options snd-rawmidi midi_map=2 + + +PCM Mode +======== + +As default, ALSA emulates the OSS PCM with so-called plugin layer, +i.e. tries to convert the sample format, rate or channels +automatically when the card doesn't support it natively. +This will lead to some problems for some applications like quake or +wine, especially if they use the card only in the MMAP mode. + +In such a case, you can change the behavior of PCM per application by +writing a command to the proc file. There is a proc file for each PCM +stream, /proc/asound/cardX/pcmY[cp]/oss, where X is the card number +(zero-based), Y the PCM device number (zero-based), and 'p' is for +playback and 'c' for capture, respectively. Note that this proc file +exists only after snd-pcm-oss module is loaded. + +The command sequence has the following syntax: + + app_name fragments fragment_size [options] + +app_name is the name of application with (higher priority) or without +path. +fragments specifies the number of fragments or zero if no specific +number is given. +fragment_size is the size of fragment in bytes or zero if not given. +options is the optional parameters. The following options are +available: + + disable the application tries to open a pcm device for + this channel but does not want to use it. + direct don't use plugins + block force block open mode + non-block force non-block open mode + +The disable option is useful when one stream direction (playback or +capture) is not handled correctly by the application although the +hardware itself does support both directions. +The direct option is used, as mentioned above, to bypass the automatic +conversion and useful for MMAP-applications. +For example, to playback the first PCM device without plugins for +quake, send a command via echo like the following: + + % echo "quake 0 0 direct" > /proc/asound/card0/pcm0p/oss + +While quake wants only playback, you may append the second command +to notify driver that only this direction is about to be allocated: + + % echo "quake 0 0 disable" > /proc/asound/card0/pcm0c/oss + +The permission of proc files depend on the module options of snd. +As default it's set as root, so you'll likely need to be superuser for +sending the command above. + +The block and non-block options are used to change the behavior of +opening the device file. +As default, ALSA behaves as defined in POSIX, i.e. blocks the file +when it's busy until the device becomes free (unless O_NONBLOCK is +specified). Some applications assume the non-block open behavior, +which are actually implemented in some real OSS drivers. + +This blocking behavior can be changed globally via nonblock_open +module option of snd-pcm-oss. For using the non-block mode as default +for OSS devices, define like the following: + + options snd-pcm-oss nonblock_open=1 + +You can check the currently defined configuration by reading the proc +file. The read image can be sent to the proc file again, hence you +can save the current configuration + + % cat /proc/asound/card0/pcm0p/oss > /somewhere/oss-cfg + +and restore it like + + % cat /somewhere/oss-cfg > /proc/asound/card0/pcm0p/oss + +Also, for clearing all the current configuration, send "erase" command +as below: + + % echo "erase" > /proc/asound/card0/pcm0p/oss + + +Mixer Elements +============== + +Since ALSA has completely different mixer interface, the emulation of +OSS mixer is relatively complicated. ALSA builds up a mixer element +from several different ALSA (mixer) controls based on the name +string. For example, the volume element SOUND_MIXER_PCM is composed +from "PCM Playback Volume" and "PCM Playback Switch" controls for the +playback direction and from "PCM Capture Volume" and "PCM Capture +Switch" for the capture directory (if exists). When the PCM volume of +OSS is changed, all the volume and switch controls above are adjusted +automatically. + +As default, ALSA uses the following control for OSS volumes: + + OSS volume ALSA control Index + ----------------------------------------------------- + SOUND_MIXER_VOLUME Master 0 + SOUND_MIXER_BASS Tone Control - Bass 0 + SOUND_MIXER_TREBLE Tone Control - Treble 0 + SOUND_MIXER_SYNTH Synth 0 + SOUND_MIXER_PCM PCM 0 + SOUND_MIXER_SPEAKER PC Speaker 0 + SOUND_MIXER_LINE Line 0 + SOUND_MIXER_MIC Mic 0 + SOUND_MIXER_CD CD 0 + SOUND_MIXER_IMIX Monitor Mix 0 + SOUND_MIXER_ALTPCM PCM 1 + SOUND_MIXER_RECLEV (not assigned) + SOUND_MIXER_IGAIN Capture 0 + SOUND_MIXER_OGAIN Playback 0 + SOUND_MIXER_LINE1 Aux 0 + SOUND_MIXER_LINE2 Aux 1 + SOUND_MIXER_LINE3 Aux 2 + SOUND_MIXER_DIGITAL1 Digital 0 + SOUND_MIXER_DIGITAL2 Digital 1 + SOUND_MIXER_DIGITAL3 Digital 2 + SOUND_MIXER_PHONEIN Phone 0 + SOUND_MIXER_PHONEOUT Phone 1 + SOUND_MIXER_VIDEO Video 0 + SOUND_MIXER_RADIO Radio 0 + SOUND_MIXER_MONITOR Monitor 0 + +The second column is the base-string of the corresponding ALSA +control. In fact, the controls with "XXX [Playback|Capture] +[Volume|Switch]" will be checked in addition. + +The current assignment of these mixer elements is listed in the proc +file, /proc/asound/cardX/mixer_oss, which will be like the following + + VOLUME "Master" 0 + BASS "" 0 + TREBLE "" 0 + SYNTH "" 0 + PCM "PCM" 0 + ... + +where the first column is the OSS volume element, the second column +the base-string of the corresponding ALSA control, and the third the +control index. When the string is empty, it means that the +corresponding OSS control is not available. + +For changing the assignment, you can write the configuration to this +proc file. For example, to map "Wave Playback" to the PCM volume, +send the command like the following: + + % echo 'VOLUME "Wave Playback" 0' > /proc/asound/card0/mixer_oss + +The command is exactly as same as listed in the proc file. You can +change one or more elements, one volume per line. In the last +example, both "Wave Playback Volume" and "Wave Playback Switch" will +be affected when PCM volume is changed. + +Like the case of PCM proc file, the permission of proc files depend on +the module options of snd. you'll likely need to be superuser for +sending the command above. + +As well as in the case of PCM proc file, you can save and restore the +current mixer configuration by reading and writing the whole file +image. + + +Unsupported Features +==================== + +MMAP on ICE1712 driver +---------------------- +ICE1712 supports only the unconventional format, interleaved +10-channels 24bit (packed in 32bit) format. Therefore you cannot mmap +the buffer as the conventional (mono or 2-channels, 8 or 16bit) format +on OSS. + +USB devices +----------- +Some USB devices support only 24bit format packed in 3bytes. This +format is not supported by OSS and no conversion is provided by kernel +OSS emulation. You can use the user-space OSS emulation via libaoss +instead. + diff -Nru a/Documentation/sparc/sbus_drivers.txt b/Documentation/sparc/sbus_drivers.txt --- a/Documentation/sparc/sbus_drivers.txt Sun Feb 9 21:13:30 2003 +++ b/Documentation/sparc/sbus_drivers.txt Sun Feb 9 21:13:30 2003 @@ -208,7 +208,7 @@ char *mem; /* Address in the CPU space */ u32 busa; /* Address in the SBus space */ - mem = (char *) sbus_alloc_consistant(sdev, MYMEMSIZE, &busa); + mem = (char *) sbus_alloc_consistent(sdev, MYMEMSIZE, &busa); Then mem is used when CPU accesses this memory and u32 is fed to the device so that it can do DVMA. This is typically @@ -216,7 +216,7 @@ Do not forget to free the DVMA resources once you are done: - sbus_free_consistant(sdev, MYMEMSIZE, mem, busa); + sbus_free_consistent(sdev, MYMEMSIZE, mem, busa); Streaming DVMA is more interesting. First you allocate some memory suitable for it or pin down some user pages. Then it all works diff -Nru a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt --- a/Documentation/sysctl/kernel.txt Sun Feb 9 21:13:32 2003 +++ b/Documentation/sysctl/kernel.txt Sun Feb 9 21:13:32 2003 @@ -222,7 +222,7 @@ printk: The four values in printk denote: console_loglevel, -default_message_loglevel, minimum_console_level and +default_message_loglevel, minimum_console_loglevel and default_console_loglevel respectively. These values influence printk() behavior when printing or diff -Nru a/Documentation/tipar.txt b/Documentation/tipar.txt --- a/Documentation/tipar.txt Sun Feb 9 21:13:28 2003 +++ b/Documentation/tipar.txt Sun Feb 9 21:13:28 2003 @@ -12,7 +12,7 @@ This is a driver for the very common home-made parallel link cable, a cable designed for connecting TI8x/9x graphing calculators (handhelds) to a computer or workstation (Alpha, Sparc). Given that driver is built on parport, the -parallel port abstraction layer, this driver is independant of the platform. +parallel port abstraction layer, this driver is independent of the platform. It can also be used with another device plugged on the same port (such as a ZIP drive). I have a 100MB ZIP and both of them work fine ! @@ -90,4 +90,4 @@ CREDITS: The code is based on tidev.c & parport.c. -The driver has been developed independantly of Texas Instruments. +The driver has been developed independently of Texas Instruments. diff -Nru a/Documentation/usb/hiddev.txt b/Documentation/usb/hiddev.txt --- a/Documentation/usb/hiddev.txt Sun Feb 9 21:13:30 2003 +++ b/Documentation/usb/hiddev.txt Sun Feb 9 21:13:30 2003 @@ -9,7 +9,7 @@ supplies) and monitor control on higher end monitors. To support these disparite requirements, the Linux USB system provides -HID events to two seperate interfaces: +HID events to two separate interfaces: * the input subsystem, which converts HID events into normal input device interfaces (such as keyboard, mouse and joystick) and a normalised event interface - see Documentation/input/input.txt diff -Nru a/Documentation/usb/silverlink.txt b/Documentation/usb/silverlink.txt --- a/Documentation/usb/silverlink.txt Sun Feb 9 21:13:30 2003 +++ b/Documentation/usb/silverlink.txt Sun Feb 9 21:13:30 2003 @@ -73,4 +73,4 @@ CREDITS: The code is based on dabusb.c, printer.c and scanner.c ! -The driver has been developed independantly of Texas Instruments. +The driver has been developed independently of Texas Instruments. diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Sun Feb 9 21:13:33 2003 +++ b/MAINTAINERS Sun Feb 9 21:13:33 2003 @@ -614,11 +614,9 @@ S: Maintained ETHERNET BRIDGE -P: Lennert Buytenhek -M: buytenh@gnu.org L: bridge@math.leidenuniv.nl W: http://bridge.sourceforge.net/ -S: Maintained +S: Unmaintained ETHERTEAM 16I DRIVER P: Mika Kuoppala diff -Nru a/Makefile b/Makefile --- a/Makefile Sun Feb 9 21:13:29 2003 +++ b/Makefile Sun Feb 9 21:13:29 2003 @@ -53,6 +53,8 @@ CROSS_COMPILE = # That's our default target when none is given on the command line +# Note that 'modules' will be added as a prerequisite as well, +# in the CONFIG_MODULES part below all: vmlinux @@ -183,6 +185,8 @@ export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE +export MODVERDIR := .tmp_versions + # The temporary file to save gcc -MD generated dependencies must not # contain a comma depfile = $(subst $(comma),_,$(@D)/.$(@F).d) @@ -190,7 +194,7 @@ noconfig_targets := xconfig menuconfig config oldconfig randconfig \ defconfig allyesconfig allnoconfig allmodconfig \ clean mrproper distclean \ - help tags TAGS sgmldocs psdocs pdfdocs htmldocs \ + help tags TAGS cscope sgmldocs psdocs pdfdocs htmldocs \ checkconfig checkhelp checkincludes RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \) -prune -o @@ -256,14 +260,22 @@ -include .config.cmd -ifdef CONFIG_MODULES -export EXPORT_FLAGS := -DEXPORT_SYMTAB -endif - ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif +# When we're building modules with modversions, we need to consider +# the built-in objects during the descend as well, in order to +# make sure the checksums are uptodate before we record them. + +ifdef CONFIG_MODVERSIONS +ifeq ($(KBUILD_MODULES),1) +ifneq ($(KBUILD_BUILTIN),1) + KBUILD_BUILTIN := 1 +endif +endif +endif + # # INSTALL_PATH specifies where to place the updated kernel and system map # images. Uncomment if you want to place them anywhere other than root. @@ -289,12 +301,12 @@ # normal descending-into-subdirs phase, since at that time # we cannot yet know if we will need to relink vmlinux. # So we descend into init/ inside the rule for vmlinux again. - -vmlinux-objs := $(HEAD) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y) +head-y += $(HEAD) +vmlinux-objs := $(head-y) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y) quiet_cmd_vmlinux__ = LD $@ define cmd_vmlinux__ - $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) $(HEAD) $(init-y) \ + $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) $(head-y) $(init-y) \ --start-group \ $(core-y) \ $(libs-y) \ @@ -384,7 +396,7 @@ # Handle descending into subdirectories listed in $(SUBDIRS) .PHONY: $(SUBDIRS) -$(SUBDIRS): .hdepend prepare +$(SUBDIRS): prepare $(Q)$(MAKE) $(build)=$@ # Things we need done before we descend to build or make @@ -392,6 +404,17 @@ .PHONY: prepare prepare: include/linux/version.h include/asm include/config/MARKER +ifdef CONFIG_MODVERSIONS +ifdef KBUILD_MODULES +ifeq ($(origin SUBDIRS),file) + $(Q)rm -rf $(MODVERDIR) + $(Q)mkdir $(MODVERDIR) +else + @echo '*** Warning: Overriding SUBDIRS on the command line can cause' + @echo '*** inconsistencies with module symbol versions' +endif +endif +endif @echo ' Starting the build. KBUILD_BUILTIN=$(KBUILD_BUILTIN) KBUILD_MODULES=$(KBUILD_MODULES)' # We need to build init/vermagic.o before descending since all modules @@ -424,6 +447,8 @@ $(Q)$(MAKE) $(build)=$(@D) $@ %.o: %.c scripts FORCE $(Q)$(MAKE) $(build)=$(@D) $@ +%/: scripts prepare FORCE + $(Q)$(MAKE) $(build)=$(@D) %.ko: scripts FORCE $(Q)$(MAKE) $(build)=$(@D) $@ %.lst: %.c scripts FORCE @@ -475,75 +500,33 @@ ) > $@.tmp @$(update-if-changed) -# Generate module versions # --------------------------------------------------------------------------- -# The targets are still named depend / dep for traditional -# reasons, but the only thing we do here is generating -# the module version checksums. - -.PHONY: depend dep $(patsubst %,_sfdep_%,$(SUBDIRS)) - -depend dep: .hdepend - -# .hdepend is our (misnomed) marker for whether we've -# generated module versions - -make-versions := $(strip $(if $(filter dep depend,$(MAKECMDGOALS)),1) \ - $(if $(wildcard .hdepend),,1)) - -.hdepend: prepare FORCE -ifneq ($(make-versions),) - @$(MAKE) include/linux/modversions.h - @touch $@ -endif - -ifdef CONFIG_MODVERSIONS - -# Update modversions.h, but only if it would change. - -.PHONY: __rm_tmp_export-objs -__rm_tmp_export-objs: - @rm -rf .tmp_export-objs - -include/linux/modversions.h: $(patsubst %,_modver_%,$(SUBDIRS)) - @echo -n ' Generating $@' - @( echo "#ifndef _LINUX_MODVERSIONS_H";\ - echo "#define _LINUX_MODVERSIONS_H"; \ - echo "#include "; \ - cd .tmp_export-objs >/dev/null; \ - for f in `find modules -name \*.ver -print | sort`; do \ - echo "#include "; \ - done; \ - echo "#endif"; \ - ) > $@.tmp; \ - $(update-if-changed) - -.PHONY: $(patsubst %, _modver_%, $(SUBDIRS)) -$(patsubst %, _modver_%, $(SUBDIRS)): __rm_tmp_export-objs - $(Q)$(MAKE) -f scripts/Makefile.modver obj=$(patsubst _modver_%,%,$@) - -else # !CONFIG_MODVERSIONS - -.PHONY: include/linux/modversions.h - -include/linux/modversions.h: - -endif # CONFIG_MODVERSIONS +.PHONY: depend dep +depend dep: + @echo '*** Warning: make $@ is unnecessary now.' # --------------------------------------------------------------------------- # Modules ifdef CONFIG_MODULES +# By default, build modules as well + +all: modules + # Build modules +.PHONY: modules __modversions +modules: $(SUBDIRS) __modversions + ifdef CONFIG_MODVERSIONS -MODFLAGS += -include include/linux/modversions.h -endif -.PHONY: modules -modules: $(SUBDIRS) +__modversions: vmlinux $(SUBDIRS) + @echo ' Recording module symbol versions.'; + $(Q)$(MAKE) -rR -f scripts/Makefile.modver + +endif # Install modules @@ -574,6 +557,7 @@ .PHONY: $(patsubst %, _modinst_%, $(SUBDIRS)) $(patsubst %, _modinst_%, $(SUBDIRS)) : $(Q)$(MAKE) -rR -f scripts/Makefile.modinst obj=$(patsubst _modinst_%,%,$@) + else # CONFIG_MODULES # Modules not configured @@ -624,7 +608,7 @@ rpm: clean spec find . $(RCS_FIND_IGNORE) \ - \( -size 0 -o -name .depend -o -name .hdepend \) \ + \( -size 0 -o -name .depend -o -name .hdepend\) \ -type f -print | xargs rm -f set -e; \ cd $(TOPDIR)/.. ; \ @@ -718,25 +702,26 @@ .menuconfig.log \ include/asm \ .hdepend include/linux/modversions.h \ - tags TAGS kernel.spec \ + tags TAGS cscope kernel.spec \ .tmp* # Directories removed with 'make mrproper' MRPROPER_DIRS += \ + $(MODVERDIR) \ .tmp_export-objs \ include/config \ include/linux/modules # clean - Delete all intermediate files # -clean-dirs += $(ALL_SUBDIRS) Documentation/DocBook scripts - -$(addprefix _clean_,$(clean-dirs)): +clean-dirs += $(addprefix _clean_,$(ALL_SUBDIRS) Documentation/DocBook scripts) +.PHONY: $(clean-dirs) clean archclean mrproper archmrproper distclean +$(clean-dirs): $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) quiet_cmd_rmclean = RM $$(CLEAN_FILES) cmd_rmclean = rm -f $(CLEAN_FILES) -clean: archclean $(addprefix _clean_,$(clean-dirs)) +clean: archclean $(clean-dirs) $(call cmd,rmclean) @find . $(RCS_FIND_IGNORE) \ \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ @@ -775,6 +760,9 @@ -name '*.[chS]' -print ) endef +quiet_cmd_cscope = MAKE $@ +cmd_cscope = $(all-sources) | cscope -k -b -i - + quiet_cmd_TAGS = MAKE $@ cmd_TAGS = $(all-sources) | etags - @@ -786,6 +774,9 @@ CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_NOVERS"`; \ $(all-sources) | xargs ctags $$CTAGSF -a endef + +cscope: FORCE + $(call cmd,cscope) TAGS: FORCE $(call cmd,TAGS) diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig --- a/arch/alpha/Kconfig Sun Feb 9 21:13:34 2003 +++ b/arch/alpha/Kconfig Sun Feb 9 21:13:34 2003 @@ -458,6 +458,11 @@ If unsure, say N. +config EARLY_PRINTK + bool + depends on ALPHA_GENERIC || ALPHA_SRM + default y + config ALPHA_EISA bool depends on ALPHA_ALCOR || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_RAWHIDE @@ -630,7 +635,7 @@ of course). This driver is also available as a module and will be called - srm_env.o then. + srm_env then. config BINFMT_AOUT tristate "Kernel support for a.out (ECOFF) binaries" @@ -650,7 +655,7 @@ QMAGIC support" then you'll have to say Y here. You may answer M to compile a.out support as a module and later load the module when you want to use a program or library in a.out format. The module will be - called binfmt_aout.o. Saying M or N here is dangerous though, + called binfmt_aout. Saying M or N here is dangerous though, because some crucial programs on your system might still be in A.OUT format. @@ -688,7 +693,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config BINFMT_MISC @@ -713,7 +718,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. config BINFMT_EM86 @@ -728,7 +733,7 @@ You may answer M to compile the emulation support as a module and later load the module when you want to use a Linux/Intel binary. The - module will be called binfmt_em86.o. If unsure, say Y. + module will be called binfmt_em86. If unsure, say Y. source "drivers/parport/Kconfig" @@ -785,7 +790,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -821,7 +826,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -915,7 +920,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/alpha/Makefile b/arch/alpha/Makefile --- a/arch/alpha/Makefile Sun Feb 9 21:13:33 2003 +++ b/arch/alpha/Makefile Sun Feb 9 21:13:33 2003 @@ -90,7 +90,7 @@ # BWX is most important, but we don't really want any emulation ever. CFLAGS += $(cflags-y) -Wa,-mev6 -HEAD := arch/alpha/kernel/head.o +head-y := arch/alpha/kernel/head.o core-y += arch/alpha/kernel/ arch/alpha/mm/ core-$(CONFIG_MATHEMU) += arch/alpha/math-emu/ @@ -124,8 +124,6 @@ archclean: $(Q)$(MAKE) -f scripts/Makefile.clean obj=$(boot) - -archmrproper: CLEAN_FILES += include/asm-$(ARCH)/asm_offsets.h.tmp \ include/asm-$(ARCH)/asm_offsets.h diff -Nru a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile --- a/arch/alpha/kernel/Makefile Sun Feb 9 21:13:31 2003 +++ b/arch/alpha/kernel/Makefile Sun Feb 9 21:13:31 2003 @@ -6,8 +6,6 @@ EXTRA_AFLAGS := $(CFLAGS) -export-objs := alpha_ksyms.o core_marvel.o core_titan.o - obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \ irq_alpha.o signal.o setup.o ptrace.o time.o semaphore.o \ alpha_ksyms.o systbls.o err_common.o @@ -35,7 +33,12 @@ obj-y += es1888.o smc37c669.o smc37c93x.o ns87312.o gct.o +obj-y += srmcons.o + else + +# Misc support +obj-$(CONFIG_ALPHA_SRM) += srmcons.o # Core logic support obj-$(CONFIG_ALPHA_APECS) += core_apecs.o diff -Nru a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c --- a/arch/alpha/kernel/alpha_ksyms.c Sun Feb 9 21:13:28 2003 +++ b/arch/alpha/kernel/alpha_ksyms.c Sun Feb 9 21:13:28 2003 @@ -40,7 +40,6 @@ extern struct hwrpb_struct *hwrpb; extern void dump_thread(struct pt_regs *, struct user *); -extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); extern spinlock_t rtc_lock; /* these are C runtime functions with special calling conventions: */ @@ -144,7 +143,9 @@ #endif EXPORT_SYMBOL(dump_thread); -EXPORT_SYMBOL(dump_fpu); +EXPORT_SYMBOL(dump_elf_thread); +EXPORT_SYMBOL(dump_elf_task); +EXPORT_SYMBOL(dump_elf_task_fp); EXPORT_SYMBOL(hwrpb); EXPORT_SYMBOL(start_thread); EXPORT_SYMBOL(alpha_read_fp_reg); diff -Nru a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c --- a/arch/alpha/kernel/core_irongate.c Sun Feb 9 21:13:34 2003 +++ b/arch/alpha/kernel/core_irongate.c Sun Feb 9 21:13:34 2003 @@ -27,13 +27,11 @@ #include #undef __EXTERN_INLINE +#include + #include "proto.h" #include "pci_impl.h" -#undef DEBUG_IRONGATE /* define to enable verbose Irongate debug */ - -#define IRONGATE_DEFAULT_AGP_APER_SIZE (256*1024*1024) /* 256MB */ - /* * BIOS32-style PCI interface: */ @@ -46,6 +44,7 @@ # define DBG_CFG(args) #endif +igcsr32 *IronECC; /* * Given a bus, device, and function number, compute resulting @@ -165,143 +164,6 @@ .write = irongate_write_config, }; -#ifdef DEBUG_IRONGATE -static void -irongate_register_dump(const char *function_name) -{ - printk("%s: Irongate registers:\n" - "\tFunction 0:\n" - "\tdev_vendor\t0x%08x\n" - "\tstat_cmd\t0x%08x\n" - "\tclass\t\t0x%08x\n" - "\tlatency\t\t0x%08x\n" - "\tbar0\t\t0x%08x\n" - "\tbar1\t\t0x%08x\n" - "\tbar2\t\t0x%08x\n" - "\trsrvd0[0]\t0x%08x\n" - "\trsrvd0[1]\t0x%08x\n" - "\trsrvd0[2]\t0x%08x\n" - "\trsrvd0[3]\t0x%08x\n" - "\trsrvd0[4]\t0x%08x\n" - "\trsrvd0[5]\t0x%08x\n" - "\tcapptr\t\t0x%08x\n" - "\trsrvd1[0]\t0x%08x\n" - "\trsrvd1[1]\t0x%08x\n" - "\tbacsr10\t\t0x%08x\n" - "\tbacsr32\t\t0x%08x\n" - "\tbacsr54\t\t0x%08x\n" - "\trsrvd2[0]\t0x%08x\n" - "\tdrammap\t\t0x%08x\n" - "\tdramtm\t\t0x%08x\n" - "\tdramms\t\t0x%08x\n" - "\trsrvd3[0]\t0x%08x\n" - "\tbiu0\t\t0x%08x\n" - "\tbiusip\t\t0x%08x\n" - "\trsrvd4[0]\t0x%08x\n" - "\trsrvd4[1]\t0x%08x\n" - "\tmro\t\t0x%08x\n" - "\trsrvd5[0]\t0x%08x\n" - "\trsrvd5[1]\t0x%08x\n" - "\trsrvd5[2]\t0x%08x\n" - "\twhami\t\t0x%08x\n" - "\tpciarb\t\t0x%08x\n" - "\tpcicfg\t\t0x%08x\n" - "\trsrvd6[0]\t0x%08x\n" - "\trsrvd6[1]\t0x%08x\n" - "\trsrvd6[2]\t0x%08x\n" - "\trsrvd6[3]\t0x%08x\n" - "\trsrvd6[4]\t0x%08x\n" - "\tagpcap\t\t0x%08x\n" - "\tagpstat\t\t0x%08x\n" - "\tagpcmd\t\t0x%08x\n" - "\tagpva\t\t0x%08x\n" - "\tagpmode\t\t0x%08x\n" - - "\n\tFunction 1:\n" - "\tdev_vendor:\t0x%08x\n" - "\tcmd_status:\t0x%08x\n" - "\trevid_etc :\t0x%08x\n" - "\thtype_etc :\t0x%08x\n" - "\trsrvd0[0] :\t0x%08x\n" - "\trsrvd0[1] :\t0x%08x\n" - "\tbus_nmbers:\t0x%08x\n" - "\tio_baselim:\t0x%08x\n" - "\tmem_bselim:\t0x%08x\n" - "\tpf_baselib:\t0x%08x\n" - "\trsrvd1[0] :\t0x%08x\n" - "\trsrvd1[1] :\t0x%08x\n" - "\tio_baselim:\t0x%08x\n" - "\trsrvd2[0] :\t0x%08x\n" - "\trsrvd2[1] :\t0x%08x\n" - "\tinterrupt :\t0x%08x\n", - - function_name, - IRONGATE0->dev_vendor, - IRONGATE0->stat_cmd, - IRONGATE0->class, - IRONGATE0->latency, - IRONGATE0->bar0, - IRONGATE0->bar1, - IRONGATE0->bar2, - IRONGATE0->rsrvd0[0], - IRONGATE0->rsrvd0[1], - IRONGATE0->rsrvd0[2], - IRONGATE0->rsrvd0[3], - IRONGATE0->rsrvd0[4], - IRONGATE0->rsrvd0[5], - IRONGATE0->capptr, - IRONGATE0->rsrvd1[0], - IRONGATE0->rsrvd1[1], - IRONGATE0->bacsr10, - IRONGATE0->bacsr32, - IRONGATE0->bacsr54, - IRONGATE0->rsrvd2[0], - IRONGATE0->drammap, - IRONGATE0->dramtm, - IRONGATE0->dramms, - IRONGATE0->rsrvd3[0], - IRONGATE0->biu0, - IRONGATE0->biusip, - IRONGATE0->rsrvd4[0], - IRONGATE0->rsrvd4[1], - IRONGATE0->mro, - IRONGATE0->rsrvd5[0], - IRONGATE0->rsrvd5[1], - IRONGATE0->rsrvd5[2], - IRONGATE0->whami, - IRONGATE0->pciarb, - IRONGATE0->pcicfg, - IRONGATE0->rsrvd6[0], - IRONGATE0->rsrvd6[1], - IRONGATE0->rsrvd6[2], - IRONGATE0->rsrvd6[3], - IRONGATE0->rsrvd6[4], - IRONGATE0->agpcap, - IRONGATE0->agpstat, - IRONGATE0->agpcmd, - IRONGATE0->agpva, - IRONGATE0->agpmode, - IRONGATE1->dev_vendor, - IRONGATE1->stat_cmd, - IRONGATE1->class, - IRONGATE1->htype, - IRONGATE1->rsrvd0[0], - IRONGATE1->rsrvd0[1], - IRONGATE1->busnos, - IRONGATE1->io_baselim_regs, - IRONGATE1->mem_baselim, - IRONGATE1->pfmem_baselim, - IRONGATE1->rsrvd1[0], - IRONGATE1->rsrvd1[1], - IRONGATE1->io_baselim, - IRONGATE1->rsrvd2[0], - IRONGATE1->rsrvd2[1], - IRONGATE1->interrupt ); -} -#else -#define irongate_register_dump(x) -#endif - int irongate_pci_clr_err(void) { @@ -315,11 +177,11 @@ mb(); IRONGATE_jd = IRONGATE0->stat_cmd; /* re-read to force write */ - IRONGATE_jd = IRONGATE0->dramms; - printk("Iron dramms %x\n", IRONGATE_jd); - IRONGATE0->dramms = IRONGATE_jd; /* write again clears error bits */ + IRONGATE_jd = *IronECC; + printk("Iron ECC %x\n", IRONGATE_jd); + *IronECC = IRONGATE_jd; /* write again clears error bits */ mb(); - IRONGATE_jd = IRONGATE0->dramms; /* re-read to force write */ + IRONGATE_jd = *IronECC; /* re-read to force write */ /* Clear ALI NMI */ nmi_ctl = inb(0x61); @@ -328,28 +190,88 @@ nmi_ctl &= ~0x0c; outb(nmi_ctl, 0x61); - IRONGATE_jd = IRONGATE0->dramms; + IRONGATE_jd = *IronECC; if (IRONGATE_jd & 0x300) goto again; return 0; } +#define IRONGATE_3GB 0xc0000000UL + +/* On Albacore (aka UP1500) with 4Gb of RAM we have to reserve some + memory for PCI. At this point we just reserve memory above 3Gb. Most + of this memory will be freed after PCI setup is done. */ +static void __init +albacore_init_arch(void) +{ + unsigned long memtop = max_low_pfn << PAGE_SHIFT; + unsigned long pci_mem = (memtop + 0x1000000UL) & ~0xffffffUL; + struct percpu_struct *cpu; + int pal_rev, pal_var; + + cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset); + pal_rev = cpu->pal_revision & 0xffff; + pal_var = (cpu->pal_revision >> 16) & 0xff; + + /* Consoles earlier than A5.6-18 (OSF PALcode v1.62-2) set up + the CPU incorrectly (leave speculative stores enabled), + which causes memory corruption under certain conditions. + Issue a warning for such consoles. */ + if (alpha_using_srm && + (pal_rev < 0x13e || (pal_rev == 0x13e && pal_var < 2))) + printk(KERN_WARNING "WARNING! Upgrade to SRM A5.6-19 " + "or later\n"); + + if (pci_mem > IRONGATE_3GB) + pci_mem = IRONGATE_3GB; + IRONGATE0->pci_mem = pci_mem; + alpha_mv.min_mem_address = pci_mem; + if (memtop > pci_mem) { +#ifdef CONFIG_BLK_DEV_INITRD + extern unsigned long initrd_start, initrd_end; + extern void *move_initrd(unsigned long); + + /* Move the initrd out of the way. */ + if (initrd_end && __pa(initrd_end) > pci_mem) { + unsigned long size; + + size = initrd_end - initrd_start; + free_bootmem(__pa(initrd_start), PAGE_ALIGN(size)); + if (!move_initrd(pci_mem)) + printk("irongate_init_arch: initrd too big " + "(%ldK)\ndisabling initrd\n", + size / 1024); + } +#endif + reserve_bootmem(pci_mem, memtop - pci_mem); + printk("irongate_init_arch: temporarily reserving " + "region %08lx-%08lx for PCI\n", pci_mem, memtop - 1); + } +} + +static void __init +irongate_setup_agp(void) +{ + /* Disable the GART window. AGPGART doesn't work due to yet + unresolved memory coherency issues... */ + IRONGATE0->agpva = IRONGATE0->agpva & ~0xf; + alpha_agpgart_size = 0; +} + void __init irongate_init_arch(void) { struct pci_controller *hose; + int amd761 = (IRONGATE0->dev_vendor >> 16) > 0x7006; /* Albacore? */ + + IronECC = amd761 ? &IRONGATE0->bacsr54_eccms761 : &IRONGATE0->dramms; - IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100; irongate_pci_clr_err(); - irongate_register_dump(__FUNCTION__); - /* - * HACK: set AGP aperture size to 256MB. - * This should really be changed during PCI probe, when the - * size of the aperture the AGP card wants is known. - */ - printk("irongate_init_arch: AGPVA was 0x%x\n", IRONGATE0->agpva); - IRONGATE0->agpva = (IRONGATE0->agpva & ~0x0000000f) | 0x00000007; + if (amd761) + albacore_init_arch(); + + irongate_setup_agp(); /* * Create our single hose. @@ -380,89 +302,9 @@ * IO map and AGP support */ #include -#include - -static inline void -irongate_remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) -{ - unsigned long end; - unsigned long pfn; - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - if (address >= end) - BUG(); - pfn = phys_addr >> PAGE_SHIFT; - do { - if (!pte_none(*pte)) { - printk("irongate_remap_area_pte: page already exists\n"); - BUG(); - } - set_pte(pte, pfn_pte(pfn, - __pgprot(_PAGE_VALID | _PAGE_ASM | - _PAGE_KRE | _PAGE_KWE | flags))); - address += PAGE_SIZE; - pfn++; - pte++; - } while (address && (address < end)); -} - -static inline int -irongate_remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - phys_addr -= address; - if (address >= end) - BUG(); - do { - pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address); - if (!pte) - return -ENOMEM; - irongate_remap_area_pte(pte, address, end - address, - address + phys_addr, flags); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address && (address < end)); - return 0; -} - -static int -irongate_remap_area_pages(unsigned long address, unsigned long phys_addr, - unsigned long size, unsigned long flags) -{ - pgd_t * dir; - unsigned long end = address + size; - - phys_addr -= address; - dir = pgd_offset(&init_mm, address); - flush_cache_all(); - if (address >= end) - BUG(); - do { - pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); - if (!pmd) - return -ENOMEM; - if (irongate_remap_area_pmd(pmd, address, end - address, - phys_addr + address, flags)) - return -ENOMEM; - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); - return 0; -} - #include #include +#include #define GET_PAGE_DIR_OFF(addr) (addr >> 22) #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr)) @@ -477,15 +319,13 @@ unsigned long vaddr; unsigned long baddr, last; u32 *mmio_regs, *gatt_pages, *cur_gatt, pte; - unsigned long gart_bus_addr, gart_aper_size; - - gart_bus_addr = (unsigned long)IRONGATE0->bar0 & - PCI_BASE_ADDRESS_MEM_MASK; + unsigned long gart_bus_addr; - if (!gart_bus_addr) /* FIXME - there must be a better way!!! */ + if (!alpha_agpgart_size) return addr + IRONGATE_MEM; - gart_aper_size = IRONGATE_DEFAULT_AGP_APER_SIZE; /* FIXME */ + gart_bus_addr = (unsigned long)IRONGATE0->bar0 & + PCI_BASE_ADDRESS_MEM_MASK; /* * Check for within the AGP aperture... @@ -495,7 +335,7 @@ * Check the AGP area */ if (addr >= gart_bus_addr && addr + size - 1 < - gart_bus_addr + gart_aper_size) + gart_bus_addr + alpha_agpgart_size) break; /* @@ -549,8 +389,8 @@ cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1); pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1; - if (irongate_remap_area_pages(VMALLOC_VMADDR(vaddr), - pte, PAGE_SIZE, 0)) { + if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr), + pte, PAGE_SIZE, 0)) { printk("AGP ioremap: FAILED to map...\n"); vfree(area->addr); return (unsigned long)NULL; diff -Nru a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c --- a/arch/alpha/kernel/core_marvel.c Sun Feb 9 21:13:29 2003 +++ b/arch/alpha/kernel/core_marvel.c Sun Feb 9 21:13:29 2003 @@ -732,21 +732,6 @@ EXPORT_SYMBOL(marvel_ioremap); EXPORT_SYMBOL(marvel_iounmap); #endif - -/* - * SRMCons support - * - * Marvel doesn't have a real serial console -- it's either graphics or - * server management based. If we're running on the server management based - * console, allow the srmcons callback driver to be a console device. - */ -int -marvel_srmcons_allowed(void) -{ - u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset); - - return (pu64[7] == 2); -} /* @@ -874,8 +859,6 @@ #include #include -#define MARVEL_AGP_APER_SIZE (64 * 1024 * 1024) - struct marvel_agp_aperture { struct pci_iommu_arena *arena; long pg_start; @@ -887,11 +870,14 @@ { struct marvel_agp_aperture *aper; + if (!alpha_agpgart_size) + return -ENOMEM; + aper = kmalloc(sizeof(*aper), GFP_KERNEL); if (aper == NULL) return -ENOMEM; aper->arena = agp->hose->sg_pci; - aper->pg_count = MARVEL_AGP_APER_SIZE / PAGE_SIZE; + aper->pg_count = alpha_agpgart_size / PAGE_SIZE; aper->pg_start = iommu_reserve(aper->arena, aper->pg_count, aper->pg_count - 1); diff -Nru a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c --- a/arch/alpha/kernel/core_titan.c Sun Feb 9 21:13:30 2003 +++ b/arch/alpha/kernel/core_titan.c Sun Feb 9 21:13:30 2003 @@ -580,8 +580,6 @@ #include #include -#define TITAN_AGP_APER_SIZE (64 * 1024 * 1024) - struct titan_agp_aperture { struct pci_iommu_arena *arena; long pg_start; @@ -593,12 +591,15 @@ { struct titan_agp_aperture *aper; + if (!alpha_agpgart_size) + return -ENOMEM; + aper = kmalloc(sizeof(struct titan_agp_aperture), GFP_KERNEL); if (aper == NULL) return -ENOMEM; aper->arena = agp->hose->sg_pci; - aper->pg_count = TITAN_AGP_APER_SIZE / PAGE_SIZE; + aper->pg_count = alpha_agpgart_size / PAGE_SIZE; aper->pg_start = iommu_reserve(aper->arena, aper->pg_count, aper->pg_count - 1); if (aper->pg_start < 0) { diff -Nru a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c --- a/arch/alpha/kernel/irq.c Sun Feb 9 21:13:35 2003 +++ b/arch/alpha/kernel/irq.c Sun Feb 9 21:13:35 2003 @@ -534,7 +534,7 @@ #else for (j = 0; j < NR_CPUS; j++) if (cpu_online(j)) - seq_printf(p, "%10u ", kstat_cpu(i).irqs[j]); + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %c%s", diff -Nru a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h --- a/arch/alpha/kernel/pci_impl.h Sun Feb 9 21:13:36 2003 +++ b/arch/alpha/kernel/pci_impl.h Sun Feb 9 21:13:36 2003 @@ -71,6 +71,8 @@ #define IRONGATE_DEFAULT_MEM_BASE ((256*8-16)*1024*1024) +#define DEFAULT_AGP_APER_SIZE (64*1024*1024) + /* * A small note about bridges and interrupts. The DECchip 21050 (and * later) adheres to the PCI-PCI bridge specification. This says that @@ -152,6 +154,8 @@ /* Indicate that we trust the console to configure things properly. */ extern int pci_probe_only; + +extern unsigned long alpha_agpgart_size; extern void common_init_pci(void); extern u8 common_swizzle(struct pci_dev *, u8 *); diff -Nru a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c --- a/arch/alpha/kernel/process.c Sun Feb 9 21:13:35 2003 +++ b/arch/alpha/kernel/process.c Sun Feb 9 21:13:35 2003 @@ -313,7 +313,7 @@ } /* - * fill in the user structure for a core dump.. + * Fill in the user structure for an ECOFF core dump. */ void dump_thread(struct pt_regs * pt, struct user * dump) @@ -373,12 +373,81 @@ memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8); } -int -dump_fpu(struct pt_regs * regs, elf_fpregset_t *r) +/* + * Fill in the user structure for a ELF core dump. + */ +void +dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti) { /* switch stack follows right below pt_regs: */ - struct switch_stack * sw = ((struct switch_stack *) regs) - 1; - memcpy(r, sw->fp, 32 * 8); + struct switch_stack * sw = ((struct switch_stack *) pt) - 1; + + dest[ 0] = pt->r0; + dest[ 1] = pt->r1; + dest[ 2] = pt->r2; + dest[ 3] = pt->r3; + dest[ 4] = pt->r4; + dest[ 5] = pt->r5; + dest[ 6] = pt->r6; + dest[ 7] = pt->r7; + dest[ 8] = pt->r8; + dest[ 9] = sw->r9; + dest[10] = sw->r10; + dest[11] = sw->r11; + dest[12] = sw->r12; + dest[13] = sw->r13; + dest[14] = sw->r14; + dest[15] = sw->r15; + dest[16] = pt->r16; + dest[17] = pt->r17; + dest[18] = pt->r18; + dest[19] = pt->r19; + dest[20] = pt->r20; + dest[21] = pt->r21; + dest[22] = pt->r22; + dest[23] = pt->r23; + dest[24] = pt->r24; + dest[25] = pt->r25; + dest[26] = pt->r26; + dest[27] = pt->r27; + dest[28] = pt->r28; + dest[29] = pt->gp; + dest[30] = rdusp(); + dest[31] = pt->pc; + + /* Once upon a time this was the PS value. Which is stupid + since that is always 8 for usermode. Usurped for the more + useful value of the thread's UNIQUE field. */ + dest[32] = ti->pcb.unique; +} + +int +dump_elf_task(elf_greg_t *dest, struct task_struct *task) +{ + struct thread_info *ti; + struct pt_regs *pt; + + ti = task->thread_info; + pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1; + + dump_elf_thread(dest, pt, ti); + + return 1; +} + +int +dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task) +{ + struct thread_info *ti; + struct pt_regs *pt; + struct switch_stack *sw; + + ti = task->thread_info; + pt = (struct pt_regs *)((unsigned long)ti + 2*PAGE_SIZE) - 1; + sw = (struct switch_stack *)pt - 1; + + memcpy(dest, sw->fp, 32 * 8); + return 1; } diff -Nru a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h --- a/arch/alpha/kernel/proto.h Sun Feb 9 21:13:29 2003 +++ b/arch/alpha/kernel/proto.h Sun Feb 9 21:13:29 2003 @@ -53,7 +53,6 @@ extern int marvel_cpuid_to_nid(int); extern unsigned long marvel_node_mem_start(int); extern unsigned long marvel_node_mem_size(int); -extern int marvel_srmcons_allowed(void); extern struct _alpha_agp_info *marvel_agp_info(void); struct io7 *marvel_find_io7(int pe); struct io7 *marvel_next_io7(struct io7 *prev); @@ -109,9 +108,15 @@ /* setup.c */ extern unsigned long srm_hae; extern int boot_cpuid; -extern int srmcons_output; + +/* srmcons.c */ +#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM) extern void register_srm_console(void); extern void unregister_srm_console(void); +#else +#define register_srm_console() +#define unregister_srm_console() +#endif /* smp.c */ extern void setup_smp(void); diff -Nru a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c --- a/arch/alpha/kernel/ptrace.c Sun Feb 9 21:13:35 2003 +++ b/arch/alpha/kernel/ptrace.c Sun Feb 9 21:13:35 2003 @@ -102,7 +102,9 @@ if (regno == 30) { addr = &task->thread_info->pcb.usp; - } else if (regno == 31 || regno > 64) { + } else if (regno == 65) { + addr = &task->thread_info->pcb.unique; + } else if (regno == 31 || regno > 65) { zero = 0; addr = &zero; } else { diff -Nru a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c --- a/arch/alpha/kernel/setup.c Sun Feb 9 21:13:29 2003 +++ b/arch/alpha/kernel/setup.c Sun Feb 9 21:13:29 2003 @@ -77,18 +77,25 @@ * "srmcons" specified in the boot command arguments allows us to * see kernel messages during the period of time before the true - * console device is "registered" during console_init(). As of this - * version (2.4.10), time_init() is the last Alpha-specific code - * called before console_init(), so we put "unregister" code - * there to prevent schizophrenic console behavior later... ;-} + * console device is "registered" during console_init(). + * As of this version (2.5.59), console_init() will call + * disable_early_printk() as the last action before initializing + * the console drivers. That's the last possible time srmcons can be + * unregistered without interfering with console behavior. * - * By default, OFF; set it with a bootcommand arg of "srmcons". + * By default, OFF; set it with a bootcommand arg of "srmcons" or + * "console=srm". The meaning of these two args is: + * "srmcons" - early callback prints + * "console=srm" - full callback based console, including early prints */ int srmcons_output = 0; /* Enforce a memory size limit; useful for testing. By default, none. */ unsigned long mem_size_limit = 0; +/* Set AGP GART window size (0 means disabled). */ +unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE; + #ifdef CONFIG_ALPHA_GENERIC struct alpha_machine_vector alpha_mv; int alpha_using_srm; @@ -461,57 +468,6 @@ #undef PFN_PHYS #undef PFN_MAX -#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM) -/* - * Manage the SRM callbacks as a "console". - */ -static struct console srmcons; - -void __init register_srm_console(void) -{ - register_console(&srmcons); -} - -void __init unregister_srm_console(void) -{ - unregister_console(&srmcons); -} - -static void srm_console_write(struct console *co, const char *s, - unsigned count) -{ - srm_printk(s); -} - -static kdev_t srm_console_device(struct console *c) -{ - /* Huh? */ - return mk_kdev(TTY_MAJOR, 64 + c->index); -} - -static int __init srm_console_setup(struct console *co, char *options) -{ - return 1; -} - -static struct console srmcons = { - .name = "srm0", - .write = srm_console_write, - .device = srm_console_device, - .setup = srm_console_setup, - .flags = CON_PRINTBUFFER | CON_ENABLED, /* fake it out */ - .index = -1, -}; - -#else -void __init register_srm_console(void) -{ -} -void __init unregister_srm_console(void) -{ -} -#endif - void __init setup_arch(char **cmdline_p) { @@ -574,7 +530,16 @@ continue; } if (strncmp(p, "srmcons", 7) == 0) { - srmcons_output = 1; + srmcons_output |= 1; + continue; + } + if (strncmp(p, "console=srm", 11) == 0) { + srmcons_output |= 2; + continue; + } + if (strncmp(p, "gartsize=", 9) == 0) { + alpha_agpgart_size = + get_mem_size_limit(p+9) << PAGE_SHIFT; continue; } } @@ -585,6 +550,13 @@ /* If we want SRM console printk echoing early, do it now. */ if (alpha_using_srm && srmcons_output) { register_srm_console(); + + /* + * If "console=srm" was specified, clear the srmcons_output + * flag now so that time.c won't unregister_srm_console + */ + if (srmcons_output & 2) + srmcons_output = 0; } #ifdef CONFIG_MAGIC_SYSRQ @@ -686,6 +658,15 @@ setup_smp(); #endif paging_init(); +} + +void __init +disable_early_printk(void) +{ + if (alpha_using_srm && srmcons_output) { + unregister_srm_console(); + srmcons_output = 0; + } } static char sys_unknown[] = "Unknown"; diff -Nru a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c --- a/arch/alpha/kernel/signal.c Sun Feb 9 21:13:32 2003 +++ b/arch/alpha/kernel/signal.c Sun Feb 9 21:13:32 2003 @@ -63,7 +63,7 @@ unsigned long block, unblock; newmask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); oldmask = current->blocked.sig[0]; unblock = oldmask & ~newmask; @@ -76,7 +76,7 @@ sigemptyset(¤t->blocked); current->blocked.sig[0] = newmask; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); (®s)->r0 = 0; /* special no error return */ } @@ -150,11 +150,11 @@ sigset_t oldset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); oldset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); while (1) { current->state = TASK_INTERRUPTIBLE; @@ -177,11 +177,11 @@ return -EFAULT; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); oldset = current->blocked; current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); while (1) { current->state = TASK_INTERRUPTIBLE; @@ -284,10 +284,10 @@ goto give_sigsegv; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(&frame->sc, regs, sw)) goto give_sigsegv; @@ -323,10 +323,10 @@ goto give_sigsegv; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw)) goto give_sigsegv; @@ -562,11 +562,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c --- a/arch/alpha/kernel/smp.c Sun Feb 9 21:13:30 2003 +++ b/arch/alpha/kernel/smp.c Sun Feb 9 21:13:30 2003 @@ -544,9 +544,6 @@ smp_tune_scheduling(boot_cpuid); smp_setup_percpu_timer(boot_cpuid); - /* We have already have the boot CPU online.. */ - set_bit(boot_cpuid, &cpu_online_map); - /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { cpu_present_mask = 1UL << boot_cpuid; @@ -574,7 +571,11 @@ void __devinit smp_prepare_boot_cpu(void) { + /* + * Mark the boot cpu (current cpu) as both present and online + */ set_bit(smp_processor_id(), &cpu_present_mask); + set_bit(smp_processor_id(), &cpu_online_map); } int __devinit diff -Nru a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/alpha/kernel/srmcons.c Sun Feb 9 21:13:38 2003 @@ -0,0 +1,361 @@ +/* + * linux/arch/alpha/kernel/srmcons.c + * + * Callback based driver for SRM Console console device. + * (TTY driver and console driver) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +static spinlock_t srmcons_callback_lock = SPIN_LOCK_UNLOCKED; +static int srm_is_registered_console = 0; + +/* + * The TTY driver + */ +#define MAX_SRM_CONSOLE_DEVICES 1 /* only support 1 console device */ + +static int srmcons_refcount; +static struct tty_struct *srmcons_table[MAX_SRM_CONSOLE_DEVICES]; +static struct termios *srmcons_termios[MAX_SRM_CONSOLE_DEVICES]; +static struct termios *srmcons_termios_locked[MAX_SRM_CONSOLE_DEVICES]; + +struct srmcons_private { + struct tty_struct *tty; + struct timer_list timer; + spinlock_t lock; +}; + +typedef union _srmcons_result { + struct { + unsigned long c :61; + unsigned long status :3; + } bits; + long as_long; +} srmcons_result; + +/* called with callback_lock held */ +static int +srmcons_do_receive_chars(struct tty_struct *tty) +{ + srmcons_result result; + int count = 0, loops = 0; + + do { + result.as_long = callback_getc(0); + if (result.bits.status < 2) { + tty_insert_flip_char(tty, (char)result.bits.c, 0); + count++; + } + } while((result.bits.status & 1) && (++loops < 10)); + + if (count) + tty_schedule_flip(tty); + + return count; +} + +static void +srmcons_receive_chars(unsigned long data) +{ + struct srmcons_private *srmconsp = (struct srmcons_private *)data; + unsigned long flags; + int incr = 10; + + local_irq_save(flags); + if (spin_trylock(&srmcons_callback_lock)) { + if (!srmcons_do_receive_chars(srmconsp->tty)) + incr = 100; + spin_unlock(&srmcons_callback_lock); + } + + spin_lock(&srmconsp->lock); + if (srmconsp->tty) { + srmconsp->timer.expires = jiffies + incr; + add_timer(&srmconsp->timer); + } + spin_unlock(&srmconsp->lock); + + local_irq_restore(flags); +} + +/* called with callback_lock held */ +static int +srmcons_do_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + unsigned char *str_cr = "\r"; + long c, remaining = count; + srmcons_result result; + unsigned char *cur; + int need_cr; + + for (cur = (unsigned char *)buf; remaining > 0; ) { + need_cr = 0; + /* + * Break it up into reasonable size chunks to allow a chance + * for input to get in + */ + for (c = 0; c < min_t(long, 128L, remaining) && !need_cr; c++) + if (cur[c] == '\n') + need_cr = 1; + + while (c > 0) { + result.as_long = callback_puts(0, cur, c); + c -= result.bits.c; + remaining -= result.bits.c; + cur += result.bits.c; + + /* + * Check for pending input iff a tty was provided + */ + if (tty) + srmcons_do_receive_chars(tty); + } + + while (need_cr) { + result.as_long = callback_puts(0, str_cr, 1); + if (result.bits.c > 0) + need_cr = 0; + } + } + return count; +} + +static int +srmcons_write(struct tty_struct *tty, int from_user, + const unsigned char *buf, int count) +{ + unsigned long flags; + + if (from_user) { + unsigned char tmp[512]; + int ret = 0; + size_t c; + + while ((c = count) > 0) { + if (c > sizeof(tmp)) + c = sizeof(tmp); + + c -= copy_from_user(tmp, buf, c); + + if (!c) { + printk("%s: EFAULT (count %d)\n", + __FUNCTION__, count); + return -EFAULT; + } + + spin_lock_irqsave(&srmcons_callback_lock, flags); + srmcons_do_write(tty, tmp, c); + spin_unlock_irqrestore(&srmcons_callback_lock, flags); + + buf += c; + count -= c; + ret += c; + } + + return ret; + } + + spin_lock_irqsave(&srmcons_callback_lock, flags); + srmcons_do_write(tty, buf, count); + spin_unlock_irqrestore(&srmcons_callback_lock, flags); + + return count; +} + +static int +srmcons_write_room(struct tty_struct *tty) +{ + return 512; +} + +static int +srmcons_chars_in_buffer(struct tty_struct *tty) +{ + return 0; +} + +static int +srmcons_get_private_struct(struct srmcons_private **ps) +{ + static struct srmcons_private *srmconsp = NULL; + static spinlock_t srmconsp_lock = SPIN_LOCK_UNLOCKED; + unsigned long flags; + int retval = 0; + + spin_lock_irqsave(&srmconsp_lock, flags); + + do { + if (srmconsp != NULL) { + *ps = srmconsp; + break; + } + + srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL); + if (srmconsp == NULL) { + retval = -ENOMEM; + break; + } + + srmconsp->tty = NULL; + srmconsp->lock = SPIN_LOCK_UNLOCKED; + init_timer(&srmconsp->timer); + + *ps = srmconsp; + } while(0); + + spin_unlock_irqrestore(&srmconsp_lock, flags); + + return retval; +} + +static int +srmcons_open(struct tty_struct *tty, struct file *filp) +{ + struct srmcons_private *srmconsp; + unsigned long flags; + int retval; + + retval = srmcons_get_private_struct(&srmconsp); + if (retval) + return retval; + + spin_lock_irqsave(&srmconsp->lock, flags); + + if (!srmconsp->tty) { + tty->driver_data = srmconsp; + + srmconsp->tty = tty; + srmconsp->timer.function = srmcons_receive_chars; + srmconsp->timer.data = (unsigned long)srmconsp; + srmconsp->timer.expires = jiffies + 10; + add_timer(&srmconsp->timer); + } + + spin_unlock_irqrestore(&srmconsp->lock, flags); + + return 0; +} + +static void +srmcons_close(struct tty_struct *tty, struct file *filp) +{ + struct srmcons_private *srmconsp = tty->driver_data; + unsigned long flags; + + spin_lock_irqsave(&srmconsp->lock, flags); + + if (tty->count == 1) { + srmconsp->tty = NULL; + del_timer(&srmconsp->timer); + } + + spin_unlock_irqrestore(&srmconsp->lock, flags); +} + + +static struct tty_driver srmcons_driver = { + .driver_name = "srm", + .name = "srm", + .magic = TTY_DRIVER_MAGIC, + .major = 0, /* dynamic */ + .minor_start = 0, + .num = MAX_SRM_CONSOLE_DEVICES, + .type = TTY_DRIVER_TYPE_SYSTEM, + .subtype = SYSTEM_TYPE_SYSCONS, + + .table = srmcons_table, + .termios = srmcons_termios, + .termios_locked = srmcons_termios_locked, + .refcount = &srmcons_refcount, + + .open = srmcons_open, + .close = srmcons_close, + .write = srmcons_write, + .write_room = srmcons_write_room, + .chars_in_buffer= srmcons_chars_in_buffer, +}; + +static int __init +srmcons_init(void) +{ + if (srm_is_registered_console) { + srmcons_driver.init_termios = tty_std_termios; + return tty_register_driver(&srmcons_driver); + } + + return -ENODEV; +} + +module_init(srmcons_init); + + +/* + * The console driver + */ +static void +srm_console_write(struct console *co, const char *s, unsigned count) +{ + unsigned long flags; + + spin_lock_irqsave(&srmcons_callback_lock, flags); + srmcons_do_write(NULL, s, count); + spin_unlock_irqrestore(&srmcons_callback_lock, flags); +} + +static kdev_t +srm_console_device(struct console *co) +{ + return mk_kdev(srmcons_driver.major, + srmcons_driver.minor_start + co->index); +} + +static int __init +srm_console_setup(struct console *co, char *options) +{ + return 0; +} + +static struct console srmcons = { + .name = "srm", + .write = srm_console_write, + .device = srm_console_device, + .setup = srm_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +void __init +register_srm_console(void) +{ + if (!srm_is_registered_console) { + callback_open_console(); + register_console(&srmcons); + srm_is_registered_console = 1; + } +} + +void __init +unregister_srm_console(void) +{ + if (srm_is_registered_console) { + callback_close_console(); + unregister_console(&srmcons); + srm_is_registered_console = 0; + } +} diff -Nru a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c --- a/arch/alpha/kernel/sys_nautilus.c Sun Feb 9 21:13:31 2003 +++ b/arch/alpha/kernel/sys_nautilus.c Sun Feb 9 21:13:31 2003 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -163,7 +164,7 @@ } printk(KERN_CRIT "NAUTILUS Machine check 0x%lx " - "[%s System Machine Check (NMI)]\n", + "[%s System Machine Check (NMI)]\n", vector, mchk_class); naut_sys_machine_check(vector, la_ptr, regs); @@ -174,6 +175,70 @@ mb(); } +extern void free_reserved_mem(void *, void *); + +void __init +nautilus_init_pci(void) +{ + struct pci_controller *hose = hose_head; + struct pci_bus *bus; + struct pci_dev *irongate; + unsigned long saved_io_start, saved_io_end; + unsigned long saved_mem_start, saved_mem_end; + unsigned long bus_align, bus_size, pci_mem; + unsigned long memtop = max_low_pfn << PAGE_SHIFT; + + /* Scan our single hose. */ + bus = pci_scan_bus(0, alpha_mv.pci_ops, hose); + hose->bus = bus; + hose->last_busno = bus->subordinate; + + /* We're going to size the root bus, so we must + - have a non-NULL PCI device associated with the bus + - preserve hose resources. */ + irongate = pci_find_slot(0, 0); + bus->self = irongate; + saved_io_start = bus->resource[0]->start; + saved_io_end = bus->resource[0]->end; + saved_mem_start = bus->resource[1]->start; + saved_mem_end = bus->resource[1]->end; + + pci_bus_size_bridges(bus); + + /* Don't care about IO. */ + bus->resource[0]->start = saved_io_start; + bus->resource[0]->end = saved_io_end; + + bus_align = bus->resource[1]->start; + bus_size = bus->resource[1]->end + 1 - bus_align; + /* Align to 16Mb. */ + if (bus_align < 0x1000000UL) + bus_align = 0x1000000UL; + + /* Restore hose MEM resource. */ + bus->resource[1]->start = saved_mem_start; + bus->resource[1]->end = saved_mem_end; + + pci_mem = (0x100000000UL - bus_size) & -bus_align; + + if (pci_mem < memtop && pci_mem > alpha_mv.min_mem_address) { + free_reserved_mem(__va(alpha_mv.min_mem_address), + __va(pci_mem)); + printk("nautilus_init_arch: %ldk freed\n", + (pci_mem - alpha_mv.min_mem_address) >> 10); + } + + alpha_mv.min_mem_address = pci_mem; + if ((IRONGATE0->dev_vendor >> 16) > 0x7006) /* Albacore? */ + IRONGATE0->pci_mem = pci_mem; + + pci_bus_assign_resources(bus); + + /* To break the loop in common_swizzle() */ + bus->self = NULL; + + pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); +} /* * The System Vectors @@ -196,7 +261,7 @@ .init_arch = irongate_init_arch, .init_irq = nautilus_init_irq, .init_rtc = common_init_rtc, - .init_pci = common_init_pci, + .init_pci = nautilus_init_pci, .kill_arch = nautilus_kill_arch, .pci_map_irq = nautilus_map_irq, .pci_swizzle = common_swizzle, diff -Nru a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c --- a/arch/alpha/kernel/time.c Sun Feb 9 21:13:32 2003 +++ b/arch/alpha/kernel/time.c Sun Feb 9 21:13:32 2003 @@ -44,6 +44,7 @@ #include #include +#include #include #include "proto.h" @@ -51,7 +52,6 @@ u64 jiffies_64; -extern rwlock_t xtime_lock; extern unsigned long wall_jiffies; /* kernel/timer.c */ static int set_rtc_mmss(unsigned long); @@ -106,7 +106,7 @@ alpha_do_profile(regs->pc); #endif - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); /* * Calculate how many ticks have passed since the last update, @@ -138,7 +138,7 @@ state.last_rtc_update = xtime.tv_sec - (tmp ? 600 : 0); } - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } void @@ -383,21 +383,6 @@ /* Startup the timer source. */ alpha_mv.init_rtc(); - - /* - * If we had wanted SRM console printk echoing early, undo it now. - * - * "srmcons" specified in the boot command arguments allows us to - * see kernel messages during the period of time before the true - * console device is "registered" during console_init(). As of this - * version (2.4.10), time_init() is the last Alpha-specific code - * called before console_init(), so we put this "unregister" code - * here to prevent schizophrenic console behavior later... ;-} - */ - if (alpha_using_srm && srmcons_output) { - unregister_srm_console(); - srmcons_output = 0; - } } /* @@ -410,18 +395,20 @@ void do_gettimeofday(struct timeval *tv) { - unsigned long sec, usec, lost, flags; + unsigned long flags; + unsigned long sec, usec, lost, seq; unsigned long delta_cycles, delta_usec, partial_tick; - read_lock_irqsave(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); - delta_cycles = rpcc() - state.last_time; - sec = xtime.tv_sec; - usec = (xtime.tv_nsec / 1000); - partial_tick = state.partial_tick; - lost = jiffies - wall_jiffies; + delta_cycles = rpcc() - state.last_time; + sec = xtime.tv_sec; + usec = (xtime.tv_nsec / 1000); + partial_tick = state.partial_tick; + lost = jiffies - wall_jiffies; - read_unlock_irqrestore(&xtime_lock, flags); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); #ifdef CONFIG_SMP /* Until and unless we figure out how to get cpu cycle counters @@ -463,7 +450,7 @@ unsigned long delta_usec; long sec, usec; - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* The offset that is added into time in do_gettimeofday above must be subtracted out here to keep a coherent view of the @@ -494,7 +481,7 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig --- a/arch/arm/Kconfig Sun Feb 9 21:13:32 2003 +++ b/arch/arm/Kconfig Sun Feb 9 21:13:32 2003 @@ -577,7 +577,7 @@ your machine has an FPA or floating point co-processor podule. It is also possible to say M to build the emulator as a module - (nwfpe.o) or indeed to leave it out altogether. However, unless you + (nwfpe) or indeed to leave it out altogether. However, unless you know what you are doing this can easily render your machine unbootable. Saying Y is the safe option. @@ -599,7 +599,7 @@ choose NWFPE. It is also possible to say M to build the emulator as a module - (fastfpe.o). But keep in mind that you should only load the FP + (fastfpe). But keep in mind that you should only load the FP emulator early in the bootup. You should never change from NWFPE to FASTFPE or vice versa in an active system! @@ -654,7 +654,7 @@ QMAGIC support" then you'll have to say Y here. You may answer M to compile a.out support as a module and later load the module when you want to use a program or library in a.out format. The module will be - called binfmt_aout.o. Saying M or N here is dangerous though, + called binfmt_aout. Saying M or N here is dangerous though, because some crucial programs on your system might still be in A.OUT format. @@ -684,7 +684,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config BINFMT_MISC @@ -709,7 +709,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. config PM @@ -804,7 +804,7 @@ To compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module will be called - apm.o. + apm. config ARTHUR tristate "RISC OS personality" @@ -814,7 +814,7 @@ Acorn RISC OS/Arthur binaries under Linux. This code is still very experimental; if this sounds frightening, say N and sleep in peace. You can also say M here to compile this support as a module (which - will be called arthur.o). + will be called arthur). config CMDLINE string "Default kernel command string" @@ -946,7 +946,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -973,7 +973,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -1036,7 +1036,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile --- a/arch/arm/Makefile Sun Feb 9 21:13:31 2003 +++ b/arch/arm/Makefile Sun Feb 9 21:13:31 2003 @@ -17,7 +17,7 @@ CFLAGS :=$(CFLAGS:-O2=-Os) ifeq ($(CONFIG_FRAME_POINTER),y) -CFLAGS :=$(CFLAGS:-fomit-frame-pointer=-mapcs -mno-sched-prolog) +CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif ifeq ($(CONFIG_DEBUG_INFO),y) @@ -36,7 +36,7 @@ # series of macros. arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 -arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 -march=armv5 +arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 -march=armv5te arch-$(CONFIG_CPU_XSCALE) :=-D__LINUX_ARM_ARCH__=5 -march=armv4 -Wa,-mxscale #-march=armv5te # This selects how we optimise for the processor. @@ -61,7 +61,7 @@ ifeq ($(CONFIG_CPU_26),y) PROCESSOR := armo -HEAD := arch/arm/mach-arc/head.o arch/arm/kernel/init_task.o +head-y := arch/arm/mach-arc/head.o arch/arm/kernel/init_task.o LDFLAGS_BLOB += --oformat elf26-littlearm ifeq ($(CONFIG_ROM_KERNEL),y) DATAADDR := 0x02080000 @@ -73,7 +73,7 @@ ifeq ($(CONFIG_CPU_32),y) PROCESSOR := armv -HEAD := arch/arm/kernel/head.o arch/arm/kernel/init_task.o +head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o LDFLAGS_BLOB += --oformat elf32-littlearm textaddr-y := 0xC0008000 endif @@ -124,10 +124,10 @@ endif # If we have a machine-specific directory, then include it in the build. +core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ ifneq ($(MACHINE),) core-y += arch/arm/mach-$(MACHINE)/ endif -core-y += arch/arm/kernel/ arch/arm/mm/ core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/ core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) @@ -181,7 +181,6 @@ include/asm-arm/mach-types.h # We use MRPROPER_FILES and CLEAN_FILES now -archmrproper: archclean: $(Q)$(MAKE) $(clean)=$(boot) diff -Nru a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S --- a/arch/arm/boot/compressed/head.S Sun Feb 9 21:13:35 2003 +++ b/arch/arm/boot/compressed/head.S Sun Feb 9 21:13:35 2003 @@ -664,5 +664,5 @@ reloc_end: .align - .section ".stack", "aw" + .section ".stack", "w" user_stack: .space 4096 diff -Nru a/arch/arm/common/Makefile b/arch/arm/common/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/common/Makefile Sun Feb 9 21:13:37 2003 @@ -0,0 +1,8 @@ +# +# Makefile for the linux kernel. +# + +obj-$(CONFIG_SA1111) += sa1111.o sa1111-pcibuf.o sa1111-pcipool.o + +obj-$(CONFIG_PCI_HOST_PLX90X0) += plx90x0.o +obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o diff -Nru a/arch/arm/common/plx90x0.c b/arch/arm/common/plx90x0.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/common/plx90x0.c Sun Feb 9 21:13:29 2003 @@ -0,0 +1,178 @@ +/* + * Driver for PLX Technology PCI9000-series host bridge. + * + * Copyright (C) 1997, 1998, 1999, 2000 FutureTV Labs Ltd + */ + +/* + * 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. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * Since the following functions are all very similar, the common parts + * are pulled out into these macros. + */ + +#define PLX_CLEAR_CONFIG \ + __raw_writel(0, PLX_BASE + 0xac); \ + local_irq_restore(flags); } + +#define PLX_SET_CONFIG \ + { unsigned long flags; \ + local_irq_save(flags); \ + __raw_writel((1<<31 | (bus->number << 16) \ + | (devfn << 8) | (where & ~3) \ + | ((bus->number == 0)?0:1)), PLX_BASE + 0xac); \ + +#define PLX_CONFIG_WRITE(size) \ + PLX_SET_CONFIG \ + __raw_write##size(value, PCIO_BASE + (where & 3)); \ + if (__raw_readw(PLX_BASE + 0x6) & 0x2000) \ + __raw_writew(0x2000, PLX_BASE + 0x6); \ + PLX_CLEAR_CONFIG \ + return PCIBIOS_SUCCESSFUL; + +#define PLX_CONFIG_READ(size) \ + PLX_SET_CONFIG \ + *value = __raw_read##size(PCIO_BASE + (where & 3)); \ + if (__raw_readw(PLX_BASE + 0x6) & 0x2000) { \ + __raw_writew(0x2000, PLX_BASE + 0x6); \ + *value = 0xffffffffUL; \ + } \ + PLX_CLEAR_CONFIG \ + return PCIBIOS_SUCCESSFUL; + +/* Configuration space access routines */ + +static int +plx90x0_read_config (struct pci_bus *bus, unsigned int devfn, int where, + int where, int size, u32 *value) +{ + switch (size) { + case 1: + PLX_CONFIG_READ(b) + break; + case 2: + PLX_CONFIG_READ(w) + break; + case 4: + PLX_CONFIG_READ(l) + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static int +plx90x0_write_config (struct pci_bus *bus, unsigned int devfn, int where, + int where, int size, u32 value) +{ + switch (size) { + case 1: + PLX_CONFIG_WRITE(b) + break; + case 2: + PLX_CONFIG_WRITE(w) + break; + case 4: + PLX_CONFIG_WRITE(l) + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops plx90x0_ops = +{ + .read = plx90x0_read_config, + .write = plx90x0_write_config, +}; + +static void +plx_syserr_handler(int irq, void *handle, struct pt_regs *regs) +{ + printk("PLX90x0: machine check %04x (pc=%08lx)\n", + readw(PLX_BASE + 6), regs->ARM_pc); + __raw_writew(0xf000, PLX_BASE + 6); +} + +/* + * Initialise the PCI system. + */ + +void __init +plx90x0_init(struct arm_sysdata *sysdata) +{ + static const unsigned long int base = PLX_BASE; + char *what; + unsigned long bar = (unsigned long)virt_to_bus((void *)PAGE_OFFSET); + + /* Have a sniff around and see which PLX device is present. */ + unsigned long id = __raw_readl(base + 0xf0); + +#if 0 + /* This check was a good idea, but can fail. The PLX9060 puts no + default value in these registers unless NB# is asserted (which it + isn't on these cards). */ + if ((id & 0xffff) != PCI_VENDOR_ID_PLX) + return; /* Nothing found */ +#endif + + /* Found one - now work out what it is. */ + switch (id >> 16) { + case 0: /* PCI_DEVICE_ID_PLX_9060 */ + what = "PCI9060"; + break; + case PCI_DEVICE_ID_PLX_9060ES: + what = "PCI9060ES"; + break; + case PCI_DEVICE_ID_PLX_9060SD: + what = "PCI9060SD"; /* uhuhh.. */ + break; + case PCI_DEVICE_ID_PLX_9080: + what = "PCI9080"; + break; + default: + printk("PCI: Unknown PLX device %04lx found -- ignored.\n", + id >> 16); + return; + } + + printk("PCI: PLX Technology %s host bridge found.\n", what); + + /* Now set it up for both master and slave accesses. */ + __raw_writel(0xffff0147, base + 0x4); + __raw_writeb(32, base + 0xd); + __raw_writel(0x8 | bar, base + 0x18); + __raw_writel(0xf8000008, base + 0x80); + __raw_writel(0x40000001, base + 0x84); + __raw_writel(0, base + 0x88); + __raw_writel(0, base + 0x8c); + __raw_writel(0x11, base + 0x94); + __raw_writel(0xC3 + (4 << 28) + + (8 << 11) + (1 << 10) + + (1 << 24), base + 0x98); + __raw_writel(0xC0000000, base + 0x9c); + __raw_writel(PLX_MEM_START, base + 0xa0); + __raw_writel(PLX_IO_START, base + 0xa4); + __raw_writel(0x3, base + 0xa8); + __raw_writel(0, base + 0xac); + __raw_writel(0x10001, base + 0xe8); + __raw_writel(0x8000767e, base + 0xec); + + request_irq(IRQ_SYSERR, plx_syserr_handler, 0, + "system error", NULL); + + pci_scan_bus(0, &plx90x0_ops, sysdata); +} diff -Nru a/arch/arm/common/sa1111-pcibuf.c b/arch/arm/common/sa1111-pcibuf.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/common/sa1111-pcibuf.c Sun Feb 9 21:13:28 2003 @@ -0,0 +1,551 @@ +/* + * linux/arch/arm/mach-sa1100/pci-sa1111.c + * + * Special pci_{map/unmap/dma_sync}_* routines for SA-1111. + * + * These functions utilize bouncer buffers to compensate for a bug in + * the SA-1111 hardware which don't allow DMA to/from addresses + * certain addresses above 1MB. + * + * Re-written by Christopher Hoover + * Original version by Brad Parker (brad@heeltoe.com) + * + * Copyright (C) 2002 Hewlett Packard Company. + * + * 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 +#include + +//#define DEBUG +#ifdef DEBUG +#define DPRINTK(...) do { printk(KERN_DEBUG __VA_ARGS__); } while (0) +#else +#define DPRINTK(...) do { } while (0) +#endif + +//#define STATS +#ifdef STATS +#define DO_STATS(X) do { X ; } while (0) +#else +#define DO_STATS(X) do { } while (0) +#endif + +/* ************************************************** */ + +struct safe_buffer { + struct list_head node; + + /* original request */ + void *ptr; + size_t size; + int direction; + + /* safe buffer info */ + struct pci_pool *pool; + void *safe; + dma_addr_t safe_dma_addr; +}; + +LIST_HEAD(safe_buffers); + + +#define SIZE_SMALL 1024 +#define SIZE_LARGE (4*1024) + +static struct pci_pool *small_buffer_pool, *large_buffer_pool; + +#ifdef STATS +static unsigned long sbp_allocs __initdata = 0; +static unsigned long lbp_allocs __initdata = 0; +static unsigned long total_allocs __initdata= 0; + +static void print_alloc_stats(void) +{ + printk(KERN_INFO + "sa1111_pcibuf: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n", + sbp_allocs, lbp_allocs, + total_allocs - sbp_allocs - lbp_allocs, total_allocs); +} +#endif + +static int __init +create_safe_buffer_pools(void) +{ + small_buffer_pool = pci_pool_create("sa1111_small_dma_buffer", + SA1111_FAKE_PCIDEV, + SIZE_SMALL, + 0 /* byte alignment */, + 0 /* no page-crossing issues */); + if (0 == small_buffer_pool) { + printk(KERN_ERR + "sa1111_pcibuf: could not allocate small pci pool\n"); + return -1; + } + + large_buffer_pool = pci_pool_create("sa1111_large_dma_buffer", + SA1111_FAKE_PCIDEV, + SIZE_LARGE, + 0 /* byte alignment */, + 0 /* no page-crossing issues */); + if (0 == large_buffer_pool) { + printk(KERN_ERR + "sa1111_pcibuf: could not allocate large pci pool\n"); + pci_pool_destroy(small_buffer_pool); + small_buffer_pool = 0; + return -1; + } + + printk(KERN_INFO + "sa1111_pcibuf: buffer sizes: small=%u, large=%u\n", + SIZE_SMALL, SIZE_LARGE); + + return 0; +} + +static void __exit +destroy_safe_buffer_pools(void) +{ + if (small_buffer_pool) + pci_pool_destroy(small_buffer_pool); + if (large_buffer_pool) + pci_pool_destroy(large_buffer_pool); + + small_buffer_pool = large_buffer_pool = 0; +} + + +/* allocate a 'safe' buffer and keep track of it */ +static struct safe_buffer * +alloc_safe_buffer(void *ptr, size_t size, int direction) +{ + struct safe_buffer *buf; + struct pci_pool *pool; + void *safe; + dma_addr_t safe_dma_addr; + + DPRINTK("%s(ptr=%p, size=%d, direction=%d)\n", + __func__, ptr, size, direction); + + DO_STATS ( total_allocs++ ); + + buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC); + if (buf == 0) { + printk(KERN_WARNING "%s: kmalloc failed\n", __func__); + return 0; + } + + if (size <= SIZE_SMALL) { + pool = small_buffer_pool; + safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); + + DO_STATS ( sbp_allocs++ ); + } else if (size <= SIZE_LARGE) { + pool = large_buffer_pool; + safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); + + DO_STATS ( lbp_allocs++ ); + } else { + pool = 0; + safe = pci_alloc_consistent(SA1111_FAKE_PCIDEV, size, + &safe_dma_addr); + } + + if (safe == 0) { + printk(KERN_WARNING + "%s: could not alloc dma memory (size=%d)\n", + __func__, size); + kfree(buf); + return 0; + } + +#ifdef STATS + if (total_allocs % 1000 == 0) + print_alloc_stats(); +#endif + + BUG_ON(sa1111_check_dma_bug(safe_dma_addr)); // paranoia + + buf->ptr = ptr; + buf->size = size; + buf->direction = direction; + buf->pool = pool; + buf->safe = safe; + buf->safe_dma_addr = safe_dma_addr; + + MOD_INC_USE_COUNT; + list_add(&buf->node, &safe_buffers); + + return buf; +} + +/* determine if a buffer is from our "safe" pool */ +static struct safe_buffer * +find_safe_buffer(dma_addr_t safe_dma_addr) +{ + struct list_head *entry; + + list_for_each(entry, &safe_buffers) { + struct safe_buffer *b = + list_entry(entry, struct safe_buffer, node); + + if (b->safe_dma_addr == safe_dma_addr) { + return b; + } + } + + return 0; +} + +static void +free_safe_buffer(struct safe_buffer *buf) +{ + DPRINTK("%s(buf=%p)\n", __func__, buf); + + list_del(&buf->node); + + if (buf->pool) + pci_pool_free(buf->pool, buf->safe, buf->safe_dma_addr); + else + pci_free_consistent(SA1111_FAKE_PCIDEV, buf->size, buf->safe, + buf->safe_dma_addr); + kfree(buf); + + MOD_DEC_USE_COUNT; +} + +static inline int +dma_range_is_safe(dma_addr_t addr, size_t size) +{ + unsigned int physaddr = SA1111_DMA_ADDR((unsigned int) addr); + + /* Any address within one megabyte of the start of the target + * bank will be OK. This is an overly conservative test: + * other addresses can be OK depending on the dram + * configuration. (See sa1111.c:sa1111_check_dma_bug() * for + * details.) + * + * We take care to ensure the entire dma region is within + * the safe range. + */ + + return ((physaddr + size - 1) < (1<<20)); +} + +/* ************************************************** */ + +#ifdef STATS +static unsigned long map_op_count __initdata = 0; +static unsigned long bounce_count __initdata = 0; + +static void print_map_stats(void) +{ + printk(KERN_INFO + "sa1111_pcibuf: map_op_count=%lu, bounce_count=%lu\n", + map_op_count, bounce_count); +} +#endif + +static dma_addr_t +map_single(void *ptr, size_t size, int direction) +{ + dma_addr_t dma_addr; + + DO_STATS ( map_op_count++ ); + + dma_addr = virt_to_bus(ptr); + + if (!dma_range_is_safe(dma_addr, size)) { + struct safe_buffer *buf; + + DO_STATS ( bounce_count++ ) ; + + buf = alloc_safe_buffer(ptr, size, direction); + if (buf == 0) { + printk(KERN_ERR + "%s: unable to map unsafe buffer %p!\n", + __func__, ptr); + return 0; + } + + DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", + __func__, + buf->ptr, (void *) virt_to_bus(buf->ptr), + buf->safe, (void *) buf->safe_dma_addr); + + if ((direction == PCI_DMA_TODEVICE) || + (direction == PCI_DMA_BIDIRECTIONAL)) { + DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n", + __func__, ptr, buf->safe, size); + memcpy(buf->safe, ptr, size); + } + consistent_sync(buf->safe, size, direction); + + dma_addr = buf->safe_dma_addr; + } else { + consistent_sync(ptr, size, direction); + } + +#ifdef STATS + if (map_op_count % 1000 == 0) + print_map_stats(); +#endif + + return dma_addr; +} + +static void +unmap_single(dma_addr_t dma_addr, size_t size, int direction) +{ + struct safe_buffer *buf; + + buf = find_safe_buffer(dma_addr); + + if (buf) { + BUG_ON(buf->size != size); + BUG_ON(buf->direction != direction); + + DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", + __func__, + buf->ptr, (void *) virt_to_bus(buf->ptr), + buf->safe, (void *) buf->safe_dma_addr); + + + DO_STATS ( bounce_count++ ); + + if ((direction == PCI_DMA_FROMDEVICE) || + (direction == PCI_DMA_BIDIRECTIONAL)) { + DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n", + __func__, buf->safe, buf->ptr, size); + memcpy(buf->ptr, buf->safe, size); + } + free_safe_buffer(buf); + } +} + +static void +sync_single(dma_addr_t dma_addr, size_t size, int direction) +{ + struct safe_buffer *buf; + + buf = find_safe_buffer(dma_addr); + + if (buf) { + BUG_ON(buf->size != size); + BUG_ON(buf->direction != direction); + + DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", + __func__, + buf->ptr, (void *) virt_to_bus(buf->ptr), + buf->safe, (void *) buf->safe_dma_addr); + + DO_STATS ( bounce_count++ ); + + switch (direction) { + case PCI_DMA_FROMDEVICE: + DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n", + __func__, buf->safe, buf->ptr, size); + memcpy(buf->ptr, buf->safe, size); + break; + case PCI_DMA_TODEVICE: + DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n", + __func__,buf->ptr, buf->safe, size); + memcpy(buf->safe, buf->ptr, size); + break; + case PCI_DMA_BIDIRECTIONAL: + BUG(); /* is this allowed? what does it mean? */ + default: + BUG(); + } + consistent_sync(buf->safe, size, direction); + } else { + consistent_sync(bus_to_virt(dma_addr), size, direction); + } +} + +/* ************************************************** */ + +/* + * see if a buffer address is in an 'unsafe' range. if it is + * allocate a 'safe' buffer and copy the unsafe buffer into it. + * substitute the safe buffer for the unsafe one. + * (basically move the buffer from an unsafe area to a safe one) + */ +dma_addr_t +sa1111_map_single(void *ptr, size_t size, int direction) +{ + unsigned long flags; + dma_addr_t dma_addr; + + DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n", + __func__, ptr, size, direction); + + BUG_ON(direction == PCI_DMA_NONE); + + local_irq_save(flags); + + dma_addr = map_single(ptr, size, direction); + + local_irq_restore(flags); + + return dma_addr; +} + +/* + * see if a mapped address was really a "safe" buffer and if so, copy + * the data from the safe buffer back to the unsafe buffer and free up + * the safe buffer. (basically return things back to the way they + * should be) + */ + +void +sa1111_unmap_single(dma_addr_t dma_addr, size_t size, int direction) +{ + unsigned long flags; + + DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n", + __func__, (void *) dma_addr, size, direction); + + BUG_ON(direction == PCI_DMA_NONE); + + local_irq_save(flags); + + unmap_single(dma_addr, size, direction); + + local_irq_restore(flags); +} + +int +sa1111_map_sg(struct scatterlist *sg, int nents, int direction) +{ + unsigned long flags; + int i; + + DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n", + __func__, sg, nents, direction); + + BUG_ON(direction == PCI_DMA_NONE); + + local_irq_save(flags); + + for (i = 0; i < nents; i++, sg++) { + struct page *page = sg->page; + unsigned int offset = sg->offset; + unsigned int length = sg->length; + void *ptr = page_address(page) + offset; + + sg->dma_address = + map_single(ptr, length, direction); + } + + local_irq_restore(flags); + + return nents; +} + +void +sa1111_unmap_sg(struct scatterlist *sg, int nents, int direction) +{ + unsigned long flags; + int i; + + DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n", + __func__, sg, nents, direction); + + BUG_ON(direction == PCI_DMA_NONE); + + local_irq_save(flags); + + for (i = 0; i < nents; i++, sg++) { + dma_addr_t dma_addr = sg->dma_address; + unsigned int length = sg->length; + + unmap_single(dma_addr, length, direction); + } + + local_irq_restore(flags); +} + +void +sa1111_dma_sync_single(dma_addr_t dma_addr, size_t size, int direction) +{ + unsigned long flags; + + DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n", + __func__, (void *) dma_addr, size, direction); + + local_irq_save(flags); + + sync_single(dma_addr, size, direction); + + local_irq_restore(flags); +} + +void +sa1111_dma_sync_sg(struct scatterlist *sg, int nents, int direction) +{ + unsigned long flags; + int i; + + DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n", + __func__, sg, nents, direction); + + BUG_ON(direction == PCI_DMA_NONE); + + local_irq_save(flags); + + for (i = 0; i < nents; i++, sg++) { + dma_addr_t dma_addr = sg->dma_address; + unsigned int length = sg->length; + + sync_single(dma_addr, length, direction); + } + + local_irq_restore(flags); +} + +EXPORT_SYMBOL(sa1111_map_single); +EXPORT_SYMBOL(sa1111_unmap_single); +EXPORT_SYMBOL(sa1111_map_sg); +EXPORT_SYMBOL(sa1111_unmap_sg); +EXPORT_SYMBOL(sa1111_dma_sync_single); +EXPORT_SYMBOL(sa1111_dma_sync_sg); + +/* **************************************** */ + +static int __init sa1111_pcibuf_init(void) +{ + int ret; + + printk(KERN_DEBUG + "sa1111_pcibuf: initializing SA-1111 DMA workaround\n"); + + ret = create_safe_buffer_pools(); + + return ret; +} +module_init(sa1111_pcibuf_init); + +static void __exit sa1111_pcibuf_exit(void) +{ + BUG_ON(!list_empty(&safe_buffers)); + +#ifdef STATS + print_alloc_stats(); + print_map_stats(); +#endif + + destroy_safe_buffer_pools(); +} +module_exit(sa1111_pcibuf_exit); + +MODULE_AUTHOR("Christopher Hoover "); +MODULE_DESCRIPTION("Special pci_{map/unmap/dma_sync}_* routines for SA-1111."); +MODULE_LICENSE("GPL"); diff -Nru a/arch/arm/common/sa1111-pcipool.c b/arch/arm/common/sa1111-pcipool.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/common/sa1111-pcipool.c Sun Feb 9 21:13:34 2003 @@ -0,0 +1,390 @@ +/* + NOTE: + + this code was lifted straight out of drivers/pci/pci.c; + when compiling for the Intel StrongARM SA-1110/SA-1111 the + usb-ohci.c driver needs these routines even when the architecture + has no pci bus... +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * Pool allocator ... wraps the pci_alloc_consistent page allocator, so + * small blocks are easily used by drivers for bus mastering controllers. + * This should probably be sharing the guts of the slab allocator. + */ + +struct pci_pool { /* the pool */ + struct list_head page_list; + spinlock_t lock; + size_t blocks_per_page; + size_t size; + struct pci_dev *dev; + size_t allocation; + char name [32]; + wait_queue_head_t waitq; +}; + +struct pci_page { /* cacheable header for 'allocation' bytes */ + struct list_head page_list; + void *vaddr; + dma_addr_t dma; + unsigned long bitmap [0]; +}; + +#define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) +#define POOL_POISON_BYTE 0xa7 + +// #define CONFIG_PCIPOOL_DEBUG + +static inline const char *slot_name(const struct pci_pool *pool) +{ + const struct pci_dev *pdev = pool->dev; + + if (pdev == 0) + return "[0]"; + + else if (pcidev_is_sa1111(pdev)) + return "[SA-1111]"; + else + return pdev->slot_name; +} + + +/** + * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma. + * @name: name of pool, for diagnostics + * @pdev: pci device that will be doing the DMA + * @size: size of the blocks in this pool. + * @align: alignment requirement for blocks; must be a power of two + * @allocation: returned blocks won't cross this boundary (or zero) + * Context: !in_interrupt() + * + * Returns a pci allocation pool with the requested characteristics, or + * null if one can't be created. Given one of these pools, pci_pool_alloc() + * may be used to allocate memory. Such memory will all have "consistent" + * DMA mappings, accessible by the device and its driver without using + * cache flushing primitives. The actual size of blocks allocated may be + * larger than requested because of alignment. + * + * If allocation is nonzero, objects returned from pci_pool_alloc() won't + * cross that size boundary. This is useful for devices which have + * addressing restrictions on individual DMA transfers, such as not crossing + * boundaries of 4KBytes. + */ +struct pci_pool * +pci_pool_create (const char *name, struct pci_dev *pdev, + size_t size, size_t align, size_t allocation) +{ + struct pci_pool *retval; + + if (align == 0) + align = 1; + if (size == 0) + return 0; + else if (size < align) + size = align; + else if ((size % align) != 0) { + size += align + 1; + size &= ~(align - 1); + } + + if (allocation == 0) { + if (PAGE_SIZE < size) + allocation = size; + else + allocation = PAGE_SIZE; + // FIXME: round up for less fragmentation + } else if (allocation < size) + return 0; + + if (!(retval = kmalloc (sizeof *retval, SLAB_KERNEL))) + return retval; + + strncpy (retval->name, name, sizeof retval->name); + retval->name [sizeof retval->name - 1] = 0; + + retval->dev = pdev; + INIT_LIST_HEAD (&retval->page_list); + spin_lock_init (&retval->lock); + retval->size = size; + retval->allocation = allocation; + retval->blocks_per_page = allocation / size; + init_waitqueue_head (&retval->waitq); + +#ifdef CONFIG_PCIPOOL_DEBUG + printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n", + slot_name(retval), retval->name, size, + retval->blocks_per_page, allocation); +#endif + + return retval; +} + + +static struct pci_page * +pool_alloc_page (struct pci_pool *pool, int mem_flags) +{ + struct pci_page *page; + int mapsize; + + mapsize = pool->blocks_per_page; + mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG; + mapsize *= sizeof (long); + + page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags); + if (!page) + return 0; + page->vaddr = pci_alloc_consistent (pool->dev, + pool->allocation, + &page->dma); + if (page->vaddr) { + memset (page->bitmap, 0xff, mapsize); // bit set == free +#ifdef CONFIG_DEBUG_SLAB + memset (page->vaddr, POOL_POISON_BYTE, pool->allocation); +#endif + list_add (&page->page_list, &pool->page_list); + } else { + kfree (page); + page = 0; + } + return page; +} + + +static inline int +is_page_busy (int blocks, unsigned long *bitmap) +{ + while (blocks > 0) { + if (*bitmap++ != ~0UL) + return 1; + blocks -= BITS_PER_LONG; + } + return 0; +} + +static void +pool_free_page (struct pci_pool *pool, struct pci_page *page) +{ + dma_addr_t dma = page->dma; + +#ifdef CONFIG_DEBUG_SLAB + memset (page->vaddr, POOL_POISON_BYTE, pool->allocation); +#endif + pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma); + list_del (&page->page_list); + kfree (page); +} + + +/** + * pci_pool_destroy - destroys a pool of pci memory blocks. + * @pool: pci pool that will be destroyed + * + * Caller guarantees that no more memory from the pool is in use, + * and that nothing will try to use the pool after this call. + */ +void +pci_pool_destroy (struct pci_pool *pool) +{ + unsigned long flags; + +#ifdef CONFIG_PCIPOOL_DEBUG + printk (KERN_DEBUG "pcipool destroy %s/%s\n", + slot_name(pool), pool->name); +#endif + + spin_lock_irqsave (&pool->lock, flags); + while (!list_empty (&pool->page_list)) { + struct pci_page *page; + page = list_entry (pool->page_list.next, + struct pci_page, page_list); + if (is_page_busy (pool->blocks_per_page, page->bitmap)) { + printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n", + slot_name(pool), pool->name, page->vaddr); + /* leak the still-in-use consistent memory */ + list_del (&page->page_list); + kfree (page); + } else + pool_free_page (pool, page); + } + spin_unlock_irqrestore (&pool->lock, flags); + kfree (pool); +} + + +/** + * pci_pool_alloc - get a block of consistent memory + * @pool: pci pool that will produce the block + * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC + * @handle: pointer to dma address of block + * + * This returns the kernel virtual address of a currently unused block, + * and reports its dma address through the handle. + * If such a memory block can't be allocated, null is returned. + */ +void * +pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle) +{ + unsigned long flags; + struct list_head *entry; + struct pci_page *page; + int map, block; + size_t offset; + void *retval; + +restart: + spin_lock_irqsave (&pool->lock, flags); + list_for_each (entry, &pool->page_list) { + int i; + page = list_entry (entry, struct pci_page, page_list); + /* only cachable accesses here ... */ + for (map = 0, i = 0; + i < pool->blocks_per_page; + i += BITS_PER_LONG, map++) { + if (page->bitmap [map] == 0) + continue; + block = ffz (~ page->bitmap [map]); + if ((i + block) < pool->blocks_per_page) { + clear_bit (block, &page->bitmap [map]); + offset = (BITS_PER_LONG * map) + block; + offset *= pool->size; + goto ready; + } + } + } + if (!(page = pool_alloc_page (pool, mem_flags))) { + if (mem_flags == SLAB_KERNEL) { + DECLARE_WAITQUEUE (wait, current); + + current->state = TASK_INTERRUPTIBLE; + add_wait_queue (&pool->waitq, &wait); + spin_unlock_irqrestore (&pool->lock, flags); + + schedule_timeout (POOL_TIMEOUT_JIFFIES); + + current->state = TASK_RUNNING; + remove_wait_queue (&pool->waitq, &wait); + goto restart; + } + retval = 0; + goto done; + } + + clear_bit (0, &page->bitmap [0]); + offset = 0; +ready: + retval = offset + page->vaddr; + *handle = offset + page->dma; +done: + spin_unlock_irqrestore (&pool->lock, flags); + return retval; +} + + +static struct pci_page * +pool_find_page (struct pci_pool *pool, dma_addr_t dma) +{ + unsigned long flags; + struct list_head *entry; + struct pci_page *page; + + spin_lock_irqsave (&pool->lock, flags); + list_for_each (entry, &pool->page_list) { + page = list_entry (entry, struct pci_page, page_list); + if (dma < page->dma) + continue; + if (dma < (page->dma + pool->allocation)) + goto done; + } + page = 0; +done: + spin_unlock_irqrestore (&pool->lock, flags); + return page; +} + + +/** + * pci_pool_free - put block back into pci pool + * @pool: the pci pool holding the block + * @vaddr: virtual address of block + * @dma: dma address of block + * + * Caller promises neither device nor driver will again touch this block + * unless it is first re-allocated. + */ +void +pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma) +{ + struct pci_page *page; + unsigned long flags; + int map, block; + + if ((page = pool_find_page (pool, dma)) == 0) { + printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n", + pool->dev ? pool->dev->slot_name : NULL, + pool->name, vaddr, (unsigned long) dma); + return; + } + + block = dma - page->dma; + block /= pool->size; + map = block / BITS_PER_LONG; + block %= BITS_PER_LONG; + +#ifdef CONFIG_DEBUG_SLAB + if (((dma - page->dma) + (void *)page->vaddr) != vaddr) { + printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%lx\n", + pool->dev ? pool->dev->slot_name : NULL, + pool->name, vaddr, (unsigned long) dma); + return; + } + if (page->bitmap [map] & (1UL << block)) { + printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n", + pool->dev ? pool->dev->slot_name : NULL, + pool->name, dma); + return; + } + memset (vaddr, POOL_POISON_BYTE, pool->size); +#endif + + spin_lock_irqsave (&pool->lock, flags); + set_bit (block, &page->bitmap [map]); + if (waitqueue_active (&pool->waitq)) + wake_up (&pool->waitq); + /* + * Resist a temptation to do + * if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page); + * it is not interrupt safe. Better have empty pages hang around. + */ + spin_unlock_irqrestore (&pool->lock, flags); +} + +EXPORT_SYMBOL (pci_pool_create); +EXPORT_SYMBOL (pci_pool_destroy); +EXPORT_SYMBOL (pci_pool_alloc); +EXPORT_SYMBOL (pci_pool_free); + +/* **************************************** */ + +static int __init pcipool_init(void) +{ + MOD_INC_USE_COUNT; /* never unload */ + + return 0; +} +module_init(pcipool_init); + +MODULE_LICENSE("GPL"); diff -Nru a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/common/sa1111.c Sun Feb 9 21:13:36 2003 @@ -0,0 +1,1107 @@ +/* + * linux/arch/arm/mach-sa1100/sa1111.c + * + * SA1111 support + * + * Original code by John Dorsey + * + * 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. + * + * This file contains all generic SA1111 support. + * + * All initialization functions provided here are intended to be called + * from machine specific code with proper arguments when required. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/* + * We keep the following data for the overall SA1111. Note that the + * struct device and struct resource are "fake"; they should be supplied + * by the bus above us. However, in the interests of getting all SA1111 + * drivers converted over to the device model, we provide this as an + * anchor point for all the other drivers. + */ +struct sa1111 { + struct device *dev; + struct resource res; + int irq; + spinlock_t lock; + void *base; +}; + +/* + * We _really_ need to eliminate this. Its only users + * are the PWM and DMA checking code. + */ +static struct sa1111 *g_sa1111; + +static struct sa1111_dev usb_dev = { + .dev = { + .name = "Intel Corporation SA1111 [USB Controller]", + }, + .skpcr_mask = SKPCR_UCLKEN, + .devid = SA1111_DEVID_USB, + .irq = { + IRQ_USBPWR, + IRQ_HCIM, + IRQ_HCIBUFFACC, + IRQ_HCIRMTWKP, + IRQ_NHCIMFCIR, + IRQ_USB_PORT_RESUME + }, +}; + +static struct sa1111_dev sac_dev = { + .dev = { + .name = "Intel Corporation SA1111 [Audio Controller]", + }, + .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN, + .devid = SA1111_DEVID_SAC, + .irq = { + AUDXMTDMADONEA, + AUDXMTDMADONEB, + AUDRCVDMADONEA, + AUDRCVDMADONEB + }, +}; + +static struct sa1111_dev ssp_dev = { + .dev = { + .name = "Intel Corporation SA1111 [SSP Controller]", + }, + .skpcr_mask = SKPCR_SCLKEN, + .devid = SA1111_DEVID_SSP, +}; + +static struct sa1111_dev kbd_dev = { + .dev = { + .name = "Intel Corporation SA1111 [PS2]", + }, + .skpcr_mask = SKPCR_PTCLKEN, + .devid = SA1111_DEVID_PS2, + .irq = { + IRQ_TPRXINT, + IRQ_TPTXINT + }, +}; + +static struct sa1111_dev mse_dev = { + .dev = { + .name = "Intel Corporation SA1111 [PS2]", + }, + .skpcr_mask = SKPCR_PMCLKEN, + .devid = SA1111_DEVID_PS2, + .irq = { + IRQ_MSRXINT, + IRQ_MSTXINT + }, +}; + +static struct sa1111_dev int_dev = { + .dev = { + .name = "Intel Corporation SA1111 [Interrupt Controller]", + }, + .skpcr_mask = 0, + .devid = SA1111_DEVID_INT, +}; + +static struct sa1111_dev pcmcia_dev = { + .dev = { + .name = "Intel Corporation SA1111 [PCMCIA Controller]", + }, + .skpcr_mask = 0, + .devid = SA1111_DEVID_PCMCIA, + .irq = { + IRQ_S0_READY_NINT, + IRQ_S0_CD_VALID, + IRQ_S0_BVD1_STSCHG, + IRQ_S1_READY_NINT, + IRQ_S1_CD_VALID, + IRQ_S1_BVD1_STSCHG, + }, +}; + +static struct sa1111_dev *devs[] = { + &usb_dev, + &sac_dev, + &ssp_dev, + &kbd_dev, + &mse_dev, + &pcmcia_dev, +}; + +static unsigned int dev_offset[] = { + SA1111_USB, + 0x0600, + 0x0800, + SA1111_KBD, + SA1111_MSE, + 0x1800, +}; + +/* + * SA1111 interrupt support. Since clearing an IRQ while there are + * active IRQs causes the interrupt output to pulse, the upper levels + * will call us again if there are more interrupts to process. + */ +static void +sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + unsigned int stat0, stat1, i; + + stat0 = INTSTATCLR0; + stat1 = INTSTATCLR1; + + INTSTATCLR0 = stat0; + + desc->chip->ack(irq); + + INTSTATCLR1 = stat1; + + if (stat0 == 0 && stat1 == 0) { + do_bad_IRQ(irq, desc, regs); + return; + } + + for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1) + if (stat0 & 1) + do_edge_IRQ(i, irq_desc + i, regs); + + for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1) + if (stat1 & 1) + do_edge_IRQ(i, irq_desc + i, regs); + + /* For level-based interrupts */ + desc->chip->unmask(irq); +} + +#define SA1111_IRQMASK_LO(x) (1 << (x - IRQ_SA1111_START)) +#define SA1111_IRQMASK_HI(x) (1 << (x - IRQ_SA1111_START - 32)) + +static void sa1111_ack_irq(unsigned int irq) +{ +} + +static void sa1111_mask_lowirq(unsigned int irq) +{ + INTEN0 &= ~SA1111_IRQMASK_LO(irq); +} + +static void sa1111_unmask_lowirq(unsigned int irq) +{ + INTEN0 |= SA1111_IRQMASK_LO(irq); +} + +/* + * Attempt to re-trigger the interrupt. The SA1111 contains a register + * (INTSET) which claims to do this. However, in practice no amount of + * manipulation of INTEN and INTSET guarantees that the interrupt will + * be triggered. In fact, its very difficult, if not impossible to get + * INTSET to re-trigger the interrupt. + */ +static void sa1111_rerun_lowirq(unsigned int irq) +{ + unsigned int mask = SA1111_IRQMASK_LO(irq); + int i; + + for (i = 0; i < 8; i++) { + INTPOL0 ^= mask; + INTPOL0 ^= mask; + if (INTSTATCLR1 & mask) + break; + } + + if (i == 8) + printk(KERN_ERR "Danger Will Robinson: failed to " + "re-trigger IRQ%d\n", irq); +} + +static int sa1111_type_lowirq(unsigned int irq, unsigned int flags) +{ + unsigned int mask = SA1111_IRQMASK_LO(irq); + + if (flags == IRQT_PROBE) + return 0; + + if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0) + return -EINVAL; + + if (flags & __IRQT_RISEDGE) + INTPOL0 &= ~mask; + else + INTPOL0 |= mask; + WAKE_POL0 = INTPOL0; + + return 0; +} + +static int sa1111_wake_lowirq(unsigned int irq, unsigned int on) +{ + unsigned int mask = SA1111_IRQMASK_LO(irq); + + if (on) + WAKE_EN0 |= mask; + else + WAKE_EN0 &= ~mask; + + return 0; +} + +static struct irqchip sa1111_low_chip = { + .ack = sa1111_ack_irq, + .mask = sa1111_mask_lowirq, + .unmask = sa1111_unmask_lowirq, + .rerun = sa1111_rerun_lowirq, + .type = sa1111_type_lowirq, + .wake = sa1111_wake_lowirq, +}; + +static void sa1111_mask_highirq(unsigned int irq) +{ + INTEN1 &= ~SA1111_IRQMASK_HI(irq); +} + +static void sa1111_unmask_highirq(unsigned int irq) +{ + INTEN1 |= SA1111_IRQMASK_HI(irq); +} + +/* + * Attempt to re-trigger the interrupt. The SA1111 contains a register + * (INTSET) which claims to do this. However, in practice no amount of + * manipulation of INTEN and INTSET guarantees that the interrupt will + * be triggered. In fact, its very difficult, if not impossible to get + * INTSET to re-trigger the interrupt. + */ +static void sa1111_rerun_highirq(unsigned int irq) +{ + unsigned int mask = SA1111_IRQMASK_HI(irq); + int i; + + for (i = 0; i < 8; i++) { + INTPOL1 ^= mask; + INTPOL1 ^= mask; + if (INTSTATCLR1 & mask) + break; + } + + if (i == 8) + printk(KERN_ERR "Danger Will Robinson: failed to " + "re-trigger IRQ%d\n", irq); +} + +static int sa1111_type_highirq(unsigned int irq, unsigned int flags) +{ + unsigned int mask = SA1111_IRQMASK_HI(irq); + + if (flags == IRQT_PROBE) + return 0; + + if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0) + return -EINVAL; + + if (flags & __IRQT_RISEDGE) + INTPOL1 &= ~mask; + else + INTPOL1 |= mask; + WAKE_POL1 = INTPOL1; + + return 0; +} + +static int sa1111_wake_highirq(unsigned int irq, unsigned int on) +{ + unsigned int mask = SA1111_IRQMASK_HI(irq); + + if (on) + WAKE_EN1 |= mask; + else + WAKE_EN1 &= ~mask; + + return 0; +} + +static struct irqchip sa1111_high_chip = { + .ack = sa1111_ack_irq, + .mask = sa1111_mask_highirq, + .unmask = sa1111_unmask_highirq, + .rerun = sa1111_rerun_highirq, + .type = sa1111_type_highirq, + .wake = sa1111_wake_highirq, +}; + +static void __init sa1111_init_irq(struct sa1111_dev *sadev) +{ + unsigned int irq; + + /* + * We're guaranteed that this region hasn't been taken. + */ + request_mem_region(sadev->res.start, 512, "irqs"); + + /* disable all IRQs */ + sa1111_writel(0, sadev->mapbase + SA1111_INTEN0); + sa1111_writel(0, sadev->mapbase + SA1111_INTEN1); + sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN0); + sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN1); + + /* + * detect on rising edge. Note: Feb 2001 Errata for SA1111 + * specifies that S0ReadyInt and S1ReadyInt should be '1'. + */ + sa1111_writel(0, sadev->mapbase + SA1111_INTPOL0); + sa1111_writel(SA1111_IRQMASK_HI(IRQ_S0_READY_NINT) | + SA1111_IRQMASK_HI(IRQ_S1_READY_NINT), + sadev->mapbase + SA1111_INTPOL1); + + /* clear all IRQs */ + sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR0); + sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR1); + + for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { + set_irq_chip(irq, &sa1111_low_chip); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { + set_irq_chip(irq, &sa1111_high_chip); + set_irq_handler(irq, do_edge_IRQ); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + + /* + * Register SA1111 interrupt + */ + set_irq_type(sadev->irq[0], IRQT_RISING); + set_irq_chained_handler(sadev->irq[0], sa1111_irq_handler); +} + +/* + * Bring the SA1111 out of reset. This requires a set procedure: + * 1. nRESET asserted (by hardware) + * 2. CLK turned on from SA1110 + * 3. nRESET deasserted + * 4. VCO turned on, PLL_BYPASS turned off + * 5. Wait lock time, then assert RCLKEn + * 7. PCR set to allow clocking of individual functions + * + * Until we've done this, the only registers we can access are: + * SBI_SKCR + * SBI_SMCR + * SBI_SKID + */ +static void sa1111_wake(struct sa1111 *sachip) +{ + unsigned long flags, r; + + spin_lock_irqsave(&sachip->lock, flags); + + /* + * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: + * (SA-1110 Developer's Manual, section 9.1.2.1) + */ + GAFR |= GPIO_32_768kHz; + GPDR |= GPIO_32_768kHz; + TUCR = TUCR_3_6864MHz; + + /* + * Turn VCO on, and disable PLL Bypass. + */ + r = sa1111_readl(sachip->base + SA1111_SKCR); + r &= ~SKCR_VCO_OFF; + sa1111_writel(r, sachip->base + SA1111_SKCR); + r |= SKCR_PLL_BYPASS | SKCR_OE_EN; + sa1111_writel(r, sachip->base + SA1111_SKCR); + + /* + * Wait lock time. SA1111 manual _doesn't_ + * specify a figure for this! We choose 100us. + */ + udelay(100); + + /* + * Enable RCLK. We also ensure that RDYEN is set. + */ + r |= SKCR_RCLKEN | SKCR_RDYEN; + sa1111_writel(r, sachip->base + SA1111_SKCR); + + /* + * Wait 14 RCLK cycles for the chip to finish coming out + * of reset. (RCLK=24MHz). This is 590ns. + */ + udelay(1); + + /* + * Ensure all clocks are initially off. + */ + sa1111_writel(0, sachip->base + SA1111_SKPCR); + + spin_unlock_irqrestore(&sachip->lock, flags); +} + +/* + * Configure the SA1111 shared memory controller. + */ +void +sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac, + unsigned int cas_latency) +{ + unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC); + + if (cas_latency == 3) + smcr |= SMCR_CLAT; + + sa1111_writel(smcr, sachip->base + SA1111_SMCR); +} + +static void +sa1111_init_one_child(struct sa1111 *sachip, struct sa1111_dev *sadev, unsigned int offset) +{ + snprintf(sadev->dev.bus_id, sizeof(sadev->dev.bus_id), + "%4.4x", offset); + + sadev->dev.parent = sachip->dev; + sadev->dev.bus = &sa1111_bus_type; + sadev->res.start = sachip->res.start + offset; + sadev->res.end = sadev->res.start + 511; + sadev->res.name = sadev->dev.name; + sadev->res.flags = IORESOURCE_MEM; + sadev->mapbase = sachip->base + offset; + + if (request_resource(&sachip->res, &sadev->res)) { + printk("SA1111: failed to allocate resource for %s\n", + sadev->res.name); + return; + } + + device_register(&sadev->dev); +} + +/** + * sa1111_probe - probe for a single SA1111 chip. + * @phys_addr: physical address of device. + * + * Probe for a SA1111 chip. This must be called + * before any other SA1111-specific code. + * + * Returns: + * %-ENODEV device not found. + * %-EBUSY physical address already marked in-use. + * %0 successful. + */ +static int __init +__sa1111_probe(struct device *me, unsigned long phys_addr, int irq) +{ + struct sa1111 *sachip; + unsigned long id; + unsigned int has_devs, val; + int i, ret = -ENODEV; + + sachip = kmalloc(sizeof(struct sa1111), GFP_KERNEL); + if (!sachip) + return -ENOMEM; + + memset(sachip, 0, sizeof(struct sa1111)); + + spin_lock_init(&sachip->lock); + + sachip->dev = me; + dev_set_drvdata(sachip->dev, sachip); + + sachip->res.name = me->name; + sachip->res.start = phys_addr; + sachip->res.end = phys_addr + 0x2000; + sachip->irq = irq; + + if (request_resource(&iomem_resource, &sachip->res)) { + ret = -EBUSY; + goto out; + } + + /* + * Map the whole region. This also maps the + * registers for our children. + */ + sachip->base = ioremap(phys_addr, PAGE_SIZE * 2); + if (!sachip->base) { + ret = -ENOMEM; + goto release; + } + + /* + * Probe for the chip. Only touch the SBI registers. + */ + id = sa1111_readl(sachip->base + SA1111_SKID); + if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { + printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id); + ret = -ENODEV; + goto unmap; + } + + printk(KERN_INFO "SA1111 Microprocessor Companion Chip: " + "silicon revision %lx, metal revision %lx\n", + (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK)); + + /* + * We found it. Wake the chip up, and initialise. + */ + sa1111_wake(sachip); + + /* + * The SDRAM configuration of the SA1110 and the SA1111 must + * match. This is very important to ensure that SA1111 accesses + * don't corrupt the SDRAM. Note that this ungates the SA1111's + * MBGNT signal, so we must have called sa1110_mb_disable() + * beforehand. + */ + sa1111_configure_smc(sachip, 1, + FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), + FExtr(MDCNFG, MDCNFG_SA1110_TDL0)); + + /* + * We only need to turn on DCLK whenever we want to use the + * DMA. It can otherwise be held firmly in the off position. + * (currently, we always enable it.) + */ + val = sa1111_readl(sachip->base + SA1111_SKPCR); + sa1111_writel(val | SKPCR_DCLKEN, sachip->base + SA1111_SKPCR); + + /* + * Enable the SA1110 memory bus request and grant signals. + */ + sa1110_mb_enable(); + + /* + * The interrupt controller must be initialised before any + * other device to ensure that the interrupts are available. + */ + int_dev.irq[0] = irq; + sa1111_init_one_child(sachip, &int_dev, SA1111_INTC); + sa1111_init_irq(&int_dev); + + g_sa1111 = sachip; + + has_devs = ~0; + if (machine_is_assabet() || machine_is_jornada720() || + machine_is_badge4()) + has_devs &= ~(1 << 4); + else + has_devs &= ~(1 << 1); + + for (i = 0; i < ARRAY_SIZE(devs); i++) + if (has_devs & (1 << i)) + sa1111_init_one_child(sachip, devs[i], dev_offset[i]); + + return 0; + + unmap: + iounmap(sachip->base); + release: + release_resource(&sachip->res); + out: + kfree(sachip); + return ret; +} + +static void __sa1111_remove(struct sa1111 *sachip) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(devs); i++) { + put_device(&devs[i]->dev); + release_resource(&devs[i]->res); + } + + iounmap(sachip->base); + release_resource(&sachip->res); + kfree(sachip); +} + +/* + * According to the "Intel StrongARM SA-1111 Microprocessor Companion + * Chip Specification Update" (June 2000), erratum #7, there is a + * significant bug in the SA1111 SDRAM shared memory controller. If + * an access to a region of memory above 1MB relative to the bank base, + * it is important that address bit 10 _NOT_ be asserted. Depending + * on the configuration of the RAM, bit 10 may correspond to one + * of several different (processor-relative) address bits. + * + * This routine only identifies whether or not a given DMA address + * is susceptible to the bug. + */ +int sa1111_check_dma_bug(dma_addr_t addr) +{ + struct sa1111 *sachip = g_sa1111; + unsigned int physaddr = SA1111_DMA_ADDR((unsigned int)addr); + unsigned int smcr; + + /* Section 4.6 of the "Intel StrongARM SA-1111 Development Module + * User's Guide" mentions that jumpers R51 and R52 control the + * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or + * SDRAM bank 1 on Neponset). The default configuration selects + * Assabet, so any address in bank 1 is necessarily invalid. + */ + if ((machine_is_assabet() || machine_is_pfs168()) && addr >= 0xc8000000) + return -1; + + /* The bug only applies to buffers located more than one megabyte + * above the start of the target bank: + */ + if (physaddr<(1<<20)) + return 0; + + smcr = sa1111_readl(sachip->base + SA1111_SMCR); + switch (FExtr(smcr, SMCR_DRAC)) { + case 01: /* 10 row + bank address bits, A<20> must not be set */ + if (physaddr & (1<<20)) + return -1; + break; + case 02: /* 11 row + bank address bits, A<23> must not be set */ + if (physaddr & (1<<23)) + return -1; + break; + case 03: /* 12 row + bank address bits, A<24> must not be set */ + if (physaddr & (1<<24)) + return -1; + break; + case 04: /* 13 row + bank address bits, A<25> must not be set */ + if (physaddr & (1<<25)) + return -1; + break; + case 05: /* 14 row + bank address bits, A<20> must not be set */ + if (physaddr & (1<<20)) + return -1; + break; + case 06: /* 15 row + bank address bits, A<20> must not be set */ + if (physaddr & (1<<20)) + return -1; + break; + default: + printk(KERN_ERR "%s(): invalid SMCR DRAC value 0%lo\n", + __FUNCTION__, FExtr(smcr, SMCR_DRAC)); + return -1; + } + + return 0; +} + +struct sa1111_save_data { + unsigned int skcr; + unsigned int skpcr; + unsigned int skcdr; + unsigned char skaud; + unsigned char skpwm0; + unsigned char skpwm1; + + /* + * Interrupt controller + */ + unsigned int intpol0; + unsigned int intpol1; + unsigned int inten0; + unsigned int inten1; + unsigned int wakepol0; + unsigned int wakepol1; + unsigned int wakeen0; + unsigned int wakeen1; +}; + +static int sa1111_suspend(struct device *dev, u32 state, u32 level) +{ + struct sa1111 *sachip = dev_get_drvdata(dev); + unsigned long flags; + char *base; + + /* + * Save state. + */ + if (level == SUSPEND_SAVE_STATE || + level == SUSPEND_DISABLE || + level == SUSPEND_POWER_DOWN) { + struct sa1111_save_data *save; + + if (!dev->saved_state) + dev->saved_state = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL); + if (!dev->saved_state) + return -ENOMEM; + + save = (struct sa1111_save_data *)dev->saved_state; + + spin_lock_irqsave(&sachip->lock, flags); + base = sachip->base; + save->skcr = sa1111_readl(base + SA1111_SKCR); + save->skpcr = sa1111_readl(base + SA1111_SKPCR); + save->skcdr = sa1111_readl(base + SA1111_SKCDR); + save->skaud = sa1111_readl(base + SA1111_SKAUD); + save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0); + save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1); + + base = sachip->base + SA1111_INTC; + save->intpol0 = sa1111_readl(base + SA1111_INTPOL0); + save->intpol1 = sa1111_readl(base + SA1111_INTPOL1); + save->inten0 = sa1111_readl(base + SA1111_INTEN0); + save->inten1 = sa1111_readl(base + SA1111_INTEN1); + save->wakepol0 = sa1111_readl(base + SA1111_WAKEPOL0); + save->wakepol1 = sa1111_readl(base + SA1111_WAKEPOL1); + save->wakeen0 = sa1111_readl(base + SA1111_WAKEEN0); + save->wakeen1 = sa1111_readl(base + SA1111_WAKEEN1); + spin_unlock_irqrestore(&sachip->lock, flags); + } + + /* + * Disable. + */ + if (level == SUSPEND_DISABLE && state == 4) { + unsigned int val; + + spin_lock_irqsave(&sachip->lock, flags); + base = sachip->base; + + sa1111_writel(0, base + SA1111_SKPWM0); + sa1111_writel(0, base + SA1111_SKPWM1); + val = sa1111_readl(base + SA1111_SKCR); + sa1111_writel(val | SKCR_SLEEP, base + SA1111_SKCR); + + spin_unlock_irqrestore(&sachip->lock, flags); + } + + return 0; +} + +/* + * sa1111_resume - Restore the SA1111 device state. + * @dev: device to restore + * @level: resume level + * + * Restore the general state of the SA1111; clock control and + * interrupt controller. Other parts of the SA1111 must be + * restored by their respective drivers, and must be called + * via LDM after this function. + */ +static int sa1111_resume(struct device *dev, u32 level) +{ + struct sa1111 *sachip = dev_get_drvdata(dev); + struct sa1111_save_data *save; + unsigned long flags, id; + char *base; + + if (level != RESUME_RESTORE_STATE && level != RESUME_ENABLE) + return 0; + + save = (struct sa1111_save_data *)dev->saved_state; + if (!save) + return 0; + + dev->saved_state = NULL; + + /* + * Ensure that the SA1111 is still here. + */ + id = sa1111_readl(sachip->base + SA1111_SKID); + if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { + __sa1111_remove(sachip); + dev_set_drvdata(dev, NULL); + kfree(save); + return 0; + } + + spin_lock_irqsave(&sachip->lock, flags); + sa1111_wake(sachip); + + base = sachip->base; + sa1111_writel(save->skcr, base + SA1111_SKCR); + sa1111_writel(save->skpcr, base + SA1111_SKPCR); + sa1111_writel(save->skcdr, base + SA1111_SKCDR); + sa1111_writel(save->skaud, base + SA1111_SKAUD); + sa1111_writel(save->skpwm0, base + SA1111_SKPWM0); + sa1111_writel(save->skpwm1, base + SA1111_SKPWM1); + + base = sachip->base + SA1111_INTC; + sa1111_writel(save->intpol0, base + SA1111_INTPOL0); + sa1111_writel(save->intpol1, base + SA1111_INTPOL1); + sa1111_writel(save->inten0, base + SA1111_INTEN0); + sa1111_writel(save->inten1, base + SA1111_INTEN1); + sa1111_writel(save->wakepol0, base + SA1111_WAKEPOL0); + sa1111_writel(save->wakepol1, base + SA1111_WAKEPOL1); + sa1111_writel(save->wakeen0, base + SA1111_WAKEEN0); + sa1111_writel(save->wakeen1, base + SA1111_WAKEEN1); + spin_unlock_irqrestore(&sachip->lock, flags); + + kfree(save); + + return 0; +} + +static int sa1111_probe(struct device *dev) +{ + return -ENODEV; +} + +static int sa1111_remove(struct device *dev) +{ + struct sa1111 *sachip = dev_get_drvdata(dev); + + if (sachip) { + __sa1111_remove(sachip); + dev_set_drvdata(dev, NULL); + + kfree(dev->saved_state); + dev->saved_state = NULL; + } + + return 0; +} + +/* + * Not sure if this should be on the system bus or not yet. + * We really want some way to register a system device at + * the per-machine level, and then have this driver pick + * up the registered devices. + * + * We also need to handle the SDRAM configuration for + * PXA250/SA1110 machine classes. + */ +static struct device_driver sa1111_device_driver = { + .name = "sa1111", + .bus = &system_bus_type, + .probe = sa1111_probe, + .remove = sa1111_remove, + .suspend = sa1111_suspend, + .resume = sa1111_resume, +}; + +/* + * Register the SA1111 driver with LDM. + */ +static int sa1111_driver_init(void) +{ + driver_register(&sa1111_device_driver); + return 0; +} + +arch_initcall(sa1111_driver_init); + +static struct sys_device sa1111_device = { + .name = "SA1111", + .id = 0, + .root = NULL, + .dev = { + .name = "Intel Corporation SA1111", + .driver = &sa1111_device_driver, + }, +}; + +int sa1111_init(unsigned long phys, unsigned int irq) +{ + int ret; + + snprintf(sa1111_device.dev.bus_id, sizeof(sa1111_device.dev.bus_id), "%8.8lx", phys); + + ret = sys_device_register(&sa1111_device); + if (ret) + printk("sa1111 device_register failed: %d\n", ret); + + return __sa1111_probe(&sa1111_device.dev, phys, irq); +} + +/* + * Get the parent device driver (us) structure + * from a child function device + */ +static inline struct sa1111 *sa1111_chip_driver(struct sa1111_dev *sadev) +{ + return (struct sa1111 *)dev_get_drvdata(sadev->dev.parent); +} + +/* + * The bits in the opdiv field are non-linear. + */ +static unsigned char opdiv_table[] = { 1, 4, 2, 8 }; + +static unsigned int __sa1111_pll_clock(struct sa1111 *sachip) +{ + unsigned int skcdr, fbdiv, ipdiv, opdiv; + + skcdr = sa1111_readl(sachip->base + SA1111_SKCDR); + + fbdiv = (skcdr & 0x007f) + 2; + ipdiv = ((skcdr & 0x0f80) >> 7) + 2; + opdiv = opdiv_table[(skcdr & 0x3000) >> 12]; + + return 3686400 * fbdiv / (ipdiv * opdiv); +} + +/** + * sa1111_pll_clock - return the current PLL clock frequency. + * @sadev: SA1111 function block + * + * BUG: we should look at SKCR. We also blindly believe that + * the chip is being fed with the 3.6864MHz clock. + * + * Returns the PLL clock in Hz. + */ +unsigned int sa1111_pll_clock(struct sa1111_dev *sadev) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + + return __sa1111_pll_clock(sachip); +} + +/** + * sa1111_select_audio_mode - select I2S or AC link mode + * @sadev: SA1111 function block + * @mode: One of %SA1111_AUDIO_ACLINK or %SA1111_AUDIO_I2S + * + * Frob the SKCR to select AC Link mode or I2S mode for + * the audio block. + */ +void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned long flags; + unsigned int val; + + spin_lock_irqsave(&sachip->lock, flags); + + val = sa1111_readl(sachip->base + SA1111_SKCR); + if (mode == SA1111_AUDIO_I2S) { + val &= ~SKCR_SELAC; + } else { + val |= SKCR_SELAC; + } + sa1111_writel(val, sachip->base + SA1111_SKCR); + + spin_unlock_irqrestore(&sachip->lock, flags); +} + +/** + * sa1111_set_audio_rate - set the audio sample rate + * @sadev: SA1111 SAC function block + * @rate: sample rate to select + */ +int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned int div; + + if (sadev->devid != SA1111_DEVID_SAC) + return -EINVAL; + + div = (__sa1111_pll_clock(sachip) / 256 + rate / 2) / rate; + if (div == 0) + div = 1; + if (div > 128) + div = 128; + + sa1111_writel(div - 1, sachip->base + SA1111_SKAUD); + + return 0; +} + +/** + * sa1111_get_audio_rate - get the audio sample rate + * @sadev: SA1111 SAC function block device + */ +int sa1111_get_audio_rate(struct sa1111_dev *sadev) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned long div; + + if (sadev->devid != SA1111_DEVID_SAC) + return -EINVAL; + + div = sa1111_readl(sachip->base + SA1111_SKAUD) + 1; + + return __sa1111_pll_clock(sachip) / (256 * div); +} + +/* + * Individual device operations. + */ + +/** + * sa1111_enable_device - enable an on-chip SA1111 function block + * @sadev: SA1111 function block device to enable + */ +void sa1111_enable_device(struct sa1111_dev *sadev) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned long flags; + unsigned int val; + + spin_lock_irqsave(&sachip->lock, flags); + val = sa1111_readl(sachip->base + SA1111_SKPCR); + sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR); + spin_unlock_irqrestore(&sachip->lock, flags); +} + +/** + * sa1111_disable_device - disable an on-chip SA1111 function block + * @sadev: SA1111 function block device to disable + */ +void sa1111_disable_device(struct sa1111_dev *sadev) +{ + struct sa1111 *sachip = sa1111_chip_driver(sadev); + unsigned long flags; + unsigned int val; + + spin_lock_irqsave(&sachip->lock, flags); + val = sa1111_readl(sachip->base + SA1111_SKPCR); + sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR); + spin_unlock_irqrestore(&sachip->lock, flags); +} + +/* + * SA1111 "Register Access Bus." + * + * We model this as a regular bus type, and hang devices directly + * off this. + */ +static int sa1111_match(struct device *_dev, struct device_driver *_drv) +{ + struct sa1111_dev *dev = SA1111_DEV(_dev); + struct sa1111_driver *drv = SA1111_DRV(_drv); + + return dev->devid == drv->devid; +} + +struct bus_type sa1111_bus_type = { + .name = "RAB", + .match = sa1111_match, +}; + +static int sa1111_rab_bus_init(void) +{ + return bus_register(&sa1111_bus_type); +} + +postcore_initcall(sa1111_rab_bus_init); + +EXPORT_SYMBOL(sa1111_check_dma_bug); +EXPORT_SYMBOL(sa1111_select_audio_mode); +EXPORT_SYMBOL(sa1111_set_audio_rate); +EXPORT_SYMBOL(sa1111_get_audio_rate); +EXPORT_SYMBOL(sa1111_enable_device); +EXPORT_SYMBOL(sa1111_disable_device); +EXPORT_SYMBOL(sa1111_pll_clock); +EXPORT_SYMBOL(sa1111_bus_type); diff -Nru a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/common/via82c505.c Sun Feb 9 21:13:28 2003 @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define MAX_SLOTS 7 + +#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) + +static int +via82c505_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + outl(CONFIG_CMD(bus,devfn,where),0xCF8); + switch (size) { + case 1: + *value=inb(0xCFC + (where&3)); + break; + case 2: + *value=inw(0xCFC + (where&2)); + break; + case 4: + *value=inl(0xCFC); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static int +via82c505_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + outl(CONFIG_CMD(bus,devfn,where),0xCF8); + switch (size) { + case 1: + outb(value, 0xCFC + (where&3)); + break; + case 2: + outw(value, 0xCFC + (where&2)); + break; + case 4: + outl(value, 0xCFC); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops via82c505_ops = { + .read = via82c505_read_config, + .write = via82c505_write_config, +}; + +void __init via82c505_preinit(void *sysdata) +{ + printk(KERN_DEBUG "PCI: VIA 82c505\n"); + if (!request_region(0xA8,2,"via config")) { + printk(KERN_WARNING"VIA 82c505: Unable to request region 0xA8\n"); + return; + } + if (!request_region(0xCF8,8,"pci config")) { + printk(KERN_WARNING"VIA 82c505: Unable to request region 0xCF8\n"); + release_region(0xA8, 2); + return; + } + + /* Enable compatible Mode */ + outb(0x96,0xA8); + outb(0x18,0xA9); + outb(0x93,0xA8); + outb(0xd0,0xA9); + +} + +int __init via82c505_setup(int nr, struct pci_sys_data *sys) +{ + return (nr == 0); +} + +struct pci_bus * __init via82c505_scan_bus(int nr, struct pci_sys_data *sysdata) +{ + if (nr == 0) + return pci_scan_bus(0, &via82c505_ops, sysdata); + + return NULL; +} diff -Nru a/arch/arm/def-configs/hackkit b/arch/arm/def-configs/hackkit --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/def-configs/hackkit Sun Feb 9 21:13:38 2003 @@ -0,0 +1,654 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_SWAP=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_ADIFCC is not set +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP310 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_SHARK is not set + +# +# Archimedes/A5000 Implementations +# + +# +# Archimedes/A5000 Implementations (select only ONE) +# + +# +# CLPS711X/EP721X Implementations +# + +# +# Epxa10db +# + +# +# Footbridge Implementations +# + +# +# IOP310 Implementation Options +# + +# +# IOP310 Chipset Features +# + +# +# Intel PXA250/210 Implementations +# + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +CONFIG_SA1100_HACKKIT=y +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_STORK is not set +# CONFIG_SA1100_USB is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y + +# +# Processor Features +# + +# +# General setup +# +CONFIG_DISCONTIGMEM=y +CONFIG_ISA=y +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_24_API=y +CONFIG_CPU_FREQ_26_API=y +# CONFIG_HOTPLUG is not set + +# +# At least one math emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +CONFIG_BINFMT_AOUT=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set +# CONFIG_PREEMPT is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="console=ttySA0,115200 root=/dev/ram0 initrd=0xc0400000,8M init=/rootshell" +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=3 +# CONFIG_MTD_PARTITIONS is not set +# CONFIG_MTD_CONCAT is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_NORA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +CONFIG_INET_ECN=y +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_XFRM_USER is not set +# CONFIG_IPV6 is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set + +# +# Wireless ISA/PCI cards support +# +# CONFIG_WAVELAN is not set +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_TSLIBDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# L3 serial bus support +# +# CONFIG_L3 is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +CONFIG_SA1100_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UFS_FS is not set +# CONFIG_XFS_FS is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_EXPORTFS is not set +# CONFIG_CIFS is not set +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set + +# +# Console Switches +# +# CONFIG_SWITCHES is not set + +# +# USB support +# + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_SLAB=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_WAITQ=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_ERRORS=y +CONFIG_KALLSYMS=y +CONFIG_DEBUG_LL=y + +# +# Security options +# +CONFIG_SECURITY_CAPABILITIES=y + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y diff -Nru a/arch/arm/def-configs/trizeps b/arch/arm/def-configs/trizeps --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/def-configs/trizeps Sun Feb 9 21:13:37 2003 @@ -0,0 +1,852 @@ +# +# Automatically generated by make menuconfig: don't edit +# +CONFIG_ARM=y +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +# CONFIG_GENERIC_BUST_SPINLOCK is not set +# CONFIG_GENERIC_ISA_DMA is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_NET=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_ADIFCC is not set +# CONFIG_ARCH_ANAKIN is not set +# CONFIG_ARCH_ARCA5K is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP310 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_RPC is not set +CONFIG_ARCH_SA1100=y +# CONFIG_ARCH_SHARK is not set + +# +# Archimedes/A5000 Implementations +# +# CONFIG_ARCH_ARC is not set +# CONFIG_ARCH_A5K is not set + +# +# CLPS711X/EP721X Implementations +# +# CONFIG_ARCH_AUTCPU12 is not set +# CONFIG_ARCH_CDB89712 is not set +# CONFIG_ARCH_CEIVA is not set +# CONFIG_ARCH_CLEP7312 is not set +# CONFIG_ARCH_EDB7211 is not set +# CONFIG_ARCH_P720T is not set +# CONFIG_ARCH_FORTUNET is not set +# CONFIG_ARCH_EP7211 is not set +# CONFIG_ARCH_EP7212 is not set + +# +# Epxa10db +# + +# +# Footbridge Implementations +# +# CONFIG_ARCH_CATS is not set +# CONFIG_ARCH_PERSONAL_SERVER is not set +# CONFIG_ARCH_EBSA285_ADDIN is not set +# CONFIG_ARCH_EBSA285_HOST is not set +# CONFIG_ARCH_NETWINDER is not set + +# +# IOP310 Implementation Options +# +# CONFIG_ARCH_IQ80310 is not set +# CONFIG_IOP310_AAU is not set +# CONFIG_IOP310_DMA is not set +# CONFIG_IOP310_MU is not set +# CONFIG_IOP310_PMON is not set + +# +# Intel PXA250/210 Implementations +# +# CONFIG_ARCH_LUBBOCK is not set +# CONFIG_ARCH_PXA_IDP is not set + +# +# SA11x0 Implementations +# +# CONFIG_SA1100_ASSABET is not set +# CONFIG_ASSABET_NEPONSET is not set +# CONFIG_SA1100_ADSBITSY is not set +# CONFIG_SA1100_BRUTUS is not set +# CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set +# CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set +# CONFIG_SA1100_H3XXX is not set +# CONFIG_SA1100_EXTENEX1 is not set +# CONFIG_SA1100_FLEXANET is not set +# CONFIG_SA1100_FREEBIRD is not set +# CONFIG_SA1100_GRAPHICSCLIENT is not set +# CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_BADGE4 is not set +# CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HUW_WEBPANEL is not set +# CONFIG_SA1100_ITSY is not set +# CONFIG_SA1100_LART is not set +# CONFIG_SA1100_NANOENGINE is not set +# CONFIG_SA1100_OMNIMETER is not set +# CONFIG_SA1100_PANGOLIN is not set +# CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set +# CONFIG_SA1100_SHERMAN is not set +# CONFIG_SA1100_SIMPAD is not set +CONFIG_SA1100_TRIZEPS=y +CONFIG_TRIZEPS_MFTB2=y +# CONFIG_SA1100_PFS168 is not set +# CONFIG_SA1100_VICTOR is not set +# CONFIG_SA1100_XP860 is not set +# CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_STORK is not set +# CONFIG_SA1100_USB is not set +# CONFIG_SA1100_USB_NETLINK is not set +# CONFIG_SA1100_USB_CHAR is not set +# CONFIG_H3600_SLEEVE is not set +# CONFIG_ARCH_ACORN is not set +# CONFIG_FOOTBRIDGE is not set +# CONFIG_FOOTBRIDGE_HOST is not set +# CONFIG_FOOTBRIDGE_ADDIN is not set +# CONFIG_SA1111 is not set +CONFIG_CPU_32=y +# CONFIG_CPU_26 is not set +# CONFIG_CPU_ARM610 is not set +# CONFIG_CPU_ARM710 is not set +# CONFIG_CPU_ARM720T is not set +# CONFIG_CPU_ARM920T is not set +# CONFIG_CPU_ARM922T is not set +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_ARM1020 is not set +# CONFIG_CPU_SA110 is not set +CONFIG_CPU_SA1100=y +# CONFIG_CPU_XSCALE is not set +# CONFIG_CPU_32v3 is not set +CONFIG_CPU_32v4=y +# CONFIG_CPU_32v5 is not set +# CONFIG_ARM_THUMB is not set + +# +# General setup +# +CONFIG_DISCONTIGMEM=y +# CONFIG_PCI is not set +CONFIG_ISA=y +# CONFIG_ISA_DMA is not set +# CONFIG_FIQ is not set +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +# CONFIG_CPU_FREQ is not set +# CONFIG_CPU_FREQ_24_API is not set +# CONFIG_CPU_FREQ_26_API is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_I82092 is not set +# CONFIG_I82365 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_CLPS6700 is not set +CONFIG_PCMCIA_SA1100=m +# CONFIG_PCMCIA_SA1111 is not set +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_FASTFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +CONFIG_BINFMT_AOUT=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set +# CONFIG_PREEMPT is not set +# CONFIG_APM is not set +# CONFIG_ARTHUR is not set +CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/hda2 1" +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=m +CONFIG_MTD_CONCAT=m +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_AFS_PARTS=m +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_NORA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CDB89712 is not set +CONFIG_MTD_SA1100=m +# CONFIG_MTD_2PARTS_IPAQ is not set +# CONFIG_MTD_DC21285 is not set +# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_EPXA10DB is not set +# CONFIG_MTD_FORTUNET is not set +# CONFIG_MTD_AUTCPU12 is not set +# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_CEIVA is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PCMCIA is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_PNP_NAMES is not set +# CONFIG_PNP_DEBUG is not set +# CONFIG_ISAPNP is not set +# CONFIG_PNPBIOS is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_IPV6 is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000_NAPI is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_WAVELAN is not set +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +# CONFIG_PCMCIA_NETWAVE is not set +# CONFIG_PCMCIA_WAVELAN is not set +# CONFIG_PCMCIA_HERMES is not set +CONFIG_AIRO_CS=m +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_PCNET is not set +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set +# CONFIG_ARCNET_COM20020_CS is not set +# CONFIG_PCMCIA_IBMTR is not set +CONFIG_NET_PCMCIA_RADIO=y +# CONFIG_PCMCIA_RAYCS is not set +# CONFIG_AIRONET4500_CS is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +# CONFIG_BLK_DEV_IDE_ICSIDE is not set +# CONFIG_BLK_DEV_IDEDMA_ICS is not set +# CONFIG_IDEDMA_ICS_AUTO is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_BLK_DEV_IDE_RAPIDE is not set +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_TSLIBDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_GAMEPORT_NS558 is not set +# CONFIG_GAMEPORT_L4 is not set +# CONFIG_GAMEPORT_EMU10K1 is not set +# CONFIG_GAMEPORT_VORTEX is not set +# CONFIG_GAMEPORT_FM801 is not set +# CONFIG_GAMEPORT_CS461x is not set +# CONFIG_SERIO is not set +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_RPCKBD is not set +# CONFIG_SERIO_AMBAKMI is not set +# CONFIG_SERIO_SA1111 is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDDLER is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set +# CONFIG_INPUT_JOYDUMP is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_INPUT_MISC is not set +# CONFIG_INPUT_PCSPKR is not set +# CONFIG_INPUT_UINPUT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_CS is not set +# CONFIG_SERIAL_8250_EXTENDED is not set +# CONFIG_SERIAL_8250_MANY_PORTS is not set +# CONFIG_SERIAL_8250_SHARE_IRQ is not set +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set +# CONFIG_SERIAL_ACORN is not set +# CONFIG_SERIAL_ANAKIN is not set +# CONFIG_SERIAL_ANAKIN_CONSOLE is not set +# CONFIG_SERIAL_AMBA is not set +# CONFIG_SERIAL_AMBA_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X is not set +# CONFIG_SERIAL_CLPS711X_CONSOLE is not set +# CONFIG_SERIAL_CLPS711X_OLD_NAME is not set +# CONFIG_SERIAL_21285 is not set +# CONFIG_SERIAL_21285_OLD is not set +# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_UART00 is not set +# CONFIG_SERIAL_UART00_CONSOLE is not set +CONFIG_SERIAL_SA1100=y +CONFIG_SERIAL_SA1100_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +# CONFIG_I2C_PHILIPSPAR is not set +# CONFIG_I2C_ELV is not set +# CONFIG_I2C_VELLEMAN is not set +# CONFIG_SCx200_I2C is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_BIT_SA1100_GPIO is not set +# CONFIG_I2C_ALGOPCF is not set +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_PROC=m + +# +# L3 serial bus support +# +# CONFIG_L3 is not set +# CONFIG_L3_ALGOBIT is not set +# CONFIG_L3_BIT_SA1100_GPIO is not set +# CONFIG_BIT_SA1100_GPIO is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_SA1100_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_RAW_DRIVER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_QFMT_V1 is not set +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_QUOTA is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +# CONFIG_CIFS is not set +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_AFS_FS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# Multimedia Capabilities Port drivers +# +# CONFIG_MCP is not set +# CONFIG_MCP_SA1100 is not set +# CONFIG_MCP_UCB1200 is not set +# CONFIG_MCP_UCB1200_AUDIO is not set +# CONFIG_MCP_UCB1200_TS is not set + +# +# Console Switches +# +# CONFIG_SWITCHES is not set +# CONFIG_SWITCHES_SA1100 is not set +# CONFIG_SWITCHES_UCB1X00 is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +# CONFIG_NO_FRAME_POINTER is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_DC21285_PORT is not set +# CONFIG_DEBUG_CLPS711X_UART2 is not set + +# +# Security options +# +CONFIG_SECURITY_CAPABILITIES=y + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -Nru a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile --- a/arch/arm/kernel/Makefile Sun Feb 9 21:13:36 2003 +++ b/arch/arm/kernel/Makefile Sun Feb 9 21:13:36 2003 @@ -15,8 +15,6 @@ obj-n := obj- := -export-objs := armksyms.o apm.o dma.o ecard.o fiq.o io.o time.o - obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_ARCH_ACORN) += ecard.o time-acorn.o obj-$(CONFIG_ARCH_CLPS7500) += time-acorn.o @@ -26,8 +24,6 @@ obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o obj-$(CONFIG_PCI) += bios32.o -obj-$(CONFIG_PCI_HOST_PLX90X0) += plx90x0.o -obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o ifneq ($(MACHINE),ebsa110) obj-y += io.o diff -Nru a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c --- a/arch/arm/kernel/ecard.c Sun Feb 9 21:13:34 2003 +++ b/arch/arm/kernel/ecard.c Sun Feb 9 21:13:34 2003 @@ -881,6 +881,90 @@ get_ecard_dev_info); } +#define ec_set_resource(ec,nr,st,sz,flg) \ + do { \ + (ec)->resource[nr].name = ec->dev.name; \ + (ec)->resource[nr].start = st; \ + (ec)->resource[nr].end = (st) + (sz) - 1; \ + (ec)->resource[nr].flags = flg; \ + } while (0) + +static void __init ecard_init_resources(struct expansion_card *ec) +{ + unsigned long base = PODSLOT_IOC4_BASE; + unsigned int slot = ec->slot_no; + int i; + + if (slot < 4) { + ec_set_resource(ec, ECARD_RES_MEMC, + PODSLOT_MEMC_BASE + (slot << 14), + PODSLOT_MEMC_SIZE, IORESOURCE_MEM); + base = PODSLOT_IOC0_BASE; + } + +#ifdef CONFIG_ARCH_RPC + if (slot < 8) { + ec_set_resource(ec, ECARD_RES_EASI, + PODSLOT_EASI_BASE + (slot << 24), + PODSLOT_EASI_SIZE, IORESOURCE_MEM); + } + + if (slot == 8) { + ec_set_resource(ec, ECARD_RES_MEMC, NETSLOT_BASE, + NETSLOT_SIZE, IORESOURCE_MEM); + } else +#endif + + for (i = 0; i < ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++) { + ec_set_resource(ec, i + ECARD_RES_IOCSLOW, + base + (slot << 14) + (i << 19), + PODSLOT_IOC_SIZE, IORESOURCE_MEM); + } + + for (i = 0; i < ECARD_NUM_RESOURCES; i++) { + if (ec->resource[i].start && + request_resource(&iomem_resource, &ec->resource[i])) { + printk(KERN_ERR "%s: resource(s) not available\n", + ec->dev.bus_id); + ec->resource[i].end -= ec->resource[i].start; + ec->resource[i].start = 0; + } + } +} + +static ssize_t ecard_show_irq(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + return sprintf(buf, "%u\n", ec->irq); +} + +static DEVICE_ATTR(irq, S_IRUGO, ecard_show_irq, NULL); + +static ssize_t ecard_show_dma(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + return sprintf(buf, "%u\n", ec->dma); +} + +static DEVICE_ATTR(dma, S_IRUGO, ecard_show_dma, NULL); + +static ssize_t ecard_show_resources(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + char *str = buf; + int i; + + for (i = 0; i < ECARD_NUM_RESOURCES; i++) + str += sprintf(str, "%08lx %08lx %08lx\n", + ec->resource[i].start, + ec->resource[i].end, + ec->resource[i].flags); + + return str - buf; +} + +static DEVICE_ATTR(resource, S_IRUGO, ecard_show_resources, NULL); + /* * Probe for an expansion card. * @@ -949,6 +1033,16 @@ break; } + snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot); + snprintf(ec->dev.name, sizeof(ec->dev.name), "ecard %04x:%04x", + ec->cid.manufacturer, ec->cid.product); + ec->dev.parent = NULL; + ec->dev.bus = &ecard_bus_type; + ec->dev.dma_mask = &ec->dma_mask; + ec->dma_mask = (u64)0xffffffff; + + ecard_init_resources(ec); + /* * hook the interrupt handlers */ @@ -974,14 +1068,10 @@ *ecp = ec; slot_to_expcard[slot] = ec; - snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot); - strcpy(ec->dev.name, "fixme!"); - ec->dev.parent = NULL; - ec->dev.bus = &ecard_bus_type; - ec->dev.dma_mask = &ec->dma_mask; - ec->dma_mask = (u64)0xffffffff; - device_register(&ec->dev); + device_create_file(&ec->dev, &dev_attr_dma); + device_create_file(&ec->dev, &dev_attr_irq); + device_create_file(&ec->dev, &dev_attr_resource); return 0; diff -Nru a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c --- a/arch/arm/kernel/irq.c Sun Feb 9 21:13:28 2003 +++ b/arch/arm/kernel/irq.c Sun Feb 9 21:13:28 2003 @@ -78,7 +78,8 @@ * disable_irq - disable an irq and wait for completion * @irq: Interrupt to disable * - * Disable the selected interrupt line. We do this lazily. + * Disable the selected interrupt line. Enables and disables + * are nested. We do this lazily. * * This function may be called from IRQ context. */ @@ -88,8 +89,7 @@ unsigned long flags; spin_lock_irqsave(&irq_controller_lock, flags); - if (!desc->depth++) - desc->enabled = 0; + desc->disable_depth++; spin_unlock_irqrestore(&irq_controller_lock, flags); } @@ -107,24 +107,25 @@ { struct irqdesc *desc = irq_desc + irq; unsigned long flags; - int pending = 0; spin_lock_irqsave(&irq_controller_lock, flags); - if (unlikely(!desc->depth)) { + if (unlikely(!desc->disable_depth)) { printk("enable_irq(%u) unbalanced from %p\n", irq, __builtin_return_address(0)); - } else if (!--desc->depth) { + } else if (!--desc->disable_depth) { desc->probing = 0; - desc->enabled = 1; desc->chip->unmask(irq); - pending = desc->pending; - desc->pending = 0; + /* - * If the interrupt was waiting to be processed, - * retrigger it. + * If the interrupt is waiting to be processed, + * try to re-run it. We can't directly run it + * from here since the caller might be in an + * interrupt-protected region. */ - if (pending) + if (desc->pending) { + desc->pending = 0; desc->chip->rerun(irq); + } } spin_unlock_irqrestore(&irq_controller_lock, flags); } @@ -264,7 +265,7 @@ * we shouldn't process the IRQ. Instead, turn on the * hardware masks. */ - if (unlikely(desc->running || !desc->enabled)) + if (unlikely(desc->running || desc->disable_depth)) goto running; /* @@ -286,13 +287,13 @@ if (!action) break; - if (desc->pending && desc->enabled) { + if (desc->pending && !desc->disable_depth) { desc->pending = 0; desc->chip->unmask(irq); } __do_irq(irq, action, regs); - } while (desc->pending && desc->enabled); + } while (desc->pending && !desc->disable_depth); desc->running = 0; @@ -328,7 +329,7 @@ */ desc->chip->ack(irq); - if (likely(desc->enabled)) { + if (likely(!desc->disable_depth)) { kstat_cpu(cpu).irqs[irq]++; /* @@ -338,7 +339,7 @@ if (action) { __do_irq(irq, desc->action, regs); - if (likely(desc->enabled && + if (likely(!desc->disable_depth && !check_irq_lock(desc, irq, regs))) desc->chip->unmask(irq); } @@ -390,14 +391,13 @@ if (handle == do_bad_IRQ) { desc->chip->mask(irq); desc->chip->ack(irq); - desc->depth = 1; - desc->enabled = 0; + desc->disable_depth = 1; } desc->handle = handle; if (handle != do_bad_IRQ && is_chained) { desc->valid = 0; desc->probe_ok = 0; - desc->depth = 0; + desc->disable_depth = 0; desc->chip->unmask(irq); } spin_unlock_irqrestore(&irq_controller_lock, flags); @@ -512,10 +512,9 @@ desc->probing = 0; desc->running = 0; desc->pending = 0; - desc->depth = 1; + desc->disable_depth = 1; if (!desc->noautoenable) { - desc->depth = 0; - desc->enabled = 1; + desc->disable_depth = 0; desc->chip->unmask(irq); } } diff -Nru a/arch/arm/kernel/plx90x0.c b/arch/arm/kernel/plx90x0.c --- a/arch/arm/kernel/plx90x0.c Sun Feb 9 21:13:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,178 +0,0 @@ -/* - * Driver for PLX Technology PCI9000-series host bridge. - * - * Copyright (C) 1997, 1998, 1999, 2000 FutureTV Labs Ltd - */ - -/* - * 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. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * Since the following functions are all very similar, the common parts - * are pulled out into these macros. - */ - -#define PLX_CLEAR_CONFIG \ - __raw_writel(0, PLX_BASE + 0xac); \ - local_irq_restore(flags); } - -#define PLX_SET_CONFIG \ - { unsigned long flags; \ - local_irq_save(flags); \ - __raw_writel((1<<31 | (bus->number << 16) \ - | (devfn << 8) | (where & ~3) \ - | ((bus->number == 0)?0:1)), PLX_BASE + 0xac); \ - -#define PLX_CONFIG_WRITE(size) \ - PLX_SET_CONFIG \ - __raw_write##size(value, PCIO_BASE + (where & 3)); \ - if (__raw_readw(PLX_BASE + 0x6) & 0x2000) \ - __raw_writew(0x2000, PLX_BASE + 0x6); \ - PLX_CLEAR_CONFIG \ - return PCIBIOS_SUCCESSFUL; - -#define PLX_CONFIG_READ(size) \ - PLX_SET_CONFIG \ - *value = __raw_read##size(PCIO_BASE + (where & 3)); \ - if (__raw_readw(PLX_BASE + 0x6) & 0x2000) { \ - __raw_writew(0x2000, PLX_BASE + 0x6); \ - *value = 0xffffffffUL; \ - } \ - PLX_CLEAR_CONFIG \ - return PCIBIOS_SUCCESSFUL; - -/* Configuration space access routines */ - -static int -plx90x0_read_config (struct pci_bus *bus, unsigned int devfn, int where, - int where, int size, u32 *value) -{ - switch (size) { - case 1: - PLX_CONFIG_READ(b) - break; - case 2: - PLX_CONFIG_READ(w) - break; - case 4: - PLX_CONFIG_READ(l) - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int -plx90x0_write_config (struct pci_bus *bus, unsigned int devfn, int where, - int where, int size, u32 value) -{ - switch (size) { - case 1: - PLX_CONFIG_WRITE(b) - break; - case 2: - PLX_CONFIG_WRITE(w) - break; - case 4: - PLX_CONFIG_WRITE(l) - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops plx90x0_ops = -{ - .read = plx90x0_read_config, - .write = plx90x0_write_config, -}; - -static void -plx_syserr_handler(int irq, void *handle, struct pt_regs *regs) -{ - printk("PLX90x0: machine check %04x (pc=%08lx)\n", - readw(PLX_BASE + 6), regs->ARM_pc); - __raw_writew(0xf000, PLX_BASE + 6); -} - -/* - * Initialise the PCI system. - */ - -void __init -plx90x0_init(struct arm_sysdata *sysdata) -{ - static const unsigned long int base = PLX_BASE; - char *what; - unsigned long bar = (unsigned long)virt_to_bus((void *)PAGE_OFFSET); - - /* Have a sniff around and see which PLX device is present. */ - unsigned long id = __raw_readl(base + 0xf0); - -#if 0 - /* This check was a good idea, but can fail. The PLX9060 puts no - default value in these registers unless NB# is asserted (which it - isn't on these cards). */ - if ((id & 0xffff) != PCI_VENDOR_ID_PLX) - return; /* Nothing found */ -#endif - - /* Found one - now work out what it is. */ - switch (id >> 16) { - case 0: /* PCI_DEVICE_ID_PLX_9060 */ - what = "PCI9060"; - break; - case PCI_DEVICE_ID_PLX_9060ES: - what = "PCI9060ES"; - break; - case PCI_DEVICE_ID_PLX_9060SD: - what = "PCI9060SD"; /* uhuhh.. */ - break; - case PCI_DEVICE_ID_PLX_9080: - what = "PCI9080"; - break; - default: - printk("PCI: Unknown PLX device %04lx found -- ignored.\n", - id >> 16); - return; - } - - printk("PCI: PLX Technology %s host bridge found.\n", what); - - /* Now set it up for both master and slave accesses. */ - __raw_writel(0xffff0147, base + 0x4); - __raw_writeb(32, base + 0xd); - __raw_writel(0x8 | bar, base + 0x18); - __raw_writel(0xf8000008, base + 0x80); - __raw_writel(0x40000001, base + 0x84); - __raw_writel(0, base + 0x88); - __raw_writel(0, base + 0x8c); - __raw_writel(0x11, base + 0x94); - __raw_writel(0xC3 + (4 << 28) - + (8 << 11) + (1 << 10) - + (1 << 24), base + 0x98); - __raw_writel(0xC0000000, base + 0x9c); - __raw_writel(PLX_MEM_START, base + 0xa0); - __raw_writel(PLX_IO_START, base + 0xa4); - __raw_writel(0x3, base + 0xa8); - __raw_writel(0, base + 0xac); - __raw_writel(0x10001, base + 0xe8); - __raw_writel(0x8000767e, base + 0xec); - - request_irq(IRQ_SYSERR, plx_syserr_handler, 0, - "system error", NULL); - - pci_scan_bus(0, &plx90x0_ops, sysdata); -} diff -Nru a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c --- a/arch/arm/kernel/setup.c Sun Feb 9 21:13:32 2003 +++ b/arch/arm/kernel/setup.c Sun Feb 9 21:13:32 2003 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -690,6 +691,15 @@ #endif #endif } + +static struct cpu cpu[1]; + +static int __init topology_init(void) +{ + return register_cpu(cpu, 0, NULL); +} + +subsys_initcall(topology_init); static const char *hwcap_str[] = { "swp", diff -Nru a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c --- a/arch/arm/kernel/signal.c Sun Feb 9 21:13:28 2003 +++ b/arch/arm/kernel/signal.c Sun Feb 9 21:13:28 2003 @@ -59,11 +59,11 @@ sigset_t saveset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->ARM_r0 = -EINTR; while (1) { @@ -87,11 +87,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->ARM_r0 = -EINTR; while (1) { @@ -207,10 +207,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(regs, &frame->sc)) goto badframe; @@ -247,10 +247,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; @@ -477,12 +477,12 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(&tsk->sig->siglock); + spin_lock_irq(&tsk->sighand->siglock); sigorsets(&tsk->blocked, &tsk->blocked, &ka->sa.sa_mask); sigaddset(&tsk->blocked, sig); recalc_sigpending(); - spin_unlock_irq(&tsk->sig->siglock); + spin_unlock_irq(&tsk->sighand->siglock); } return; } @@ -521,9 +521,9 @@ unsigned long signr = 0; struct k_sigaction *ka; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); signr = dequeue_signal(¤t->blocked, &info); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (!signr) break; diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c --- a/arch/arm/kernel/time.c Sun Feb 9 21:13:34 2003 +++ b/arch/arm/kernel/time.c Sun Feb 9 21:13:34 2003 @@ -34,7 +34,6 @@ u64 jiffies_64; -extern rwlock_t xtime_lock; extern unsigned long wall_jiffies; /* this needs a better home */ @@ -148,18 +147,20 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; unsigned long usec, sec, lost; - read_lock_irqsave(&xtime_lock, flags); - usec = gettimeoffset(); - - lost = jiffies - wall_jiffies; - if (lost) - usec += lost * USECS_PER_JIFFY; - - sec = xtime.tv_sec; - usec += xtime.tv_nsec / 1000; - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + usec = gettimeoffset(); + + lost = jiffies - wall_jiffies; + if (lost) + usec += lost * USECS_PER_JIFFY; + + sec = xtime.tv_sec; + usec += xtime.tv_nsec / 1000; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); /* usec may have gone up a lot: be safe */ while (usec >= 1000000) { @@ -173,7 +174,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* * This is revolting. We need to set "xtime" correctly. However, the * value in this location is the value at the most recent update of @@ -194,7 +195,7 @@ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } static struct irqaction timer_irq = { diff -Nru a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c --- a/arch/arm/kernel/traps.c Sun Feb 9 21:13:31 2003 +++ b/arch/arm/kernel/traps.c Sun Feb 9 21:13:31 2003 @@ -53,7 +53,8 @@ void dump_backtrace_entry(unsigned long where, unsigned long from) { printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); - print_symbol(" %s\n", where); + print_symbol(" %s", where); + printk("\n"); } /* diff -Nru a/arch/arm/kernel/via82c505.c b/arch/arm/kernel/via82c505.c --- a/arch/arm/kernel/via82c505.c Sun Feb 9 21:13:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,94 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#define MAX_SLOTS 7 - -#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) - -static int -via82c505_read_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 *value) -{ - outl(CONFIG_CMD(bus,devfn,where),0xCF8); - switch (size) { - case 1: - *value=inb(0xCFC + (where&3)); - break; - case 2: - *value=inw(0xCFC + (where&2)); - break; - case 4: - *value=inl(0xCFC); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int -via82c505_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 value) -{ - outl(CONFIG_CMD(bus,devfn,where),0xCF8); - switch (size) { - case 1: - outb(value, 0xCFC + (where&3)); - break; - case 2: - outw(value, 0xCFC + (where&2)); - break; - case 4: - outl(value, 0xCFC); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops via82c505_ops = { - .read = via82c505_read_config, - .write = via82c505_write_config, -}; - -void __init via82c505_preinit(void *sysdata) -{ - printk(KERN_DEBUG "PCI: VIA 82c505\n"); - if (!request_region(0xA8,2,"via config")) { - printk(KERN_WARNING"VIA 82c505: Unable to request region 0xA8\n"); - return; - } - if (!request_region(0xCF8,8,"pci config")) { - printk(KERN_WARNING"VIA 82c505: Unable to request region 0xCF8\n"); - release_region(0xA8, 2); - return; - } - - /* Enable compatible Mode */ - outb(0x96,0xA8); - outb(0x18,0xA9); - outb(0x93,0xA8); - outb(0xd0,0xA9); - -} - -int __init via82c505_setup(int nr, struct pci_sys_data *sys) -{ - return (nr == 0); -} - -struct pci_bus * __init via82c505_scan_bus(int nr, struct pci_sys_data *sysdata) -{ - if (nr == 0) - return pci_scan_bus(0, &via82c505_ops, sysdata); - - return NULL; -} diff -Nru a/arch/arm/mach-adifcc/Makefile b/arch/arm/mach-adifcc/Makefile --- a/arch/arm/mach-adifcc/Makefile Sun Feb 9 21:13:28 2003 +++ b/arch/arm/mach-adifcc/Makefile Sun Feb 9 21:13:28 2003 @@ -9,4 +9,3 @@ obj-n := obj- := -export-objs := diff -Nru a/arch/arm/mach-anakin/Makefile b/arch/arm/mach-anakin/Makefile --- a/arch/arm/mach-anakin/Makefile Sun Feb 9 21:13:32 2003 +++ b/arch/arm/mach-anakin/Makefile Sun Feb 9 21:13:32 2003 @@ -9,4 +9,3 @@ obj-n := obj- := -export-objs := diff -Nru a/arch/arm/mach-arc/Makefile b/arch/arm/mach-arc/Makefile --- a/arch/arm/mach-arc/Makefile Sun Feb 9 21:13:29 2003 +++ b/arch/arm/mach-arc/Makefile Sun Feb 9 21:13:29 2003 @@ -10,8 +10,6 @@ obj-n := obj- := -export-objs := oldlatches.o - obj-$(CONFIG_DEBUG_LL) += debug.o EXTRA_TARGETS := head.o diff -Nru a/arch/arm/mach-clps7500/Makefile b/arch/arm/mach-clps7500/Makefile --- a/arch/arm/mach-clps7500/Makefile Sun Feb 9 21:13:32 2003 +++ b/arch/arm/mach-clps7500/Makefile Sun Feb 9 21:13:32 2003 @@ -9,4 +9,3 @@ obj-n := obj- := -export-objs := diff -Nru a/arch/arm/mach-ebsa110/Makefile b/arch/arm/mach-ebsa110/Makefile --- a/arch/arm/mach-ebsa110/Makefile Sun Feb 9 21:13:32 2003 +++ b/arch/arm/mach-ebsa110/Makefile Sun Feb 9 21:13:32 2003 @@ -4,11 +4,9 @@ # Object file lists. -obj-y := core.o io.o time.o +obj-y := core.o io.o obj-m := obj-n := obj- := - -export-objs := io.o obj-$(CONFIG_LEDS) += leds.o diff -Nru a/arch/arm/mach-ebsa110/time.c b/arch/arm/mach-ebsa110/time.c --- a/arch/arm/mach-ebsa110/time.c Sun Feb 9 21:13:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,112 +0,0 @@ -/* - * linux/arch/arm/mach-ebsa110/time.c - * - * Copyright (C) 2001 Russell King - * - * 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 - -#define PIT_CTRL (PIT_BASE + 0x0d) -#define PIT_T2 (PIT_BASE + 0x09) -#define PIT_T1 (PIT_BASE + 0x05) -#define PIT_T0 (PIT_BASE + 0x01) - -/* - * This is the rate at which your MCLK signal toggles (in Hz) - * This was measured on a 10 digit frequency counter sampling - * over 1 second. - */ -#define MCLK 47894000 - -/* - * This is the rate at which the PIT timers get clocked - */ -#define CLKBY7 (MCLK / 7) - -/* - * If CLKBY7 is larger than this, then we must do software - * division of the timer interrupt. - */ -#if CLKBY7 > 6553500 -#define DIVISOR 2 -#else -#define DIVISOR 1 -#endif - -/* - * This is the counter value - */ -#define COUNT ((CLKBY7 + (DIVISOR * HZ / 2)) / (DIVISOR * HZ)) - -extern unsigned long (*gettimeoffset)(void); - -static unsigned long divisor; - -/* - * Get the time offset from the system PIT. Note that if we have missed an - * interrupt, then the PIT counter will roll over (ie, be negative). - * This actually works out to be convenient. - */ -static unsigned long ebsa110_gettimeoffset(void) -{ - unsigned long offset, count; - - __raw_writeb(0x40, PIT_CTRL); - count = __raw_readb(PIT_T1); - count |= __raw_readb(PIT_T1) << 8; - - /* - * If count > COUNT, make the number negative. - */ - if (count > COUNT) - count |= 0xffff0000; - - offset = COUNT * (DIVISOR - divisor); - offset -= count; - - /* - * `offset' is in units of timer counts. Convert - * offset to units of microseconds. - */ - offset = offset * (1000000 / HZ) / (COUNT * DIVISOR); - - return offset; -} - -int ebsa110_reset_timer(void) -{ - u32 count; - - /* latch and read timer 1 */ - __raw_writeb(0x40, PIT_CTRL); - count = __raw_readb(PIT_T1); - count |= __raw_readb(PIT_T1) << 8; - - count += COUNT; - - __raw_writeb(count & 0xff, PIT_T1); - __raw_writeb(count >> 8, PIT_T1); - - if (divisor == 0) - divisor = DIVISOR; - divisor -= 1; - return divisor; -} - -void __init ebsa110_setup_timer(void) -{ - /* - * Timer 1, mode 2, LSB/MSB - */ - __raw_writeb(0x70, PIT_CTRL); - __raw_writeb(COUNT & 0xff, PIT_T1); - __raw_writeb(COUNT >> 8, PIT_T1); - divisor = DIVISOR - 1; - - gettimeoffset = ebsa110_gettimeoffset; -} diff -Nru a/arch/arm/mach-epxa10db/Makefile b/arch/arm/mach-epxa10db/Makefile --- a/arch/arm/mach-epxa10db/Makefile Sun Feb 9 21:13:35 2003 +++ b/arch/arm/mach-epxa10db/Makefile Sun Feb 9 21:13:35 2003 @@ -9,4 +9,3 @@ obj-n := obj- := -export-objs := diff -Nru a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile --- a/arch/arm/mach-footbridge/Makefile Sun Feb 9 21:13:32 2003 +++ b/arch/arm/mach-footbridge/Makefile Sun Feb 9 21:13:32 2003 @@ -9,8 +9,6 @@ obj-n := obj- := -export-objs := arch.o netwinder-hw.o - pci-$(CONFIG_ARCH_CATS) += cats-pci.o pci-$(CONFIG_ARCH_EBSA285) += ebsa285-pci.o pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o diff -Nru a/arch/arm/mach-ftvpci/Makefile b/arch/arm/mach-ftvpci/Makefile --- a/arch/arm/mach-ftvpci/Makefile Sun Feb 9 21:13:36 2003 +++ b/arch/arm/mach-ftvpci/Makefile Sun Feb 9 21:13:36 2003 @@ -9,7 +9,5 @@ obj-n := obj- := -export-objs := - obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_LEDS) += leds.o diff -Nru a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c --- a/arch/arm/mach-integrator/pci_v3.c Sun Feb 9 21:13:34 2003 +++ b/arch/arm/mach-integrator/pci_v3.c Sun Feb 9 21:13:34 2003 @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -119,7 +120,7 @@ * function = which function * offset = configuration space register we are interested in * - * description: this routine will generate a platform dependant config + * description: this routine will generate a platform dependent config * address. * * calls: none @@ -295,7 +296,7 @@ v = __raw_readw(addr); break; - case 4: + default: v = __raw_readl(addr); break; } diff -Nru a/arch/arm/mach-iop310/Makefile b/arch/arm/mach-iop310/Makefile --- a/arch/arm/mach-iop310/Makefile Sun Feb 9 21:13:36 2003 +++ b/arch/arm/mach-iop310/Makefile Sun Feb 9 21:13:36 2003 @@ -10,8 +10,6 @@ obj-n := obj- := -export-objs := - obj-$(CONFIG_ARCH_IQ80310) += iq80310-pci.o iq80310-irq.o ifneq ($(CONFIG_XSCALE_PMU_TIMER),y) diff -Nru a/arch/arm/mach-l7200/Makefile b/arch/arm/mach-l7200/Makefile --- a/arch/arm/mach-l7200/Makefile Sun Feb 9 21:13:36 2003 +++ b/arch/arm/mach-l7200/Makefile Sun Feb 9 21:13:36 2003 @@ -9,4 +9,3 @@ obj-n := obj- := -export-objs := diff -Nru a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile --- a/arch/arm/mach-pxa/Makefile Sun Feb 9 21:13:32 2003 +++ b/arch/arm/mach-pxa/Makefile Sun Feb 9 21:13:32 2003 @@ -2,8 +2,6 @@ # Makefile for the linux kernel. # -export-objs := generic.o irq.o dma.o sa1111.o - # Common support (must be linked before board specific support) obj-y += generic.o irq.o dma.o obj-$(CONFIG_SA1111) += sa1111.o diff -Nru a/arch/arm/mach-rpc/Makefile b/arch/arm/mach-rpc/Makefile --- a/arch/arm/mach-rpc/Makefile Sun Feb 9 21:13:32 2003 +++ b/arch/arm/mach-rpc/Makefile Sun Feb 9 21:13:32 2003 @@ -9,4 +9,3 @@ obj-n := obj- := -export-objs := diff -Nru a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig --- a/arch/arm/mach-sa1100/Kconfig Sun Feb 9 21:13:37 2003 +++ b/arch/arm/mach-sa1100/Kconfig Sun Feb 9 21:13:37 2003 @@ -165,6 +165,13 @@ handheld computer. See for details. +config SA1100_HACKKIT + bool "HackKit Core CPU Board" + depends on ARCH_SA1100 + help + Say Y here to support the HackKit Core CPU Board + ; + config SA1100_HUW_WEBPANEL bool "HuW WebPanel" depends on ARCH_SA1100 @@ -306,6 +313,18 @@ help Say Y here if you intend to run this kernel on the Stork handheld computer. + +#config SA1100_TRIZEPS +# bool "Trizeps" +# depends on ARCH_SA1100 +# help +# :: write me :: + +#config TRIZEPS_MFTB2 +# bool "MFTB2" +# depends on SA1100_TRIZEPS +# help +# :: write me :: config SA1100_USB tristate "SA1100 USB function support" diff -Nru a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile --- a/arch/arm/mach-sa1100/Makefile Sun Feb 9 21:13:37 2003 +++ b/arch/arm/mach-sa1100/Makefile Sun Feb 9 21:13:37 2003 @@ -9,31 +9,25 @@ obj- := led-y := leds.o -export-objs := dma.o generic.o pcipool.o pm.o sa1111.o sa1111-pcibuf.o - # This needs to be cleaned up. We probably need to have SA1100 # and SA1110 config symbols. ifeq ($(CONFIG_CPU_FREQ),y) obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o obj-$(CONFIG_SA1100_CERF) += cpu-sa1110.o +obj-$(CONFIG_SA1100_HACKKIT) += cpu-sa1110.o obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o obj-$(CONFIG_SA1100_PT_SYSTEM3) += cpu-sa1110.o endif -# Next, the SA1111 stuff. -obj-$(CONFIG_SA1111) += sa1111.o sa1111-pcibuf.o pcipool.o - # Specific board support obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o led-$(CONFIG_SA1100_ADSBITSY) += leds-adsbitsy.o obj-$(CONFIG_SA1100_ASSABET) += assabet.o -export-objs += assabet.o led-$(CONFIG_SA1100_ASSABET) += leds-assabet.o obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o obj-$(CONFIG_SA1100_BADGE4) += badge4.o -export-objs += badge4.o led-$(CONFIG_SA1100_BADGE4) += leds-badge4.o obj-$(CONFIG_SA1100_BRUTUS) += brutus.o @@ -45,12 +39,9 @@ obj-$(CONFIG_SA1100_EMPEG) += empeg.o obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o -export-objs += flexanet.o led-$(CONFIG_SA1100_FLEXANET) += leds-flexanet.o obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o -export-objs += freebird.o - obj-$(CONFIG_SA1100_GRAPHICSCLIENT) += graphicsclient.o led-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o @@ -58,10 +49,11 @@ led-$(CONFIG_SA1100_GRAPHICSMASTER) += leds-graphicsmaster.o obj-$(CONFIG_SA1100_H3600) += h3600.o -export-objs += h3600.o + +obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o +led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o obj-$(CONFIG_SA1100_HUW_WEBPANEL) += huw_webpanel.o -export-objs += huw_webpanel.o obj-$(CONFIG_SA1100_ITSY) += itsy.o @@ -92,12 +84,12 @@ led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o obj-$(CONFIG_SA1100_STORK) += stork.o -export-objs += stork.o + +obj-$(CONFIG_SA1100_TRIZEPS) += trizeps.o obj-$(CONFIG_SA1100_XP860) += xp860.o obj-$(CONFIG_SA1100_YOPY) += yopy.o -export-objs += yopy.o # LEDs support obj-$(CONFIG_LEDS) += $(led-y) @@ -106,4 +98,4 @@ #obj-$(CONFIG_SA1100_USB) += usb/ # Miscelaneous functions -obj-$(CONFIG_PM) += pm.o sleep.o +obj-$(CONFIG_PM) += pm.o sleep.o diff -Nru a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/mach-sa1100/hackkit.c Sun Feb 9 21:13:38 2003 @@ -0,0 +1,180 @@ +/* + * linux/arch/arm/mach-sa1100/hackkit.c + * + * Copyright (C) 2002 Stefan Eletzhofer + * + * This file contains all HackKit tweaks. Based on original work from + * Nicolas Pitre's assabet fixes + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "generic.h" + +/********************************************************************** + * prototypes + */ + +/* init funcs */ +static void __init get_hackkit_scr(void); +static int __init hackkit_init(void); +static void __init hackkit_init_irq(void); +static void __init hackkit_map_io(void); + +static u_int hackkit_get_mctrl(struct uart_port *port); +static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl); +static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate); + +/********************************************************************** + * global data + */ + +/********************************************************************** + * static data + */ + +static struct map_desc hackkit_io_desc[] __initdata = { + /* virtual physical length type */ + { 0xe8000000, 0x00000000, 0x01000000, MT_DEVICE } /* Flash bank 0 */ +}; + +static struct sa1100_port_fns hackkit_port_fns __initdata = { + .set_mctrl = hackkit_set_mctrl, + .get_mctrl = hackkit_get_mctrl, + .pm = hackkit_uart_pm, +}; + +/********************************************************************** + * Static functions + */ + +static void __init hackkit_map_io(void) +{ + sa1100_map_io(); + iotable_init(hackkit_io_desc, ARRAY_SIZE(hackkit_io_desc)); + + sa1100_register_uart_fns(&hackkit_port_fns); + sa1100_register_uart(0, 1); /* com port */ + sa1100_register_uart(1, 2); + sa1100_register_uart(2, 3); /* radio module */ + + Ser1SDCR0 |= SDCR0_SUS; +} + +static void __init hackkit_init_irq(void) +{ + /* none used yet */ +} + +/** + * hackkit_uart_pm - powermgmt callback function for system 3 UART + * @port: uart port structure + * @state: pm state + * @oldstate: old pm state + * + */ +static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate) +{ + /* TODO: switch on/off uart in powersave mode */ +} + +/* + * Note! this can be called from IRQ context. + * FIXME: No modem ctrl lines yet. + */ +static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl) +{ +#if 0 + if (port->mapbase == _Ser1UTCR0) { + u_int set = 0, clear = 0; + + if (mctrl & TIOCM_RTS) + set |= PT_CTRL2_RS1_RTS; + else + clear |= PT_CTRL2_RS1_RTS; + + if (mctrl & TIOCM_DTR) + set |= PT_CTRL2_RS1_DTR; + else + clear |= PT_CTRL2_RS1_DTR; + + PTCTRL2_clear(clear); + PTCTRL2_set(set); + } +#endif +} + +static u_int hackkit_get_mctrl(struct uart_port *port) +{ + u_int ret = 0; +#if 0 + u_int irqsr = PT_IRQSR; + + /* need 2 reads to read current value */ + irqsr = PT_IRQSR; + + /* TODO: check IRQ source register for modem/com + status lines and set them correctly. */ +#endif + + ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; + + return ret; +} + +static int __init hackkit_init(void) +{ + int ret = 0; + + if ( !machine_is_hackkit() ) { + ret = -EINVAL; + goto DONE; + } + + hackkit_init_irq(); + + ret = 0; +DONE: + return ret; +} + +/********************************************************************** + * Exported Functions + */ + +/********************************************************************** + * kernel magic macros + */ +arch_initcall(hackkit_init); + +MACHINE_START(HACKKIT, "HackKit Cpu Board") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + MAPIO(hackkit_map_io) + INITIRQ(sa1100_init_irq) +MACHINE_END diff -Nru a/arch/arm/mach-sa1100/leds-hackkit.c b/arch/arm/mach-sa1100/leds-hackkit.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/mach-sa1100/leds-hackkit.c Sun Feb 9 21:13:37 2003 @@ -0,0 +1,113 @@ +/* + * linux/arch/arm/mach-sa1100/leds-hackkit.c + * + * based on leds-lart.c + * + * (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000 + * (C) Stefan Eletzhofer , 2002 + * + * The HackKit has two leds (GPIO 22/23). The red led (gpio 22) is used + * as cpu led, the green one is used as timer led. + */ +#include +#include + +#include +#include +#include + +#include "leds.h" + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +#define LED_GREEN GPIO_GPIO23 +#define LED_RED GPIO_GPIO22 +#define LED_MASK (LED_RED | LED_GREEN) + +void hackkit_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch(evt) { + case led_start: + /* pin 22/23 are outputs */ + GPDR |= LED_MASK; + hw_led_state = LED_MASK; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = LED_MASK; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= LED_GREEN; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + /* The LART people like the LED to be off when the + system is idle... */ + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~LED_RED; + break; + + case led_idle_end: + /* ... and on if the system is not idle */ + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= LED_RED; + break; +#endif + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_RED; + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= LED_GREEN; + break; + + default: + break; + } + + /* Now set the GPIO state, or nothing will happen at all */ + if (led_state & LED_STATE_ENABLED) { + GPSR = hw_led_state; + GPCR = hw_led_state ^ LED_MASK; + } + + local_irq_restore(flags); +} diff -Nru a/arch/arm/mach-sa1100/leds.c b/arch/arm/mach-sa1100/leds.c --- a/arch/arm/mach-sa1100/leds.c Sun Feb 9 21:13:29 2003 +++ b/arch/arm/mach-sa1100/leds.c Sun Feb 9 21:13:29 2003 @@ -29,6 +29,8 @@ leds_event = flexanet_leds_event; if (machine_is_graphicsclient()) leds_event = graphicsclient_leds_event; + if (machine_is_hackkit()) + leds_event = hackkit_leds_event; if (machine_is_lart()) leds_event = lart_leds_event; if (machine_is_pfs168()) diff -Nru a/arch/arm/mach-sa1100/leds.h b/arch/arm/mach-sa1100/leds.h --- a/arch/arm/mach-sa1100/leds.h Sun Feb 9 21:13:34 2003 +++ b/arch/arm/mach-sa1100/leds.h Sun Feb 9 21:13:34 2003 @@ -5,6 +5,7 @@ extern void cerf_leds_event(led_event_t evt); extern void flexanet_leds_event(led_event_t evt); extern void graphicsclient_leds_event(led_event_t evt); +extern void hackkit_leds_event(led_event_t evt); extern void lart_leds_event(led_event_t evt); extern void pfs168_leds_event(led_event_t evt); extern void graphicsmaster_leds_event(led_event_t evt); diff -Nru a/arch/arm/mach-sa1100/pcipool.c b/arch/arm/mach-sa1100/pcipool.c --- a/arch/arm/mach-sa1100/pcipool.c Sun Feb 9 21:13:34 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,390 +0,0 @@ -/* - NOTE: - - this code was lifted straight out of drivers/pci/pci.c; - when compiling for the Intel StrongARM SA-1110/SA-1111 the - usb-ohci.c driver needs these routines even when the architecture - has no pci bus... -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* - * Pool allocator ... wraps the pci_alloc_consistent page allocator, so - * small blocks are easily used by drivers for bus mastering controllers. - * This should probably be sharing the guts of the slab allocator. - */ - -struct pci_pool { /* the pool */ - struct list_head page_list; - spinlock_t lock; - size_t blocks_per_page; - size_t size; - struct pci_dev *dev; - size_t allocation; - char name [32]; - wait_queue_head_t waitq; -}; - -struct pci_page { /* cacheable header for 'allocation' bytes */ - struct list_head page_list; - void *vaddr; - dma_addr_t dma; - unsigned long bitmap [0]; -}; - -#define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) -#define POOL_POISON_BYTE 0xa7 - -// #define CONFIG_PCIPOOL_DEBUG - -static inline const char *slot_name(const struct pci_pool *pool) -{ - const struct pci_dev *pdev = pool->dev; - - if (pdev == 0) - return "[0]"; - - else if (pcidev_is_sa1111(pdev)) - return "[SA-1111]"; - else - return pdev->slot_name; -} - - -/** - * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma. - * @name: name of pool, for diagnostics - * @pdev: pci device that will be doing the DMA - * @size: size of the blocks in this pool. - * @align: alignment requirement for blocks; must be a power of two - * @allocation: returned blocks won't cross this boundary (or zero) - * Context: !in_interrupt() - * - * Returns a pci allocation pool with the requested characteristics, or - * null if one can't be created. Given one of these pools, pci_pool_alloc() - * may be used to allocate memory. Such memory will all have "consistent" - * DMA mappings, accessible by the device and its driver without using - * cache flushing primitives. The actual size of blocks allocated may be - * larger than requested because of alignment. - * - * If allocation is nonzero, objects returned from pci_pool_alloc() won't - * cross that size boundary. This is useful for devices which have - * addressing restrictions on individual DMA transfers, such as not crossing - * boundaries of 4KBytes. - */ -struct pci_pool * -pci_pool_create (const char *name, struct pci_dev *pdev, - size_t size, size_t align, size_t allocation) -{ - struct pci_pool *retval; - - if (align == 0) - align = 1; - if (size == 0) - return 0; - else if (size < align) - size = align; - else if ((size % align) != 0) { - size += align + 1; - size &= ~(align - 1); - } - - if (allocation == 0) { - if (PAGE_SIZE < size) - allocation = size; - else - allocation = PAGE_SIZE; - // FIXME: round up for less fragmentation - } else if (allocation < size) - return 0; - - if (!(retval = kmalloc (sizeof *retval, SLAB_KERNEL))) - return retval; - - strncpy (retval->name, name, sizeof retval->name); - retval->name [sizeof retval->name - 1] = 0; - - retval->dev = pdev; - INIT_LIST_HEAD (&retval->page_list); - spin_lock_init (&retval->lock); - retval->size = size; - retval->allocation = allocation; - retval->blocks_per_page = allocation / size; - init_waitqueue_head (&retval->waitq); - -#ifdef CONFIG_PCIPOOL_DEBUG - printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n", - slot_name(retval), retval->name, size, - retval->blocks_per_page, allocation); -#endif - - return retval; -} - - -static struct pci_page * -pool_alloc_page (struct pci_pool *pool, int mem_flags) -{ - struct pci_page *page; - int mapsize; - - mapsize = pool->blocks_per_page; - mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG; - mapsize *= sizeof (long); - - page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags); - if (!page) - return 0; - page->vaddr = pci_alloc_consistent (pool->dev, - pool->allocation, - &page->dma); - if (page->vaddr) { - memset (page->bitmap, 0xff, mapsize); // bit set == free -#ifdef CONFIG_DEBUG_SLAB - memset (page->vaddr, POOL_POISON_BYTE, pool->allocation); -#endif - list_add (&page->page_list, &pool->page_list); - } else { - kfree (page); - page = 0; - } - return page; -} - - -static inline int -is_page_busy (int blocks, unsigned long *bitmap) -{ - while (blocks > 0) { - if (*bitmap++ != ~0UL) - return 1; - blocks -= BITS_PER_LONG; - } - return 0; -} - -static void -pool_free_page (struct pci_pool *pool, struct pci_page *page) -{ - dma_addr_t dma = page->dma; - -#ifdef CONFIG_DEBUG_SLAB - memset (page->vaddr, POOL_POISON_BYTE, pool->allocation); -#endif - pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma); - list_del (&page->page_list); - kfree (page); -} - - -/** - * pci_pool_destroy - destroys a pool of pci memory blocks. - * @pool: pci pool that will be destroyed - * - * Caller guarantees that no more memory from the pool is in use, - * and that nothing will try to use the pool after this call. - */ -void -pci_pool_destroy (struct pci_pool *pool) -{ - unsigned long flags; - -#ifdef CONFIG_PCIPOOL_DEBUG - printk (KERN_DEBUG "pcipool destroy %s/%s\n", - slot_name(pool), pool->name); -#endif - - spin_lock_irqsave (&pool->lock, flags); - while (!list_empty (&pool->page_list)) { - struct pci_page *page; - page = list_entry (pool->page_list.next, - struct pci_page, page_list); - if (is_page_busy (pool->blocks_per_page, page->bitmap)) { - printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n", - slot_name(pool), pool->name, page->vaddr); - /* leak the still-in-use consistent memory */ - list_del (&page->page_list); - kfree (page); - } else - pool_free_page (pool, page); - } - spin_unlock_irqrestore (&pool->lock, flags); - kfree (pool); -} - - -/** - * pci_pool_alloc - get a block of consistent memory - * @pool: pci pool that will produce the block - * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC - * @handle: pointer to dma address of block - * - * This returns the kernel virtual address of a currently unused block, - * and reports its dma address through the handle. - * If such a memory block can't be allocated, null is returned. - */ -void * -pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle) -{ - unsigned long flags; - struct list_head *entry; - struct pci_page *page; - int map, block; - size_t offset; - void *retval; - -restart: - spin_lock_irqsave (&pool->lock, flags); - list_for_each (entry, &pool->page_list) { - int i; - page = list_entry (entry, struct pci_page, page_list); - /* only cachable accesses here ... */ - for (map = 0, i = 0; - i < pool->blocks_per_page; - i += BITS_PER_LONG, map++) { - if (page->bitmap [map] == 0) - continue; - block = ffz (~ page->bitmap [map]); - if ((i + block) < pool->blocks_per_page) { - clear_bit (block, &page->bitmap [map]); - offset = (BITS_PER_LONG * map) + block; - offset *= pool->size; - goto ready; - } - } - } - if (!(page = pool_alloc_page (pool, mem_flags))) { - if (mem_flags == SLAB_KERNEL) { - DECLARE_WAITQUEUE (wait, current); - - current->state = TASK_INTERRUPTIBLE; - add_wait_queue (&pool->waitq, &wait); - spin_unlock_irqrestore (&pool->lock, flags); - - schedule_timeout (POOL_TIMEOUT_JIFFIES); - - current->state = TASK_RUNNING; - remove_wait_queue (&pool->waitq, &wait); - goto restart; - } - retval = 0; - goto done; - } - - clear_bit (0, &page->bitmap [0]); - offset = 0; -ready: - retval = offset + page->vaddr; - *handle = offset + page->dma; -done: - spin_unlock_irqrestore (&pool->lock, flags); - return retval; -} - - -static struct pci_page * -pool_find_page (struct pci_pool *pool, dma_addr_t dma) -{ - unsigned long flags; - struct list_head *entry; - struct pci_page *page; - - spin_lock_irqsave (&pool->lock, flags); - list_for_each (entry, &pool->page_list) { - page = list_entry (entry, struct pci_page, page_list); - if (dma < page->dma) - continue; - if (dma < (page->dma + pool->allocation)) - goto done; - } - page = 0; -done: - spin_unlock_irqrestore (&pool->lock, flags); - return page; -} - - -/** - * pci_pool_free - put block back into pci pool - * @pool: the pci pool holding the block - * @vaddr: virtual address of block - * @dma: dma address of block - * - * Caller promises neither device nor driver will again touch this block - * unless it is first re-allocated. - */ -void -pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma) -{ - struct pci_page *page; - unsigned long flags; - int map, block; - - if ((page = pool_find_page (pool, dma)) == 0) { - printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n", - pool->dev ? pool->dev->slot_name : NULL, - pool->name, vaddr, (unsigned long) dma); - return; - } - - block = dma - page->dma; - block /= pool->size; - map = block / BITS_PER_LONG; - block %= BITS_PER_LONG; - -#ifdef CONFIG_DEBUG_SLAB - if (((dma - page->dma) + (void *)page->vaddr) != vaddr) { - printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%lx\n", - pool->dev ? pool->dev->slot_name : NULL, - pool->name, vaddr, (unsigned long) dma); - return; - } - if (page->bitmap [map] & (1UL << block)) { - printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n", - pool->dev ? pool->dev->slot_name : NULL, - pool->name, dma); - return; - } - memset (vaddr, POOL_POISON_BYTE, pool->size); -#endif - - spin_lock_irqsave (&pool->lock, flags); - set_bit (block, &page->bitmap [map]); - if (waitqueue_active (&pool->waitq)) - wake_up (&pool->waitq); - /* - * Resist a temptation to do - * if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page); - * it is not interrupt safe. Better have empty pages hang around. - */ - spin_unlock_irqrestore (&pool->lock, flags); -} - -EXPORT_SYMBOL (pci_pool_create); -EXPORT_SYMBOL (pci_pool_destroy); -EXPORT_SYMBOL (pci_pool_alloc); -EXPORT_SYMBOL (pci_pool_free); - -/* **************************************** */ - -static int __init pcipool_init(void) -{ - MOD_INC_USE_COUNT; /* never unload */ - - return 0; -} -module_init(pcipool_init); - -MODULE_LICENSE("GPL"); diff -Nru a/arch/arm/mach-sa1100/sa1111-pcibuf.c b/arch/arm/mach-sa1100/sa1111-pcibuf.c --- a/arch/arm/mach-sa1100/sa1111-pcibuf.c Sun Feb 9 21:13:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,551 +0,0 @@ -/* - * linux/arch/arm/mach-sa1100/pci-sa1111.c - * - * Special pci_{map/unmap/dma_sync}_* routines for SA-1111. - * - * These functions utilize bouncer buffers to compensate for a bug in - * the SA-1111 hardware which don't allow DMA to/from addresses - * certain addresses above 1MB. - * - * Re-written by Christopher Hoover - * Original version by Brad Parker (brad@heeltoe.com) - * - * Copyright (C) 2002 Hewlett Packard Company. - * - * 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 -#include - -//#define DEBUG -#ifdef DEBUG -#define DPRINTK(...) do { printk(KERN_DEBUG __VA_ARGS__); } while (0) -#else -#define DPRINTK(...) do { } while (0) -#endif - -//#define STATS -#ifdef STATS -#define DO_STATS(X) do { X ; } while (0) -#else -#define DO_STATS(X) do { } while (0) -#endif - -/* ************************************************** */ - -struct safe_buffer { - struct list_head node; - - /* original request */ - void *ptr; - size_t size; - int direction; - - /* safe buffer info */ - struct pci_pool *pool; - void *safe; - dma_addr_t safe_dma_addr; -}; - -LIST_HEAD(safe_buffers); - - -#define SIZE_SMALL 1024 -#define SIZE_LARGE (4*1024) - -static struct pci_pool *small_buffer_pool, *large_buffer_pool; - -#ifdef STATS -static unsigned long sbp_allocs __initdata = 0; -static unsigned long lbp_allocs __initdata = 0; -static unsigned long total_allocs __initdata= 0; - -static void print_alloc_stats(void) -{ - printk(KERN_INFO - "sa1111_pcibuf: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n", - sbp_allocs, lbp_allocs, - total_allocs - sbp_allocs - lbp_allocs, total_allocs); -} -#endif - -static int __init -create_safe_buffer_pools(void) -{ - small_buffer_pool = pci_pool_create("sa1111_small_dma_buffer", - SA1111_FAKE_PCIDEV, - SIZE_SMALL, - 0 /* byte alignment */, - 0 /* no page-crossing issues */); - if (0 == small_buffer_pool) { - printk(KERN_ERR - "sa1111_pcibuf: could not allocate small pci pool\n"); - return -1; - } - - large_buffer_pool = pci_pool_create("sa1111_large_dma_buffer", - SA1111_FAKE_PCIDEV, - SIZE_LARGE, - 0 /* byte alignment */, - 0 /* no page-crossing issues */); - if (0 == large_buffer_pool) { - printk(KERN_ERR - "sa1111_pcibuf: could not allocate large pci pool\n"); - pci_pool_destroy(small_buffer_pool); - small_buffer_pool = 0; - return -1; - } - - printk(KERN_INFO - "sa1111_pcibuf: buffer sizes: small=%u, large=%u\n", - SIZE_SMALL, SIZE_LARGE); - - return 0; -} - -static void __exit -destroy_safe_buffer_pools(void) -{ - if (small_buffer_pool) - pci_pool_destroy(small_buffer_pool); - if (large_buffer_pool) - pci_pool_destroy(large_buffer_pool); - - small_buffer_pool = large_buffer_pool = 0; -} - - -/* allocate a 'safe' buffer and keep track of it */ -static struct safe_buffer * -alloc_safe_buffer(void *ptr, size_t size, int direction) -{ - struct safe_buffer *buf; - struct pci_pool *pool; - void *safe; - dma_addr_t safe_dma_addr; - - DPRINTK("%s(ptr=%p, size=%d, direction=%d)\n", - __func__, ptr, size, direction); - - DO_STATS ( total_allocs++ ); - - buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC); - if (buf == 0) { - printk(KERN_WARNING "%s: kmalloc failed\n", __func__); - return 0; - } - - if (size <= SIZE_SMALL) { - pool = small_buffer_pool; - safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); - - DO_STATS ( sbp_allocs++ ); - } else if (size <= SIZE_LARGE) { - pool = large_buffer_pool; - safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); - - DO_STATS ( lbp_allocs++ ); - } else { - pool = 0; - safe = pci_alloc_consistent(SA1111_FAKE_PCIDEV, size, - &safe_dma_addr); - } - - if (safe == 0) { - printk(KERN_WARNING - "%s: could not alloc dma memory (size=%d)\n", - __func__, size); - kfree(buf); - return 0; - } - -#ifdef STATS - if (total_allocs % 1000 == 0) - print_alloc_stats(); -#endif - - BUG_ON(sa1111_check_dma_bug(safe_dma_addr)); // paranoia - - buf->ptr = ptr; - buf->size = size; - buf->direction = direction; - buf->pool = pool; - buf->safe = safe; - buf->safe_dma_addr = safe_dma_addr; - - MOD_INC_USE_COUNT; - list_add(&buf->node, &safe_buffers); - - return buf; -} - -/* determine if a buffer is from our "safe" pool */ -static struct safe_buffer * -find_safe_buffer(dma_addr_t safe_dma_addr) -{ - struct list_head *entry; - - list_for_each(entry, &safe_buffers) { - struct safe_buffer *b = - list_entry(entry, struct safe_buffer, node); - - if (b->safe_dma_addr == safe_dma_addr) { - return b; - } - } - - return 0; -} - -static void -free_safe_buffer(struct safe_buffer *buf) -{ - DPRINTK("%s(buf=%p)\n", __func__, buf); - - list_del(&buf->node); - - if (buf->pool) - pci_pool_free(buf->pool, buf->safe, buf->safe_dma_addr); - else - pci_free_consistent(SA1111_FAKE_PCIDEV, buf->size, buf->safe, - buf->safe_dma_addr); - kfree(buf); - - MOD_DEC_USE_COUNT; -} - -static inline int -dma_range_is_safe(dma_addr_t addr, size_t size) -{ - unsigned int physaddr = SA1111_DMA_ADDR((unsigned int) addr); - - /* Any address within one megabyte of the start of the target - * bank will be OK. This is an overly conservative test: - * other addresses can be OK depending on the dram - * configuration. (See sa1111.c:sa1111_check_dma_bug() * for - * details.) - * - * We take care to ensure the entire dma region is within - * the safe range. - */ - - return ((physaddr + size - 1) < (1<<20)); -} - -/* ************************************************** */ - -#ifdef STATS -static unsigned long map_op_count __initdata = 0; -static unsigned long bounce_count __initdata = 0; - -static void print_map_stats(void) -{ - printk(KERN_INFO - "sa1111_pcibuf: map_op_count=%lu, bounce_count=%lu\n", - map_op_count, bounce_count); -} -#endif - -static dma_addr_t -map_single(void *ptr, size_t size, int direction) -{ - dma_addr_t dma_addr; - - DO_STATS ( map_op_count++ ); - - dma_addr = virt_to_bus(ptr); - - if (!dma_range_is_safe(dma_addr, size)) { - struct safe_buffer *buf; - - DO_STATS ( bounce_count++ ) ; - - buf = alloc_safe_buffer(ptr, size, direction); - if (buf == 0) { - printk(KERN_ERR - "%s: unable to map unsafe buffer %p!\n", - __func__, ptr); - return 0; - } - - DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", - __func__, - buf->ptr, (void *) virt_to_bus(buf->ptr), - buf->safe, (void *) buf->safe_dma_addr); - - if ((direction == PCI_DMA_TODEVICE) || - (direction == PCI_DMA_BIDIRECTIONAL)) { - DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n", - __func__, ptr, buf->safe, size); - memcpy(buf->safe, ptr, size); - } - consistent_sync(buf->safe, size, direction); - - dma_addr = buf->safe_dma_addr; - } else { - consistent_sync(ptr, size, direction); - } - -#ifdef STATS - if (map_op_count % 1000 == 0) - print_map_stats(); -#endif - - return dma_addr; -} - -static void -unmap_single(dma_addr_t dma_addr, size_t size, int direction) -{ - struct safe_buffer *buf; - - buf = find_safe_buffer(dma_addr); - - if (buf) { - BUG_ON(buf->size != size); - BUG_ON(buf->direction != direction); - - DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", - __func__, - buf->ptr, (void *) virt_to_bus(buf->ptr), - buf->safe, (void *) buf->safe_dma_addr); - - - DO_STATS ( bounce_count++ ); - - if ((direction == PCI_DMA_FROMDEVICE) || - (direction == PCI_DMA_BIDIRECTIONAL)) { - DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n", - __func__, buf->safe, buf->ptr, size); - memcpy(buf->ptr, buf->safe, size); - } - free_safe_buffer(buf); - } -} - -static void -sync_single(dma_addr_t dma_addr, size_t size, int direction) -{ - struct safe_buffer *buf; - - buf = find_safe_buffer(dma_addr); - - if (buf) { - BUG_ON(buf->size != size); - BUG_ON(buf->direction != direction); - - DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", - __func__, - buf->ptr, (void *) virt_to_bus(buf->ptr), - buf->safe, (void *) buf->safe_dma_addr); - - DO_STATS ( bounce_count++ ); - - switch (direction) { - case PCI_DMA_FROMDEVICE: - DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n", - __func__, buf->safe, buf->ptr, size); - memcpy(buf->ptr, buf->safe, size); - break; - case PCI_DMA_TODEVICE: - DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n", - __func__,buf->ptr, buf->safe, size); - memcpy(buf->safe, buf->ptr, size); - break; - case PCI_DMA_BIDIRECTIONAL: - BUG(); /* is this allowed? what does it mean? */ - default: - BUG(); - } - consistent_sync(buf->safe, size, direction); - } else { - consistent_sync(bus_to_virt(dma_addr), size, direction); - } -} - -/* ************************************************** */ - -/* - * see if a buffer address is in an 'unsafe' range. if it is - * allocate a 'safe' buffer and copy the unsafe buffer into it. - * substitute the safe buffer for the unsafe one. - * (basically move the buffer from an unsafe area to a safe one) - */ -dma_addr_t -sa1111_map_single(void *ptr, size_t size, int direction) -{ - unsigned long flags; - dma_addr_t dma_addr; - - DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n", - __func__, ptr, size, direction); - - BUG_ON(direction == PCI_DMA_NONE); - - local_irq_save(flags); - - dma_addr = map_single(ptr, size, direction); - - local_irq_restore(flags); - - return dma_addr; -} - -/* - * see if a mapped address was really a "safe" buffer and if so, copy - * the data from the safe buffer back to the unsafe buffer and free up - * the safe buffer. (basically return things back to the way they - * should be) - */ - -void -sa1111_unmap_single(dma_addr_t dma_addr, size_t size, int direction) -{ - unsigned long flags; - - DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n", - __func__, (void *) dma_addr, size, direction); - - BUG_ON(direction == PCI_DMA_NONE); - - local_irq_save(flags); - - unmap_single(dma_addr, size, direction); - - local_irq_restore(flags); -} - -int -sa1111_map_sg(struct scatterlist *sg, int nents, int direction) -{ - unsigned long flags; - int i; - - DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n", - __func__, sg, nents, direction); - - BUG_ON(direction == PCI_DMA_NONE); - - local_irq_save(flags); - - for (i = 0; i < nents; i++, sg++) { - struct page *page = sg->page; - unsigned int offset = sg->offset; - unsigned int length = sg->length; - void *ptr = page_address(page) + offset; - - sg->dma_address = - map_single(ptr, length, direction); - } - - local_irq_restore(flags); - - return nents; -} - -void -sa1111_unmap_sg(struct scatterlist *sg, int nents, int direction) -{ - unsigned long flags; - int i; - - DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n", - __func__, sg, nents, direction); - - BUG_ON(direction == PCI_DMA_NONE); - - local_irq_save(flags); - - for (i = 0; i < nents; i++, sg++) { - dma_addr_t dma_addr = sg->dma_address; - unsigned int length = sg->length; - - unmap_single(dma_addr, length, direction); - } - - local_irq_restore(flags); -} - -void -sa1111_dma_sync_single(dma_addr_t dma_addr, size_t size, int direction) -{ - unsigned long flags; - - DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n", - __func__, (void *) dma_addr, size, direction); - - local_irq_save(flags); - - sync_single(dma_addr, size, direction); - - local_irq_restore(flags); -} - -void -sa1111_dma_sync_sg(struct scatterlist *sg, int nents, int direction) -{ - unsigned long flags; - int i; - - DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n", - __func__, sg, nents, direction); - - BUG_ON(direction == PCI_DMA_NONE); - - local_irq_save(flags); - - for (i = 0; i < nents; i++, sg++) { - dma_addr_t dma_addr = sg->dma_address; - unsigned int length = sg->length; - - sync_single(dma_addr, length, direction); - } - - local_irq_restore(flags); -} - -EXPORT_SYMBOL(sa1111_map_single); -EXPORT_SYMBOL(sa1111_unmap_single); -EXPORT_SYMBOL(sa1111_map_sg); -EXPORT_SYMBOL(sa1111_unmap_sg); -EXPORT_SYMBOL(sa1111_dma_sync_single); -EXPORT_SYMBOL(sa1111_dma_sync_sg); - -/* **************************************** */ - -static int __init sa1111_pcibuf_init(void) -{ - int ret; - - printk(KERN_DEBUG - "sa1111_pcibuf: initializing SA-1111 DMA workaround\n"); - - ret = create_safe_buffer_pools(); - - return ret; -} -module_init(sa1111_pcibuf_init); - -static void __exit sa1111_pcibuf_exit(void) -{ - BUG_ON(!list_empty(&safe_buffers)); - -#ifdef STATS - print_alloc_stats(); - print_map_stats(); -#endif - - destroy_safe_buffer_pools(); -} -module_exit(sa1111_pcibuf_exit); - -MODULE_AUTHOR("Christopher Hoover "); -MODULE_DESCRIPTION("Special pci_{map/unmap/dma_sync}_* routines for SA-1111."); -MODULE_LICENSE("GPL"); diff -Nru a/arch/arm/mach-sa1100/sa1111.c b/arch/arm/mach-sa1100/sa1111.c --- a/arch/arm/mach-sa1100/sa1111.c Sun Feb 9 21:13:36 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1107 +0,0 @@ -/* - * linux/arch/arm/mach-sa1100/sa1111.c - * - * SA1111 support - * - * Original code by John Dorsey - * - * 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. - * - * This file contains all generic SA1111 support. - * - * All initialization functions provided here are intended to be called - * from machine specific code with proper arguments when required. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -/* - * We keep the following data for the overall SA1111. Note that the - * struct device and struct resource are "fake"; they should be supplied - * by the bus above us. However, in the interests of getting all SA1111 - * drivers converted over to the device model, we provide this as an - * anchor point for all the other drivers. - */ -struct sa1111 { - struct device *dev; - struct resource res; - int irq; - spinlock_t lock; - void *base; -}; - -/* - * We _really_ need to eliminate this. Its only users - * are the PWM and DMA checking code. - */ -static struct sa1111 *g_sa1111; - -static struct sa1111_dev usb_dev = { - .dev = { - .name = "Intel Corporation SA1111 [USB Controller]", - }, - .skpcr_mask = SKPCR_UCLKEN, - .devid = SA1111_DEVID_USB, - .irq = { - IRQ_USBPWR, - IRQ_HCIM, - IRQ_HCIBUFFACC, - IRQ_HCIRMTWKP, - IRQ_NHCIMFCIR, - IRQ_USB_PORT_RESUME - }, -}; - -static struct sa1111_dev sac_dev = { - .dev = { - .name = "Intel Corporation SA1111 [Audio Controller]", - }, - .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN, - .devid = SA1111_DEVID_SAC, - .irq = { - AUDXMTDMADONEA, - AUDXMTDMADONEB, - AUDRCVDMADONEA, - AUDRCVDMADONEB - }, -}; - -static struct sa1111_dev ssp_dev = { - .dev = { - .name = "Intel Corporation SA1111 [SSP Controller]", - }, - .skpcr_mask = SKPCR_SCLKEN, - .devid = SA1111_DEVID_SSP, -}; - -static struct sa1111_dev kbd_dev = { - .dev = { - .name = "Intel Corporation SA1111 [PS2]", - }, - .skpcr_mask = SKPCR_PTCLKEN, - .devid = SA1111_DEVID_PS2, - .irq = { - IRQ_TPRXINT, - IRQ_TPTXINT - }, -}; - -static struct sa1111_dev mse_dev = { - .dev = { - .name = "Intel Corporation SA1111 [PS2]", - }, - .skpcr_mask = SKPCR_PMCLKEN, - .devid = SA1111_DEVID_PS2, - .irq = { - IRQ_MSRXINT, - IRQ_MSTXINT - }, -}; - -static struct sa1111_dev int_dev = { - .dev = { - .name = "Intel Corporation SA1111 [Interrupt Controller]", - }, - .skpcr_mask = 0, - .devid = SA1111_DEVID_INT, -}; - -static struct sa1111_dev pcmcia_dev = { - .dev = { - .name = "Intel Corporation SA1111 [PCMCIA Controller]", - }, - .skpcr_mask = 0, - .devid = SA1111_DEVID_PCMCIA, - .irq = { - IRQ_S0_READY_NINT, - IRQ_S0_CD_VALID, - IRQ_S0_BVD1_STSCHG, - IRQ_S1_READY_NINT, - IRQ_S1_CD_VALID, - IRQ_S1_BVD1_STSCHG, - }, -}; - -static struct sa1111_dev *devs[] = { - &usb_dev, - &sac_dev, - &ssp_dev, - &kbd_dev, - &mse_dev, - &pcmcia_dev, -}; - -static unsigned int dev_offset[] = { - SA1111_USB, - 0x0600, - 0x0800, - SA1111_KBD, - SA1111_MSE, - 0x1800, -}; - -/* - * SA1111 interrupt support. Since clearing an IRQ while there are - * active IRQs causes the interrupt output to pulse, the upper levels - * will call us again if there are more interrupts to process. - */ -static void -sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) -{ - unsigned int stat0, stat1, i; - - stat0 = INTSTATCLR0; - stat1 = INTSTATCLR1; - - INTSTATCLR0 = stat0; - - desc->chip->ack(irq); - - INTSTATCLR1 = stat1; - - if (stat0 == 0 && stat1 == 0) { - do_bad_IRQ(irq, desc, regs); - return; - } - - for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1) - if (stat0 & 1) - do_edge_IRQ(i, irq_desc + i, regs); - - for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1) - if (stat1 & 1) - do_edge_IRQ(i, irq_desc + i, regs); - - /* For level-based interrupts */ - desc->chip->unmask(irq); -} - -#define SA1111_IRQMASK_LO(x) (1 << (x - IRQ_SA1111_START)) -#define SA1111_IRQMASK_HI(x) (1 << (x - IRQ_SA1111_START - 32)) - -static void sa1111_ack_irq(unsigned int irq) -{ -} - -static void sa1111_mask_lowirq(unsigned int irq) -{ - INTEN0 &= ~SA1111_IRQMASK_LO(irq); -} - -static void sa1111_unmask_lowirq(unsigned int irq) -{ - INTEN0 |= SA1111_IRQMASK_LO(irq); -} - -/* - * Attempt to re-trigger the interrupt. The SA1111 contains a register - * (INTSET) which claims to do this. However, in practice no amount of - * manipulation of INTEN and INTSET guarantees that the interrupt will - * be triggered. In fact, its very difficult, if not impossible to get - * INTSET to re-trigger the interrupt. - */ -static void sa1111_rerun_lowirq(unsigned int irq) -{ - unsigned int mask = SA1111_IRQMASK_LO(irq); - int i; - - for (i = 0; i < 8; i++) { - INTPOL0 ^= mask; - INTPOL0 ^= mask; - if (INTSTATCLR1 & mask) - break; - } - - if (i == 8) - printk(KERN_ERR "Danger Will Robinson: failed to " - "re-trigger IRQ%d\n", irq); -} - -static int sa1111_type_lowirq(unsigned int irq, unsigned int flags) -{ - unsigned int mask = SA1111_IRQMASK_LO(irq); - - if (flags == IRQT_PROBE) - return 0; - - if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0) - return -EINVAL; - - if (flags & __IRQT_RISEDGE) - INTPOL0 &= ~mask; - else - INTPOL0 |= mask; - WAKE_POL0 = INTPOL0; - - return 0; -} - -static int sa1111_wake_lowirq(unsigned int irq, unsigned int on) -{ - unsigned int mask = SA1111_IRQMASK_LO(irq); - - if (on) - WAKE_EN0 |= mask; - else - WAKE_EN0 &= ~mask; - - return 0; -} - -static struct irqchip sa1111_low_chip = { - .ack = sa1111_ack_irq, - .mask = sa1111_mask_lowirq, - .unmask = sa1111_unmask_lowirq, - .rerun = sa1111_rerun_lowirq, - .type = sa1111_type_lowirq, - .wake = sa1111_wake_lowirq, -}; - -static void sa1111_mask_highirq(unsigned int irq) -{ - INTEN1 &= ~SA1111_IRQMASK_HI(irq); -} - -static void sa1111_unmask_highirq(unsigned int irq) -{ - INTEN1 |= SA1111_IRQMASK_HI(irq); -} - -/* - * Attempt to re-trigger the interrupt. The SA1111 contains a register - * (INTSET) which claims to do this. However, in practice no amount of - * manipulation of INTEN and INTSET guarantees that the interrupt will - * be triggered. In fact, its very difficult, if not impossible to get - * INTSET to re-trigger the interrupt. - */ -static void sa1111_rerun_highirq(unsigned int irq) -{ - unsigned int mask = SA1111_IRQMASK_HI(irq); - int i; - - for (i = 0; i < 8; i++) { - INTPOL1 ^= mask; - INTPOL1 ^= mask; - if (INTSTATCLR1 & mask) - break; - } - - if (i == 8) - printk(KERN_ERR "Danger Will Robinson: failed to " - "re-trigger IRQ%d\n", irq); -} - -static int sa1111_type_highirq(unsigned int irq, unsigned int flags) -{ - unsigned int mask = SA1111_IRQMASK_HI(irq); - - if (flags == IRQT_PROBE) - return 0; - - if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0) - return -EINVAL; - - if (flags & __IRQT_RISEDGE) - INTPOL1 &= ~mask; - else - INTPOL1 |= mask; - WAKE_POL1 = INTPOL1; - - return 0; -} - -static int sa1111_wake_highirq(unsigned int irq, unsigned int on) -{ - unsigned int mask = SA1111_IRQMASK_HI(irq); - - if (on) - WAKE_EN1 |= mask; - else - WAKE_EN1 &= ~mask; - - return 0; -} - -static struct irqchip sa1111_high_chip = { - .ack = sa1111_ack_irq, - .mask = sa1111_mask_highirq, - .unmask = sa1111_unmask_highirq, - .rerun = sa1111_rerun_highirq, - .type = sa1111_type_highirq, - .wake = sa1111_wake_highirq, -}; - -static void __init sa1111_init_irq(struct sa1111_dev *sadev) -{ - unsigned int irq; - - /* - * We're guaranteed that this region hasn't been taken. - */ - request_mem_region(sadev->res.start, 512, "irqs"); - - /* disable all IRQs */ - sa1111_writel(0, sadev->mapbase + SA1111_INTEN0); - sa1111_writel(0, sadev->mapbase + SA1111_INTEN1); - sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN0); - sa1111_writel(0, sadev->mapbase + SA1111_WAKEEN1); - - /* - * detect on rising edge. Note: Feb 2001 Errata for SA1111 - * specifies that S0ReadyInt and S1ReadyInt should be '1'. - */ - sa1111_writel(0, sadev->mapbase + SA1111_INTPOL0); - sa1111_writel(SA1111_IRQMASK_HI(IRQ_S0_READY_NINT) | - SA1111_IRQMASK_HI(IRQ_S1_READY_NINT), - sadev->mapbase + SA1111_INTPOL1); - - /* clear all IRQs */ - sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR0); - sa1111_writel(~0, sadev->mapbase + SA1111_INTSTATCLR1); - - for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { - set_irq_chip(irq, &sa1111_low_chip); - set_irq_handler(irq, do_edge_IRQ); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - - for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { - set_irq_chip(irq, &sa1111_high_chip); - set_irq_handler(irq, do_edge_IRQ); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - } - - /* - * Register SA1111 interrupt - */ - set_irq_type(sadev->irq[0], IRQT_RISING); - set_irq_chained_handler(sadev->irq[0], sa1111_irq_handler); -} - -/* - * Bring the SA1111 out of reset. This requires a set procedure: - * 1. nRESET asserted (by hardware) - * 2. CLK turned on from SA1110 - * 3. nRESET deasserted - * 4. VCO turned on, PLL_BYPASS turned off - * 5. Wait lock time, then assert RCLKEn - * 7. PCR set to allow clocking of individual functions - * - * Until we've done this, the only registers we can access are: - * SBI_SKCR - * SBI_SMCR - * SBI_SKID - */ -static void sa1111_wake(struct sa1111 *sachip) -{ - unsigned long flags, r; - - spin_lock_irqsave(&sachip->lock, flags); - - /* - * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: - * (SA-1110 Developer's Manual, section 9.1.2.1) - */ - GAFR |= GPIO_32_768kHz; - GPDR |= GPIO_32_768kHz; - TUCR = TUCR_3_6864MHz; - - /* - * Turn VCO on, and disable PLL Bypass. - */ - r = sa1111_readl(sachip->base + SA1111_SKCR); - r &= ~SKCR_VCO_OFF; - sa1111_writel(r, sachip->base + SA1111_SKCR); - r |= SKCR_PLL_BYPASS | SKCR_OE_EN; - sa1111_writel(r, sachip->base + SA1111_SKCR); - - /* - * Wait lock time. SA1111 manual _doesn't_ - * specify a figure for this! We choose 100us. - */ - udelay(100); - - /* - * Enable RCLK. We also ensure that RDYEN is set. - */ - r |= SKCR_RCLKEN | SKCR_RDYEN; - sa1111_writel(r, sachip->base + SA1111_SKCR); - - /* - * Wait 14 RCLK cycles for the chip to finish coming out - * of reset. (RCLK=24MHz). This is 590ns. - */ - udelay(1); - - /* - * Ensure all clocks are initially off. - */ - sa1111_writel(0, sachip->base + SA1111_SKPCR); - - spin_unlock_irqrestore(&sachip->lock, flags); -} - -/* - * Configure the SA1111 shared memory controller. - */ -void -sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac, - unsigned int cas_latency) -{ - unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC); - - if (cas_latency == 3) - smcr |= SMCR_CLAT; - - sa1111_writel(smcr, sachip->base + SA1111_SMCR); -} - -static void -sa1111_init_one_child(struct sa1111 *sachip, struct sa1111_dev *sadev, unsigned int offset) -{ - snprintf(sadev->dev.bus_id, sizeof(sadev->dev.bus_id), - "%4.4x", offset); - - sadev->dev.parent = sachip->dev; - sadev->dev.bus = &sa1111_bus_type; - sadev->res.start = sachip->res.start + offset; - sadev->res.end = sadev->res.start + 511; - sadev->res.name = sadev->dev.name; - sadev->res.flags = IORESOURCE_MEM; - sadev->mapbase = sachip->base + offset; - - if (request_resource(&sachip->res, &sadev->res)) { - printk("SA1111: failed to allocate resource for %s\n", - sadev->res.name); - return; - } - - device_register(&sadev->dev); -} - -/** - * sa1111_probe - probe for a single SA1111 chip. - * @phys_addr: physical address of device. - * - * Probe for a SA1111 chip. This must be called - * before any other SA1111-specific code. - * - * Returns: - * %-ENODEV device not found. - * %-EBUSY physical address already marked in-use. - * %0 successful. - */ -static int __init -__sa1111_probe(struct device *me, unsigned long phys_addr, int irq) -{ - struct sa1111 *sachip; - unsigned long id; - unsigned int has_devs, val; - int i, ret = -ENODEV; - - sachip = kmalloc(sizeof(struct sa1111), GFP_KERNEL); - if (!sachip) - return -ENOMEM; - - memset(sachip, 0, sizeof(struct sa1111)); - - spin_lock_init(&sachip->lock); - - sachip->dev = me; - dev_set_drvdata(sachip->dev, sachip); - - sachip->res.name = me->name; - sachip->res.start = phys_addr; - sachip->res.end = phys_addr + 0x2000; - sachip->irq = irq; - - if (request_resource(&iomem_resource, &sachip->res)) { - ret = -EBUSY; - goto out; - } - - /* - * Map the whole region. This also maps the - * registers for our children. - */ - sachip->base = ioremap(phys_addr, PAGE_SIZE * 2); - if (!sachip->base) { - ret = -ENOMEM; - goto release; - } - - /* - * Probe for the chip. Only touch the SBI registers. - */ - id = sa1111_readl(sachip->base + SA1111_SKID); - if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { - printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id); - ret = -ENODEV; - goto unmap; - } - - printk(KERN_INFO "SA1111 Microprocessor Companion Chip: " - "silicon revision %lx, metal revision %lx\n", - (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK)); - - /* - * We found it. Wake the chip up, and initialise. - */ - sa1111_wake(sachip); - - /* - * The SDRAM configuration of the SA1110 and the SA1111 must - * match. This is very important to ensure that SA1111 accesses - * don't corrupt the SDRAM. Note that this ungates the SA1111's - * MBGNT signal, so we must have called sa1110_mb_disable() - * beforehand. - */ - sa1111_configure_smc(sachip, 1, - FExtr(MDCNFG, MDCNFG_SA1110_DRAC0), - FExtr(MDCNFG, MDCNFG_SA1110_TDL0)); - - /* - * We only need to turn on DCLK whenever we want to use the - * DMA. It can otherwise be held firmly in the off position. - * (currently, we always enable it.) - */ - val = sa1111_readl(sachip->base + SA1111_SKPCR); - sa1111_writel(val | SKPCR_DCLKEN, sachip->base + SA1111_SKPCR); - - /* - * Enable the SA1110 memory bus request and grant signals. - */ - sa1110_mb_enable(); - - /* - * The interrupt controller must be initialised before any - * other device to ensure that the interrupts are available. - */ - int_dev.irq[0] = irq; - sa1111_init_one_child(sachip, &int_dev, SA1111_INTC); - sa1111_init_irq(&int_dev); - - g_sa1111 = sachip; - - has_devs = ~0; - if (machine_is_assabet() || machine_is_jornada720() || - machine_is_badge4()) - has_devs &= ~(1 << 4); - else - has_devs &= ~(1 << 1); - - for (i = 0; i < ARRAY_SIZE(devs); i++) - if (has_devs & (1 << i)) - sa1111_init_one_child(sachip, devs[i], dev_offset[i]); - - return 0; - - unmap: - iounmap(sachip->base); - release: - release_resource(&sachip->res); - out: - kfree(sachip); - return ret; -} - -static void __sa1111_remove(struct sa1111 *sachip) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devs); i++) { - put_device(&devs[i]->dev); - release_resource(&devs[i]->res); - } - - iounmap(sachip->base); - release_resource(&sachip->res); - kfree(sachip); -} - -/* - * According to the "Intel StrongARM SA-1111 Microprocessor Companion - * Chip Specification Update" (June 2000), erratum #7, there is a - * significant bug in the SA1111 SDRAM shared memory controller. If - * an access to a region of memory above 1MB relative to the bank base, - * it is important that address bit 10 _NOT_ be asserted. Depending - * on the configuration of the RAM, bit 10 may correspond to one - * of several different (processor-relative) address bits. - * - * This routine only identifies whether or not a given DMA address - * is susceptible to the bug. - */ -int sa1111_check_dma_bug(dma_addr_t addr) -{ - struct sa1111 *sachip = g_sa1111; - unsigned int physaddr = SA1111_DMA_ADDR((unsigned int)addr); - unsigned int smcr; - - /* Section 4.6 of the "Intel StrongARM SA-1111 Development Module - * User's Guide" mentions that jumpers R51 and R52 control the - * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or - * SDRAM bank 1 on Neponset). The default configuration selects - * Assabet, so any address in bank 1 is necessarily invalid. - */ - if ((machine_is_assabet() || machine_is_pfs168()) && addr >= 0xc8000000) - return -1; - - /* The bug only applies to buffers located more than one megabyte - * above the start of the target bank: - */ - if (physaddr<(1<<20)) - return 0; - - smcr = sa1111_readl(sachip->base + SA1111_SMCR); - switch (FExtr(smcr, SMCR_DRAC)) { - case 01: /* 10 row + bank address bits, A<20> must not be set */ - if (physaddr & (1<<20)) - return -1; - break; - case 02: /* 11 row + bank address bits, A<23> must not be set */ - if (physaddr & (1<<23)) - return -1; - break; - case 03: /* 12 row + bank address bits, A<24> must not be set */ - if (physaddr & (1<<24)) - return -1; - break; - case 04: /* 13 row + bank address bits, A<25> must not be set */ - if (physaddr & (1<<25)) - return -1; - break; - case 05: /* 14 row + bank address bits, A<20> must not be set */ - if (physaddr & (1<<20)) - return -1; - break; - case 06: /* 15 row + bank address bits, A<20> must not be set */ - if (physaddr & (1<<20)) - return -1; - break; - default: - printk(KERN_ERR "%s(): invalid SMCR DRAC value 0%lo\n", - __FUNCTION__, FExtr(smcr, SMCR_DRAC)); - return -1; - } - - return 0; -} - -struct sa1111_save_data { - unsigned int skcr; - unsigned int skpcr; - unsigned int skcdr; - unsigned char skaud; - unsigned char skpwm0; - unsigned char skpwm1; - - /* - * Interrupt controller - */ - unsigned int intpol0; - unsigned int intpol1; - unsigned int inten0; - unsigned int inten1; - unsigned int wakepol0; - unsigned int wakepol1; - unsigned int wakeen0; - unsigned int wakeen1; -}; - -static int sa1111_suspend(struct device *dev, u32 state, u32 level) -{ - struct sa1111 *sachip = dev_get_drvdata(dev); - unsigned long flags; - char *base; - - /* - * Save state. - */ - if (level == SUSPEND_SAVE_STATE || - level == SUSPEND_DISABLE || - level == SUSPEND_POWER_DOWN) { - struct sa1111_save_data *save; - - if (!dev->saved_state) - dev->saved_state = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL); - if (!dev->saved_state) - return -ENOMEM; - - save = (struct sa1111_save_data *)dev->saved_state; - - spin_lock_irqsave(&sachip->lock, flags); - base = sachip->base; - save->skcr = sa1111_readl(base + SA1111_SKCR); - save->skpcr = sa1111_readl(base + SA1111_SKPCR); - save->skcdr = sa1111_readl(base + SA1111_SKCDR); - save->skaud = sa1111_readl(base + SA1111_SKAUD); - save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0); - save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1); - - base = sachip->base + SA1111_INTC; - save->intpol0 = sa1111_readl(base + SA1111_INTPOL0); - save->intpol1 = sa1111_readl(base + SA1111_INTPOL1); - save->inten0 = sa1111_readl(base + SA1111_INTEN0); - save->inten1 = sa1111_readl(base + SA1111_INTEN1); - save->wakepol0 = sa1111_readl(base + SA1111_WAKEPOL0); - save->wakepol1 = sa1111_readl(base + SA1111_WAKEPOL1); - save->wakeen0 = sa1111_readl(base + SA1111_WAKEEN0); - save->wakeen1 = sa1111_readl(base + SA1111_WAKEEN1); - spin_unlock_irqrestore(&sachip->lock, flags); - } - - /* - * Disable. - */ - if (level == SUSPEND_DISABLE && state == 4) { - unsigned int val; - - spin_lock_irqsave(&sachip->lock, flags); - base = sachip->base; - - sa1111_writel(0, base + SA1111_SKPWM0); - sa1111_writel(0, base + SA1111_SKPWM1); - val = sa1111_readl(base + SA1111_SKCR); - sa1111_writel(val | SKCR_SLEEP, base + SA1111_SKCR); - - spin_unlock_irqrestore(&sachip->lock, flags); - } - - return 0; -} - -/* - * sa1111_resume - Restore the SA1111 device state. - * @dev: device to restore - * @level: resume level - * - * Restore the general state of the SA1111; clock control and - * interrupt controller. Other parts of the SA1111 must be - * restored by their respective drivers, and must be called - * via LDM after this function. - */ -static int sa1111_resume(struct device *dev, u32 level) -{ - struct sa1111 *sachip = dev_get_drvdata(dev); - struct sa1111_save_data *save; - unsigned long flags, id; - char *base; - - if (level != RESUME_RESTORE_STATE && level != RESUME_ENABLE) - return 0; - - save = (struct sa1111_save_data *)dev->saved_state; - if (!save) - return 0; - - dev->saved_state = NULL; - - /* - * Ensure that the SA1111 is still here. - */ - id = sa1111_readl(sachip->base + SA1111_SKID); - if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { - __sa1111_remove(sachip); - dev_set_drvdata(dev, NULL); - kfree(save); - return 0; - } - - spin_lock_irqsave(&sachip->lock, flags); - sa1111_wake(sachip); - - base = sachip->base; - sa1111_writel(save->skcr, base + SA1111_SKCR); - sa1111_writel(save->skpcr, base + SA1111_SKPCR); - sa1111_writel(save->skcdr, base + SA1111_SKCDR); - sa1111_writel(save->skaud, base + SA1111_SKAUD); - sa1111_writel(save->skpwm0, base + SA1111_SKPWM0); - sa1111_writel(save->skpwm1, base + SA1111_SKPWM1); - - base = sachip->base + SA1111_INTC; - sa1111_writel(save->intpol0, base + SA1111_INTPOL0); - sa1111_writel(save->intpol1, base + SA1111_INTPOL1); - sa1111_writel(save->inten0, base + SA1111_INTEN0); - sa1111_writel(save->inten1, base + SA1111_INTEN1); - sa1111_writel(save->wakepol0, base + SA1111_WAKEPOL0); - sa1111_writel(save->wakepol1, base + SA1111_WAKEPOL1); - sa1111_writel(save->wakeen0, base + SA1111_WAKEEN0); - sa1111_writel(save->wakeen1, base + SA1111_WAKEEN1); - spin_unlock_irqrestore(&sachip->lock, flags); - - kfree(save); - - return 0; -} - -static int sa1111_probe(struct device *dev) -{ - return -ENODEV; -} - -static int sa1111_remove(struct device *dev) -{ - struct sa1111 *sachip = dev_get_drvdata(dev); - - if (sachip) { - __sa1111_remove(sachip); - dev_set_drvdata(dev, NULL); - - kfree(dev->saved_state); - dev->saved_state = NULL; - } - - return 0; -} - -/* - * Not sure if this should be on the system bus or not yet. - * We really want some way to register a system device at - * the per-machine level, and then have this driver pick - * up the registered devices. - * - * We also need to handle the SDRAM configuration for - * PXA250/SA1110 machine classes. - */ -static struct device_driver sa1111_device_driver = { - .name = "sa1111", - .bus = &system_bus_type, - .probe = sa1111_probe, - .remove = sa1111_remove, - .suspend = sa1111_suspend, - .resume = sa1111_resume, -}; - -/* - * Register the SA1111 driver with LDM. - */ -static int sa1111_driver_init(void) -{ - driver_register(&sa1111_device_driver); - return 0; -} - -arch_initcall(sa1111_driver_init); - -static struct sys_device sa1111_device = { - .name = "SA1111", - .id = 0, - .root = NULL, - .dev = { - .name = "Intel Corporation SA1111", - .driver = &sa1111_device_driver, - }, -}; - -int sa1111_init(unsigned long phys, unsigned int irq) -{ - int ret; - - snprintf(sa1111_device.dev.bus_id, sizeof(sa1111_device.dev.bus_id), "%8.8lx", phys); - - ret = sys_device_register(&sa1111_device); - if (ret) - printk("sa1111 device_register failed: %d\n", ret); - - return __sa1111_probe(&sa1111_device.dev, phys, irq); -} - -/* - * Get the parent device driver (us) structure - * from a child function device - */ -static inline struct sa1111 *sa1111_chip_driver(struct sa1111_dev *sadev) -{ - return (struct sa1111 *)dev_get_drvdata(sadev->dev.parent); -} - -/* - * The bits in the opdiv field are non-linear. - */ -static unsigned char opdiv_table[] = { 1, 4, 2, 8 }; - -static unsigned int __sa1111_pll_clock(struct sa1111 *sachip) -{ - unsigned int skcdr, fbdiv, ipdiv, opdiv; - - skcdr = sa1111_readl(sachip->base + SA1111_SKCDR); - - fbdiv = (skcdr & 0x007f) + 2; - ipdiv = ((skcdr & 0x0f80) >> 7) + 2; - opdiv = opdiv_table[(skcdr & 0x3000) >> 12]; - - return 3686400 * fbdiv / (ipdiv * opdiv); -} - -/** - * sa1111_pll_clock - return the current PLL clock frequency. - * @sadev: SA1111 function block - * - * BUG: we should look at SKCR. We also blindly believe that - * the chip is being fed with the 3.6864MHz clock. - * - * Returns the PLL clock in Hz. - */ -unsigned int sa1111_pll_clock(struct sa1111_dev *sadev) -{ - struct sa1111 *sachip = sa1111_chip_driver(sadev); - - return __sa1111_pll_clock(sachip); -} - -/** - * sa1111_select_audio_mode - select I2S or AC link mode - * @sadev: SA1111 function block - * @mode: One of %SA1111_AUDIO_ACLINK or %SA1111_AUDIO_I2S - * - * Frob the SKCR to select AC Link mode or I2S mode for - * the audio block. - */ -void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode) -{ - struct sa1111 *sachip = sa1111_chip_driver(sadev); - unsigned long flags; - unsigned int val; - - spin_lock_irqsave(&sachip->lock, flags); - - val = sa1111_readl(sachip->base + SA1111_SKCR); - if (mode == SA1111_AUDIO_I2S) { - val &= ~SKCR_SELAC; - } else { - val |= SKCR_SELAC; - } - sa1111_writel(val, sachip->base + SA1111_SKCR); - - spin_unlock_irqrestore(&sachip->lock, flags); -} - -/** - * sa1111_set_audio_rate - set the audio sample rate - * @sadev: SA1111 SAC function block - * @rate: sample rate to select - */ -int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate) -{ - struct sa1111 *sachip = sa1111_chip_driver(sadev); - unsigned int div; - - if (sadev->devid != SA1111_DEVID_SAC) - return -EINVAL; - - div = (__sa1111_pll_clock(sachip) / 256 + rate / 2) / rate; - if (div == 0) - div = 1; - if (div > 128) - div = 128; - - sa1111_writel(div - 1, sachip->base + SA1111_SKAUD); - - return 0; -} - -/** - * sa1111_get_audio_rate - get the audio sample rate - * @sadev: SA1111 SAC function block device - */ -int sa1111_get_audio_rate(struct sa1111_dev *sadev) -{ - struct sa1111 *sachip = sa1111_chip_driver(sadev); - unsigned long div; - - if (sadev->devid != SA1111_DEVID_SAC) - return -EINVAL; - - div = sa1111_readl(sachip->base + SA1111_SKAUD) + 1; - - return __sa1111_pll_clock(sachip) / (256 * div); -} - -/* - * Individual device operations. - */ - -/** - * sa1111_enable_device - enable an on-chip SA1111 function block - * @sadev: SA1111 function block device to enable - */ -void sa1111_enable_device(struct sa1111_dev *sadev) -{ - struct sa1111 *sachip = sa1111_chip_driver(sadev); - unsigned long flags; - unsigned int val; - - spin_lock_irqsave(&sachip->lock, flags); - val = sa1111_readl(sachip->base + SA1111_SKPCR); - sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR); - spin_unlock_irqrestore(&sachip->lock, flags); -} - -/** - * sa1111_disable_device - disable an on-chip SA1111 function block - * @sadev: SA1111 function block device to disable - */ -void sa1111_disable_device(struct sa1111_dev *sadev) -{ - struct sa1111 *sachip = sa1111_chip_driver(sadev); - unsigned long flags; - unsigned int val; - - spin_lock_irqsave(&sachip->lock, flags); - val = sa1111_readl(sachip->base + SA1111_SKPCR); - sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR); - spin_unlock_irqrestore(&sachip->lock, flags); -} - -/* - * SA1111 "Register Access Bus." - * - * We model this as a regular bus type, and hang devices directly - * off this. - */ -static int sa1111_match(struct device *_dev, struct device_driver *_drv) -{ - struct sa1111_dev *dev = SA1111_DEV(_dev); - struct sa1111_driver *drv = SA1111_DRV(_drv); - - return dev->devid == drv->devid; -} - -struct bus_type sa1111_bus_type = { - .name = "RAB", - .match = sa1111_match, -}; - -static int sa1111_rab_bus_init(void) -{ - return bus_register(&sa1111_bus_type); -} - -postcore_initcall(sa1111_rab_bus_init); - -EXPORT_SYMBOL(sa1111_check_dma_bug); -EXPORT_SYMBOL(sa1111_select_audio_mode); -EXPORT_SYMBOL(sa1111_set_audio_rate); -EXPORT_SYMBOL(sa1111_get_audio_rate); -EXPORT_SYMBOL(sa1111_enable_device); -EXPORT_SYMBOL(sa1111_disable_device); -EXPORT_SYMBOL(sa1111_pll_clock); -EXPORT_SYMBOL(sa1111_bus_type); diff -Nru a/arch/arm/mach-sa1100/stork.c b/arch/arm/mach-sa1100/stork.c --- a/arch/arm/mach-sa1100/stork.c Sun Feb 9 21:13:34 2003 +++ b/arch/arm/mach-sa1100/stork.c Sun Feb 9 21:13:34 2003 @@ -181,7 +181,7 @@ { storkSetLatchB(STORK_TOUCH_SCREEN_DCLK); udelay(10); /* hmm wait 200ns (min) - ok this ought to be udelay(1) but that doesn't get */ - /* consistant values so I'm using 10 (urgh) */ + /* consistent values so I'm using 10 (urgh) */ storkClearLatchB(STORK_TOUCH_SCREEN_DCLK); udelay(10); } diff -Nru a/arch/arm/mach-sa1100/trizeps.c b/arch/arm/mach-sa1100/trizeps.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/arm/mach-sa1100/trizeps.c Sun Feb 9 21:13:38 2003 @@ -0,0 +1,232 @@ +/* + * linux/arch/arm/mach-sa1100/trizeps.c + * + * Authors: + * Andreas Hofer , + * Peter Lueg , + * Guennadi Liakhovetski + * + * This file contains all Trizeps-specific tweaks. + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "generic.h" + +#undef DEBUG_TRIZEPS +#ifdef DEBUG_TRIZEPS +#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) +#else +#define DPRINTK( x... ) +#endif + +static struct tri_uart_cts_data_t tri_uart_cts_data[] = { + { TRIZEPS_GPIO_UART1_CTS, 0, NULL, NULL,"int. UART1 cts" }, + { TRIZEPS_GPIO_UART2_CTS, 0, NULL, NULL,"int. UART2 cts" }, + { TRIZEPS_GPIO_UART3_CTS, 0, NULL, NULL,"int. UART3 cts" } +}; + +static void trizeps_cts_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct tri_uart_cts_data_t * uart_data = (struct tri_uart_cts_data_t *)dev_id; + int cts = (!(GPLR & uart_data->cts_gpio)); + + /* NOTE: I suppose that we will not get any interrupts + if the GPIO is not changed, so maybe + the cts_prev_state can be removed ... */ + if (cts != uart_data->cts_prev_state) { + + uart_data->cts_prev_state = cts; + uart_handle_cts_change(uart_data->port, cts); + DPRINTK("(IRQ %d) changed (cts=%d) stop=%d\n", + irq, cts, uart_data->info->tty->hw_stopped); + } +} + +static int +trizeps_register_cts_intr(int gpio, + int irq, + struct tri_uart_cts_data_t *uart_data) +{ + int ret = 0; + + if(irq != NO_IRQ) + { + set_irq_type(irq, IRQT_BOTHEDGE); + + ret = request_irq(irq, trizeps_cts_intr, + SA_INTERRUPT, uart_data->name, uart_data); + if (ret) + printk(KERN_ERR "uart_open: failed to register CTS irq (%d)\n", ret); + } + return ret; +} + +static void trizeps_set_mctrl(struct uart_port *port, u_int mctrl) +{ + if (port->mapbase == _Ser1UTCR0) + { + /**** ttySA1 ****/ + if (mctrl & TIOCM_RTS) + GPCR |= TRIZEPS_GPIO_UART1_RTS; + else + GPSR |= TRIZEPS_GPIO_UART1_RTS; + + DPRINTK("2 ttySA%d Set RTS %s\n",port->line, + mctrl & TIOCM_RTS ? "low" : "high"); + + } + else if (port->mapbase == _Ser3UTCR0) + { + /**** ttySA0 ****/ + } + else + { + /**** ttySA2 ****/ + } +} + +static u_int trizeps_get_mctrl(struct uart_port *port) +{ + int result = TIOCM_CD | TIOCM_DSR; + + if (port->mapbase == _Ser1UTCR0) + { + if (!(GPLR & TRIZEPS_GPIO_UART1_CTS)) + result |= TIOCM_CTS; + } + else if (port->mapbase == _Ser2UTCR0) + { + result |= TIOCM_CTS; + } + else if (port->mapbase == _Ser3UTCR0) + { + result |= TIOCM_CTS; + } + else + { + result = TIOCM_CTS; + } + + DPRINTK(" ttySA%d %s%s%s\n",port->line, + result & TIOCM_CD ? "CD " : "", + result & TIOCM_CTS ? "CTS " : "", + result & TIOCM_DSR ? "DSR " : ""); + + return result; +} + +static struct sa1100_port_fns trizeps_port_fns __initdata = { + .set_mctrl = trizeps_set_mctrl, + .get_mctrl = trizeps_get_mctrl, +}; + +static void trizeps_power_off(void) +{ + printk("trizeps power off\n"); + mdelay(100); + cli(); + /* disable internal oscillator, float CS lines */ + PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS); + /* enable wake-up on GPIO0 (Assabet...) */ + PWER = GFER = GRER = 1; + /* + * set scratchpad to zero, just in case it is used as a + * restart address by the bootloader. + */ + PSPR = 0; + + /* + * Power off + * -> disconnect AKku + */ + TRIZEPS_BCR_set(TRIZEPS_BCR0, TRIZEPS_MFT_OFF); + + /* + * if power supply no Akku + * -> enter sleep mode + */ + PMCR = PMCR_SF; +} + +static int __init trizeps_init(void) +{ + if (!machine_is_trizeps()) + return -EINVAL; + + DPRINTK(" \n"); + pm_power_off = trizeps_power_off; + + // Init UART2 for IrDA +// PPDR |= PPC_TXD2; // Set TXD2 as output + Ser2UTCR4 = UTCR4_HSE; // enable HSE + Ser2HSCR0 = 0; + Ser2HSSR0 = HSSR0_EIF | HSSR0_TUR | HSSR0_RAB | HSSR0_FRE; + + /* Init MECR */ + MECR = 0x00060006; + + /* Set up external serial IRQs */ + GAFR &= ~(GPIO_GPIO16 | GPIO_GPIO17); // no alternate function + GPDR &= ~(GPIO_GPIO16 | GPIO_GPIO17); // Set to Input + set_irq_type(IRQ_GPIO16, IRQT_RISING); + set_irq_type(IRQ_GPIO17, IRQT_RISING); + + return 0; +} + +__initcall(trizeps_init); + +static struct map_desc trizeps_io_desc[] __initdata = { + /* virtual physical length type */ + { 0xF0000000l, 0x30000000l, 0x00800000l, MT_DEVICE }, + { 0xF2000000l, 0x38000000l, 0x00800000l, MT_DEVICE }, +}; + +static void __init trizeps_map_io(void) +{ + sa1100_map_io(); + iotable_init(trizeps_io_desc, ARRAY_SIZE(trizeps_io_desc)); + + sa1100_register_uart_fns(&trizeps_port_fns); + sa1100_register_uart(0, 3); + sa1100_register_uart(1, 1); + sa1100_register_uart(2, 2); +} + +MACHINE_START(TRIZEPS, "TRIZEPS") + MAINTAINER("DSA") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + MAPIO(trizeps_map_io) + INITIRQ(sa1100_init_irq) +MACHINE_END diff -Nru a/arch/arm/mach-shark/Makefile b/arch/arm/mach-shark/Makefile --- a/arch/arm/mach-shark/Makefile Sun Feb 9 21:13:29 2003 +++ b/arch/arm/mach-shark/Makefile Sun Feb 9 21:13:29 2003 @@ -9,6 +9,4 @@ obj-n := obj- := -export-objs := - obj-$(CONFIG_LEDS) += leds.o diff -Nru a/arch/arm/mach-tbox/Makefile b/arch/arm/mach-tbox/Makefile --- a/arch/arm/mach-tbox/Makefile Sun Feb 9 21:13:30 2003 +++ b/arch/arm/mach-tbox/Makefile Sun Feb 9 21:13:30 2003 @@ -9,4 +9,3 @@ obj-n := obj- := -export-objs := diff -Nru a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile --- a/arch/arm/mm/Makefile Sun Feb 9 21:13:37 2003 +++ b/arch/arm/mm/Makefile Sun Feb 9 21:13:37 2003 @@ -8,8 +8,6 @@ obj-m := obj-n := obj- := -export-objs := proc-syms.o discontig.o - ifeq ($(CONFIG_CPU_32),y) obj-y += consistent.o fault-armv.o ioremap.o mm-armv.o obj-$(CONFIG_MODULES) += proc-syms.o diff -Nru a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S --- a/arch/arm/mm/proc-arm920.S Sun Feb 9 21:13:28 2003 +++ b/arch/arm/mm/proc-arm920.S Sun Feb 9 21:13:28 2003 @@ -297,7 +297,7 @@ * * This is a little misleading, it is not intended to clean out * the i-cache but to make sure that any data written to the - * range is made consistant. This means that when we execute code + * range is made consistent. This means that when we execute code * in that region, everything works as we expect. * * This generally means writing back data in the Dcache and diff -Nru a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S --- a/arch/arm/mm/proc-arm922.S Sun Feb 9 21:13:35 2003 +++ b/arch/arm/mm/proc-arm922.S Sun Feb 9 21:13:35 2003 @@ -298,7 +298,7 @@ * * This is a little misleading, it is not intended to clean out * the i-cache but to make sure that any data written to the - * range is made consistant. This means that when we execute code + * range is made consistent. This means that when we execute code * in that region, everything works as we expect. * * This generally means writing back data in the Dcache and diff -Nru a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S --- a/arch/arm/mm/proc-arm926.S Sun Feb 9 21:13:32 2003 +++ b/arch/arm/mm/proc-arm926.S Sun Feb 9 21:13:32 2003 @@ -147,7 +147,7 @@ * * This is a little misleading, it is not intended to clean out * the i-cache but to make sure that any data written to the - * range is made consistant. This means that when we execute code + * range is made consistent. This means that when we execute code * in that region, everything works as we expect. * * This generally means writing back data in the Dcache and diff -Nru a/arch/cris/Kconfig b/arch/cris/Kconfig --- a/arch/cris/Kconfig Sun Feb 9 21:13:36 2003 +++ b/arch/cris/Kconfig Sun Feb 9 21:13:36 2003 @@ -55,7 +55,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config ETRAX_KGDB @@ -587,7 +587,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -685,7 +685,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/cris/drivers/Kconfig b/arch/cris/drivers/Kconfig --- a/arch/cris/drivers/Kconfig Sun Feb 9 21:13:29 2003 +++ b/arch/cris/drivers/Kconfig Sun Feb 9 21:13:29 2003 @@ -366,7 +366,7 @@ ( = 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 - parport.o. If you have more than one parallel port and want to + parport. If you have more than one parallel port and want to specify which port and IRQ to be used by this driver at module load time, take a look at . @@ -400,7 +400,7 @@ driver as a module however ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read and - . The module will be called lp.o. + . The module will be called lp. If you have several parallel ports, you can specify which ports to use with the "lp" kernel command line option. (Try "man bootparam" @@ -463,7 +463,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -494,7 +494,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read and - . The module will be called ide-mod.o. + . The module will be called ide-mod. Do not compile this driver as a module if your root file system (the one containing the directory /) is located on an IDE device. @@ -516,7 +516,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide-disk.o. Do not compile this driver as a module + will be called ide-disk. Do not compile this driver as a module if your root file system (the one containing the directory /) is located on the IDE disk. If unsure, say Y. @@ -544,7 +544,7 @@ If you want to compile the driver 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 ide-cd.o. + will be called ide-cd. config BLK_DEV_IDEDMA bool @@ -859,7 +859,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usbcore.o. If you want to compile it as a + The module will be called usbcore. If you want to compile it as a module, say M here and read . config ETRAX_USB_HOST_PORT1 diff -Nru a/arch/cris/drivers/serial.c b/arch/cris/drivers/serial.c --- a/arch/cris/drivers/serial.c Sun Feb 9 21:13:34 2003 +++ b/arch/cris/drivers/serial.c Sun Feb 9 21:13:34 2003 @@ -318,7 +318,7 @@ #include -/* non-arch dependant serial structures are in linux/serial.h */ +/* non-arch dependent serial structures are in linux/serial.h */ #include /* while we keep our own stuff (struct e100_serial) in a local .h file */ #include "serial.h" diff -Nru a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile --- a/arch/cris/kernel/Makefile Sun Feb 9 21:13:33 2003 +++ b/arch/cris/kernel/Makefile Sun Feb 9 21:13:33 2003 @@ -5,8 +5,6 @@ EXTRA_TARGETS := head.o -export-objs := ksyms.o - obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o setup.o time.o sys_cris.o shadows.o \ debugport.o semaphore.o diff -Nru a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c --- a/arch/cris/kernel/ptrace.c Sun Feb 9 21:13:30 2003 +++ b/arch/cris/kernel/ptrace.c Sun Feb 9 21:13:30 2003 @@ -18,7 +18,7 @@ * PTRACE_DETACH works more simple in 2.4.10 * * Revision 1.6 2001/07/25 16:08:47 bjornw - * PTRACE_ATTACH bulk moved into arch-independant code in 2.4.7 + * PTRACE_ATTACH bulk moved into arch-independent code in 2.4.7 * * Revision 1.5 2001/03/26 14:24:28 orjanf * * Changed loop condition. diff -Nru a/arch/cris/lib/old_checksum.c b/arch/cris/lib/old_checksum.c --- a/arch/cris/lib/old_checksum.c Sun Feb 9 21:13:35 2003 +++ b/arch/cris/lib/old_checksum.c Sun Feb 9 21:13:35 2003 @@ -75,7 +75,7 @@ sum += *((unsigned short *)buff)++; } if(endMarker - buff > 0) { - sum += *buff; /* add extra byte seperately */ + sum += *buff; /* add extra byte separately */ } BITOFF; return(sum); diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Sun Feb 9 21:13:29 2003 +++ b/arch/i386/Kconfig Sun Feb 9 21:13:29 2003 @@ -573,7 +573,7 @@ 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 will be called microcode.o. If you want to compile it as + The module will be called microcode. If you want to compile it as a module, say M here and read . If you use modprobe or kmod you may also want to add the line 'alias char-major-10-184 microcode' to your /etc/modules.conf file. @@ -859,7 +859,7 @@ To compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module will be called - apm.o. + apm. config APM_IGNORE_USER_SUSPEND bool "Ignore USER SUSPEND" @@ -983,6 +983,17 @@ If in doubt, say N. +config X86_ACPI_CPUFREQ + tristate "ACPI Processor P-States driver" + depends on CPU_FREQ && ACPI_PROCESSOR + help + This driver adds a CPUFreq driver which utilizes the ACPI + Processor Performance States. + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + config X86_POWERNOW_K6 tristate "AMD Mobile K6-2/K6-3 PowerNow!" depends on CPU_FREQ @@ -1151,7 +1162,7 @@ If you don't know what to do here, say N. This support is also available as a module. If compiled as a - module, it will be called scx200.o. + module, it will be called scx200. source "drivers/pci/Kconfig" @@ -1277,7 +1288,7 @@ QMAGIC support" then you'll have to say Y here. You may answer M to compile a.out support as a module and later load the module when you want to use a program or library in a.out format. The module will be - called binfmt_aout.o. Saying M or N here is dangerous though, + called binfmt_aout. Saying M or N here is dangerous though, because some crucial programs on your system might still be in A.OUT format. @@ -1307,7 +1318,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config BINFMT_MISC @@ -1332,7 +1343,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. endmenu @@ -1388,7 +1399,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -1415,7 +1426,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -1519,7 +1530,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile --- a/arch/i386/Makefile Sun Feb 9 21:13:30 2003 +++ b/arch/i386/Makefile Sun Feb 9 21:13:30 2003 @@ -3,8 +3,7 @@ # # This file is included by the global makefile so that you can add your own # architecture-specific flags and dependencies. Remember to do have actions -# for "archclean" and "archdep" for cleaning up and making dependencies for -# this architecture +# for "archclean" cleaning up for this architecture. # # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive @@ -76,7 +75,7 @@ # default subarch .h files mflags-y += -Iinclude/asm-i386/mach-default -HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o +head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o libs-y += arch/i386/lib/ core-y += arch/i386/kernel/ \ @@ -92,8 +91,7 @@ boot := arch/i386/boot -.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \ - clean archclean archmrproper +.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install all: bzImage diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile --- a/arch/i386/kernel/Makefile Sun Feb 9 21:13:29 2003 +++ b/arch/i386/kernel/Makefile Sun Feb 9 21:13:29 2003 @@ -4,8 +4,6 @@ EXTRA_TARGETS := head.o init_task.o -export-objs := mca.o i386_ksyms.o time.o - obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \ pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o @@ -34,5 +32,4 @@ EXTRA_AFLAGS := -traditional -export-objs += scx200.o obj-$(CONFIG_SCx200) += scx200.o diff -Nru a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c --- a/arch/i386/kernel/acpi.c Sun Feb 9 21:13:35 2003 +++ b/arch/i386/kernel/acpi.c Sun Feb 9 21:13:35 2003 @@ -303,8 +303,7 @@ int __init -acpi_boot_init ( - char *cmdline) +acpi_boot_init (void) { int result = 0; @@ -317,7 +316,7 @@ /* * Initialize the ACPI boot-time table parser. */ - result = acpi_table_init(cmdline); + result = acpi_table_init(); if (result) return result; @@ -454,6 +453,7 @@ /* 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)); @@ -520,4 +520,20 @@ 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 Sun Feb 9 21:13:29 2003 +++ b/arch/i386/kernel/acpi_wakeup.S Sun Feb 9 21:13:29 2003 @@ -41,20 +41,19 @@ cmpl $0x12345678, %eax jne bogus_real_magic -#if 1 + testl $1, video_flags - wakeup_code + jz 1f lcall $0xc000,$3 -#endif -#if 0 +1: + + testl $2, video_flags - wakeup_code + jz 1f mov video_mode - wakeup_code, %ax call mode_set -#endif +1: # set up page table -#if 1 movl $swapper_pg_dir-__PAGE_OFFSET, %eax -#else - movl (real_save_cr3 - wakeup_data), %eax -#endif movl %eax, %cr3 # make sure %cr4 is set correctly (features, etc) @@ -86,6 +85,7 @@ 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) @@ -254,6 +254,8 @@ 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 diff -Nru a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c --- a/arch/i386/kernel/apm.c Sun Feb 9 21:13:28 2003 +++ b/arch/i386/kernel/apm.c Sun Feb 9 21:13:28 2003 @@ -215,6 +215,7 @@ #include #include #include +#include #include #include #include @@ -227,7 +228,6 @@ #include -extern rwlock_t xtime_lock; extern spinlock_t i8253_lock; extern unsigned long get_cmos_time(void); extern void machine_real_restart(unsigned char *, int); @@ -1264,7 +1264,7 @@ printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n"); } /* serialize with the timer interrupt */ - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* protect against access to timer chip registers */ spin_lock(&i8253_lock); @@ -1276,7 +1276,7 @@ ignore_normal_resume = 1; spin_unlock(&i8253_lock); - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); if (err == APM_NO_ERROR) err = APM_SUCCESS; @@ -1301,10 +1301,10 @@ int err; /* serialize with the timer interrupt */ - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* If needed, notify drivers here */ get_time_diff(); - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); err = set_system_power_state(APM_STATE_STANDBY); if ((err != APM_SUCCESS) && (err != APM_NO_ERROR)) @@ -1393,9 +1393,9 @@ ignore_bounce = 1; if ((event != APM_NORMAL_RESUME) || (ignore_normal_resume == 0)) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); set_time(); - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); pm_send_all(PM_RESUME, (void *)0); queue_event(event, NULL); } @@ -1410,9 +1410,9 @@ break; case APM_UPDATE_TIME: - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); set_time(); - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); break; case APM_CRITICAL_SUSPEND: diff -Nru a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile --- a/arch/i386/kernel/cpu/cpufreq/Makefile Sun Feb 9 21:13:31 2003 +++ b/arch/i386/kernel/cpu/cpufreq/Makefile Sun Feb 9 21:13:31 2003 @@ -5,3 +5,10 @@ obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o obj-$(CONFIG_X86_LONGRUN) += longrun.o obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o +obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi.o + +ifdef CONFIG_X86_ACPI_CPUFREQ + ifdef CONFIG_ACPI_DEBUG + EXTRA_CFLAGS += -DACPI_DEBUG_OUTPUT + endif +endif diff -Nru a/arch/i386/kernel/cpu/cpufreq/acpi.c b/arch/i386/kernel/cpu/cpufreq/acpi.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/cpu/cpufreq/acpi.c Sun Feb 9 21:13:37 2003 @@ -0,0 +1,696 @@ +/* + * acpi_processor_perf.c - ACPI Processor P-States Driver ($Revision: 71 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * Copyright (C) 2002, 2003 Dominik Brodowski + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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 + +#define ACPI_PROCESSOR_COMPONENT 0x01000000 +#define ACPI_PROCESSOR_CLASS "processor" +#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor P-States Driver" +#define ACPI_PROCESSOR_DEVICE_NAME "Processor" +#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" + +#define _COMPONENT ACPI_PROCESSOR_COMPONENT +ACPI_MODULE_NAME ("acpi_processor_perf") + +MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski"); +MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME); +MODULE_LICENSE("GPL"); + + +/* Performance Management */ + +static struct acpi_processor_performance *performance; +static struct cpufreq_driver acpi_cpufreq_driver; + +static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file); +static struct file_operations acpi_processor_perf_fops = { + .open = acpi_processor_perf_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + +static int +acpi_processor_get_performance_control ( + struct acpi_processor *pr) +{ + int result = 0; + acpi_status status = 0; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *pct = NULL; + union acpi_object obj = {0}; + struct acpi_pct_register *reg = NULL; + + ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control"); + + status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer); + if(ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n")); + return_VALUE(-ENODEV); + } + + pct = (union acpi_object *) buffer.pointer; + if (!pct || (pct->type != ACPI_TYPE_PACKAGE) + || (pct->package.count != 2)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n")); + result = -EFAULT; + goto end; + } + + /* + * control_register + */ + + obj = pct->package.elements[0]; + + if ((obj.type != ACPI_TYPE_BUFFER) + || (obj.buffer.length < sizeof(struct acpi_pct_register)) + || (obj.buffer.pointer == NULL)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Invalid _PCT data (control_register)\n")); + result = -EFAULT; + goto end; + } + + reg = (struct acpi_pct_register *) (obj.buffer.pointer); + + if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unsupported address space [%d] (control_register)\n", + (u32) reg->space_id)); + result = -EFAULT; + goto end; + } + + pr->performance->control_register = (u16) reg->address; + + /* + * status_register + */ + + obj = pct->package.elements[1]; + + if ((obj.type != ACPI_TYPE_BUFFER) + || (obj.buffer.length < sizeof(struct acpi_pct_register)) + || (obj.buffer.pointer == NULL)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Invalid _PCT data (status_register)\n")); + result = -EFAULT; + goto end; + } + + reg = (struct acpi_pct_register *) (obj.buffer.pointer); + + if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unsupported address space [%d] (status_register)\n", + (u32) reg->space_id)); + result = -EFAULT; + goto end; + } + + pr->performance->status_register = (u16) reg->address; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "control_register[0x%04x] status_register[0x%04x]\n", + pr->performance->control_register, + pr->performance->status_register)); + +end: + acpi_os_free(buffer.pointer); + + return_VALUE(result); +} + + +static int +acpi_processor_get_performance_states ( + struct acpi_processor* pr) +{ + int result = 0; + acpi_status status = AE_OK; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + struct acpi_buffer format = {sizeof("NNNNNN"), "NNNNNN"}; + struct acpi_buffer state = {0, NULL}; + union acpi_object *pss = NULL; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states"); + + status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer); + if(ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n")); + return_VALUE(-ENODEV); + } + + pss = (union acpi_object *) buffer.pointer; + if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n")); + result = -EFAULT; + goto end; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n", + pss->package.count)); + + if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) { + pr->performance->state_count = ACPI_PROCESSOR_MAX_PERFORMANCE; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Limiting number of states to max (%d)\n", + ACPI_PROCESSOR_MAX_PERFORMANCE)); + } + else + pr->performance->state_count = pss->package.count; + + if (pr->performance->state_count > 1) + pr->flags.performance = 1; + + for (i = 0; i < pr->performance->state_count; i++) { + + struct acpi_processor_px *px = &(pr->performance->states[i]); + + state.length = sizeof(struct acpi_processor_px); + state.pointer = px; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i)); + + status = acpi_extract_package(&(pss->package.elements[i]), + &format, &state); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n")); + result = -EFAULT; + goto end; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n", + i, + (u32) px->core_frequency, + (u32) px->power, + (u32) px->transition_latency, + (u32) px->bus_master_latency, + (u32) px->control, + (u32) px->status)); + } + +end: + acpi_os_free(buffer.pointer); + + return_VALUE(result); +} + + +static int +acpi_processor_set_performance ( + struct acpi_processor *pr, + int state) +{ + u16 port = 0; + u8 value = 0; + int i = 0; + struct cpufreq_freqs cpufreq_freqs; + + ACPI_FUNCTION_TRACE("acpi_processor_set_performance"); + + if (!pr) + return_VALUE(-EINVAL); + + if (!pr->flags.performance) + return_VALUE(-ENODEV); + + if (state >= pr->performance->state_count) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Invalid target state (P%d)\n", state)); + return_VALUE(-ENODEV); + } + + if (state < pr->performance_platform_limit) { + ACPI_DEBUG_PRINT((ACPI_DB_WARN, + "Platform limit (P%d) overrides target state (P%d)\n", + pr->performance->platform_limit, state)); + return_VALUE(-ENODEV); + } + + if (state == pr->performance->state) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Already at target state (P%d)\n", state)); + return_VALUE(0); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n", + pr->performance->state, state)); + + /* cpufreq frequency struct */ + cpufreq_freqs.cpu = pr->id; + cpufreq_freqs.old = pr->performance->states[pr->performance->state].core_frequency; + cpufreq_freqs.new = pr->performance->states[state].core_frequency; + + /* notify cpufreq */ + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); + + /* + * First we write the target state's 'control' value to the + * control_register. + */ + + port = pr->performance->control_register; + value = (u16) pr->performance->states[state].control; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Writing 0x%02x to port 0x%04x\n", value, port)); + + outb(value, port); + + /* + * Then we read the 'status_register' and compare the value with the + * target state's 'status' to make sure the transition was successful. + * Note that we'll poll for up to 1ms (100 cycles of 10us) before + * giving up. + */ + + port = pr->performance->status_register; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Looking for 0x%02x from port 0x%04x\n", + (u8) pr->performance->states[state].status, port)); + + for (i=0; i<100; i++) { + value = inb(port); + if (value == (u8) pr->performance->states[state].status) + break; + udelay(10); + } + + /* notify cpufreq */ + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); + + if (value != pr->performance->states[state].status) { + unsigned int tmp = cpufreq_freqs.new; + cpufreq_freqs.new = cpufreq_freqs.old; + cpufreq_freqs.old = tmp; + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); + ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n")); + return_VALUE(-ENODEV); + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Transition successful after %d microseconds\n", + i * 10)); + + pr->performance->state = state; + + return_VALUE(0); +} + +static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_processor *pr = (struct acpi_processor *)seq->private; + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_processor_perf_seq_show"); + + if (!pr) + goto end; + + if (!pr->flags.performance) { + seq_puts(seq, "\n"); + goto end; + } + + seq_printf(seq, "state count: %d\n" + "active state: P%d\n", + pr->performance->state_count, + pr->performance->state); + + seq_puts(seq, "states:\n"); + for (i = 0; i < pr->performance->state_count; i++) + seq_printf(seq, " %cP%d: %d MHz, %d mW, %d uS\n", + (i == pr->performance->state?'*':' '), i, + (u32) pr->performance->states[i].core_frequency, + (u32) pr->performance->states[i].power, + (u32) pr->performance->states[i].transition_latency); + +end: + return 0; +} + +static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_processor_perf_seq_show, + PDE(inode)->data); +} + +static int +acpi_processor_write_performance ( + struct file *file, + const char *buffer, + unsigned long count, + void *data) +{ + int result = 0; + struct acpi_processor *pr = (struct acpi_processor *) data; + char state_string[12] = {'\0'}; + unsigned int new_state = 0; + struct cpufreq_policy policy; + + ACPI_FUNCTION_TRACE("acpi_processor_write_performance"); + + if (!pr || !pr->performance || (count > sizeof(state_string) - 1)) + return_VALUE(-EINVAL); + + if (copy_from_user(state_string, buffer, count)) + return_VALUE(-EFAULT); + + state_string[count] = '\0'; + new_state = simple_strtoul(state_string, NULL, 0); + + cpufreq_get_policy(&policy, pr->id); + + policy.cpu = pr->id; + policy.max = pr->performance->states[new_state].core_frequency * 1000; + + result = cpufreq_set_policy(&policy); + if (result) + return_VALUE(result); + + return_VALUE(count); +} + + +static int +acpi_cpufreq_setpolicy ( + struct cpufreq_policy *policy) +{ + struct acpi_processor *pr = performance[policy->cpu].pr; + unsigned int next_state = 0; + unsigned int result = 0; + + ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy"); + + result = cpufreq_frequency_table_setpolicy(policy, + &performance[policy->cpu].freq_table[pr->limit.state.px], + &next_state); + if (result) + return_VALUE(result); + + result = acpi_processor_set_performance (pr, next_state); + + return_VALUE(result); +} + + +static int +acpi_cpufreq_verify ( + struct cpufreq_policy *policy) +{ + unsigned int result = 0; + unsigned int cpu = policy->cpu; + struct acpi_processor *pr = performance[policy->cpu].pr; + + ACPI_FUNCTION_TRACE("acpi_cpufreq_verify"); + + result = cpufreq_frequency_table_verify(policy, + &performance[cpu].freq_table[pr->limit.state.px]); + + cpufreq_verify_within_limits( + policy, + performance[cpu].states[performance[cpu].state_count - 1].core_frequency * 1000, + performance[cpu].states[pr->limit.state.px].core_frequency * 1000); + + return_VALUE(result); +} + + +static int +acpi_processor_get_performance_info ( + struct acpi_processor *pr) +{ + int result = 0; + acpi_status status = AE_OK; + acpi_handle handle = NULL; + + ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info"); + + if (!pr) + return_VALUE(-EINVAL); + + status = acpi_get_handle(pr->handle, "_PCT", &handle); + if (ACPI_FAILURE(status)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "ACPI-based processor performance control unavailable\n")); + return_VALUE(-ENODEV); + } + + result = acpi_processor_get_performance_control(pr); + if (result) + return_VALUE(result); + + result = acpi_processor_get_performance_states(pr); + if (result) + return_VALUE(result); + + result = acpi_processor_get_platform_limit(pr); + if (result) + return_VALUE(result); + + return_VALUE(0); +} + +static int +acpi_cpufreq_cpu_init ( + struct cpufreq_policy *policy) +{ + unsigned int i; + unsigned int cpu = policy->cpu; + struct acpi_processor *pr = NULL; + unsigned int result = 0; + struct proc_dir_entry *entry = NULL; + struct acpi_device *device = NULL; + + ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init"); + + acpi_processor_register_performance(&performance[cpu], &pr, cpu); + + pr = performance[cpu].pr; + if (!pr) + return_VALUE(-ENODEV); + + if (acpi_bus_get_device(pr->handle, &device)) + return_VALUE(-ENODEV); + + result = acpi_processor_get_performance_info(performance[cpu].pr); + if (result) + return_VALUE(-ENODEV); + + /* capability check */ + if (!pr->flags.performance) + return_VALUE(-ENODEV); + + /* detect transition latency */ + policy->cpuinfo.transition_latency = 0; + for (i=0;i policy->cpuinfo.transition_latency) + policy->cpuinfo.transition_latency = performance[cpu].states[i].transition_latency; + } + policy->policy = CPUFREQ_POLICY_PERFORMANCE; + + /* table init */ + for (i=0; i<=performance[cpu].state_count; i++) + { + performance[cpu].freq_table[i].index = i; + if (icpu] = performance[cpu].states[pr->limit.state.px].core_frequency * 1000; +#endif + + result = cpufreq_frequency_table_cpuinfo(policy, &performance[cpu].freq_table[0]); + + /* add file 'performance' [R/W] */ + entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE, + S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); + if (!entry) + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Unable to create '%s' fs entry\n", + ACPI_PROCESSOR_FILE_PERFORMANCE)); + else { + entry->proc_fops = &acpi_processor_perf_fops; + entry->write_proc = acpi_processor_write_performance; + entry->data = acpi_driver_data(device); + } + + return_VALUE(result); +} + + +static int __init +acpi_cpufreq_init (void) +{ + int result = 0; + int current_state = 0; + int i = 0; + struct acpi_processor *pr; + + ACPI_FUNCTION_TRACE("acpi_cpufreq_init"); + + /* alloc memory */ + if (performance) + return_VALUE(-EBUSY); + + performance = kmalloc(NR_CPUS * sizeof(struct acpi_processor_performance), GFP_KERNEL); + if (!performance) + return_VALUE(-ENOMEM); + + memset(performance, 0, NR_CPUS * sizeof(struct acpi_processor_performance)); + + /* register struct acpi_performance performance */ + for (i=0; iflags.performance) + goto found_capable_cpu; + } + result = -ENODEV; + goto err; + + found_capable_cpu: + current_state = pr->performance->state; + + if (current_state == pr->limit.state.px) { + result = acpi_processor_set_performance(pr, (pr->performance->state_count - 1)); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n")); + result = -ENODEV; + goto err; + } + } + + result = acpi_processor_set_performance(pr, pr->limit.state.px); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n")); + result = -ENODEV; + goto err; + } + + if (current_state != 0) { + result = acpi_processor_set_performance(pr, current_state); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n")); + result = -ENODEV; + goto err; + } + } + + result = cpufreq_register_driver(&acpi_cpufreq_driver); + if (result) + goto err; + + return_VALUE(0); + + /* error handling */ + err: + /* unregister struct acpi_performance performance */ + for (i=0; iflags.performance = 0; + performance[i].pr->performance = NULL; + performance[i].pr = NULL; + } + } + + kfree(performance); + + return_VALUE(result); +} + + +static void __exit +acpi_cpufreq_exit (void) +{ + int i = 0; + + ACPI_FUNCTION_TRACE("acpi_cpufreq_exit"); + + for (i=0; iflags.performance = 0; + } + + cpufreq_unregister_driver(&acpi_cpufreq_driver); + + /* unregister struct acpi_performance performance */ + for (i=0; iflags.performance = 0; + performance[i].pr->performance = NULL; + performance[i].pr = NULL; + } + } + + kfree(performance); + + return_VOID; +} + +static struct cpufreq_driver acpi_cpufreq_driver = { + .verify = acpi_cpufreq_verify, + .setpolicy = acpi_cpufreq_setpolicy, + .init = acpi_cpufreq_cpu_init, + .exit = NULL, + .policy = NULL, + .name = "acpi-cpufreq", +}; + + +late_initcall(acpi_cpufreq_init); +module_exit(acpi_cpufreq_exit); diff -Nru a/arch/i386/kernel/cpu/mtrr/Makefile b/arch/i386/kernel/cpu/mtrr/Makefile --- a/arch/i386/kernel/cpu/mtrr/Makefile Sun Feb 9 21:13:28 2003 +++ b/arch/i386/kernel/cpu/mtrr/Makefile Sun Feb 9 21:13:28 2003 @@ -3,4 +3,3 @@ obj-y += cyrix.o obj-y += centaur.o -export-objs := main.o diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c --- a/arch/i386/kernel/dmi_scan.c Sun Feb 9 21:13:31 2003 +++ b/arch/i386/kernel/dmi_scan.c Sun Feb 9 21:13:31 2003 @@ -450,17 +450,6 @@ } /* - * ASUS K7V-RM has broken ACPI table defining sleep modes - */ - -static __init int broken_acpi_Sx(struct dmi_blacklist *d) -{ - printk(KERN_WARNING "Detected ASUS mainboard with broken ACPI sleep table\n"); - dmi_broken |= BROKEN_ACPI_Sx; - return 0; -} - -/* * Toshiba keyboard likes to repeat keys when they are not repeated. */ @@ -744,12 +733,6 @@ { broken_pirq, "Dell PowerEdge 8450", { /* Bad $PIR */ MATCH(DMI_PRODUCT_NAME, "Dell PowerEdge 8450"), NO_MATCH, NO_MATCH, NO_MATCH - } }, - - { broken_acpi_Sx, "ASUS K7V-RM", { /* Bad ACPI Sx table */ - MATCH(DMI_BIOS_VERSION,"ASUS K7V-RM ACPI BIOS Revision 1003A"), - MATCH(DMI_BOARD_NAME, ""), - NO_MATCH, NO_MATCH } }, { broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */ diff -Nru a/arch/i386/kernel/edd.c b/arch/i386/kernel/edd.c --- a/arch/i386/kernel/edd.c Sun Feb 9 21:13:30 2003 +++ b/arch/i386/kernel/edd.c Sun Feb 9 21:13:30 2003 @@ -1,6 +1,6 @@ /* * linux/arch/i386/kernel/edd.c - * Copyright (C) 2002 Dell Computer Corporation + * Copyright (C) 2002, 2003 Dell Computer Corporation * by Matt Domsch * * BIOS Enhanced Disk Drive Services (EDD) @@ -11,7 +11,7 @@ * fn41 - Check Extensions Present and * fn48 - Get Device Parametes with EDD extensions * made in setup.S, copied to safe structures in setup.c, - * and presents it in driverfs. + * and presents it in sysfs. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License v2.0 as published by @@ -30,8 +30,6 @@ * * TODO: * - Add IDE and USB disk device support - * - Get symlink creator helper functions exported from - * drivers/base instead of duplicating them here. * - move edd.[ch] to better locations if/when one is decided */ @@ -46,18 +44,18 @@ #include #include #include -#include #include #include +#include /* FIXME - this really belongs in include/scsi/scsi.h */ #include <../drivers/scsi/scsi.h> #include <../drivers/scsi/hosts.h> MODULE_AUTHOR("Matt Domsch "); -MODULE_DESCRIPTION("driverfs interface to BIOS EDD information"); +MODULE_DESCRIPTION("sysfs interface to BIOS EDD information"); MODULE_LICENSE("GPL"); -#define EDD_VERSION "0.07 2002-Oct-24" +#define EDD_VERSION "0.09 2003-Jan-22" #define EDD_DEVICE_NAME_SIZE 16 #define REPORT_URL "http://domsch.com/linux/edd30/results.html" @@ -78,6 +76,7 @@ static int edd_dev_is_type(struct edd_device *edev, const char *type); static struct pci_dev *edd_get_pci_dev(struct edd_device *edev); static struct scsi_device *edd_find_matching_scsi_device(struct edd_device *edev); +static int kernel_has_scsi(void); static struct edd_device *edd_devices[EDDMAXNR]; @@ -93,6 +92,7 @@ { return edev->info; } + static inline void edd_dev_set_info(struct edd_device *edev, struct edd_info *info) { @@ -263,8 +263,8 @@ edd_show_raw_data(struct edd_device *edev, char *buf) { struct edd_info *info = edd_dev_get_info(edev); - int i, rc, warn_padding = 0, email = 0, nonzero_path = 0, - len = sizeof (*edd) - 4, found_pci=0; + int i, warn_padding = 0, nonzero_path = 0, + len = sizeof (*info) - 4, found_pci=0; uint8_t checksum = 0, c = 0; char *p = buf; struct pci_dev *pci_dev=NULL; @@ -277,7 +277,7 @@ len = info->params.length; p += snprintf(p, left, "int13 fn48 returned data:\n\n"); - p += edd_dump_raw_data(p, left, ((char *) edd) + 4, len); + p += edd_dump_raw_data(p, left, ((char *) info) + 4, len); /* Spec violation. Adaptec AIC7899 returns 0xDDBE here, when it should be 0xBEDD. @@ -286,7 +286,6 @@ if (info->params.key == 0xDDBE) { p += snprintf(p, left, "Warning: Spec violation. Key should be 0xBEDD, is 0xDDBE\n"); - email++; } if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) { @@ -294,7 +293,7 @@ } for (i = 30; i <= 73; i++) { - c = *(((uint8_t *) edd) + i + 4); + c = *(((uint8_t *) info) + i + 4); if (c) nonzero_path++; checksum += c; @@ -303,12 +302,10 @@ if (checksum) { p += snprintf(p, left, "Warning: Spec violation. Device Path checksum invalid.\n"); - email++; } if (!nonzero_path) { p += snprintf(p, left, "Error: Spec violation. Empty device path.\n"); - email++; goto out; } @@ -326,45 +323,35 @@ if (warn_padding) { p += snprintf(p, left, "Warning: Spec violation. Padding should be 0x20.\n"); - email++; } - rc = edd_dev_is_type(edev, "PCI"); - if (!rc) { - pci_dev = pci_find_slot(info->params.interface_path.pci.bus, - PCI_DEVFN(info->params.interface_path. - pci.slot, - info->params.interface_path. - pci.function)); + if (edd_dev_is_type(edev, "PCI")) { + pci_dev = edd_get_pci_dev(edev); if (!pci_dev) { p += snprintf(p, left, "Error: BIOS says this is a PCI device, but the OS doesn't know\n"); p += snprintf(p, left, " about a PCI device at %02x:%02x.%d\n", info->params.interface_path.pci.bus, info->params.interface_path.pci.slot, info->params.interface_path.pci.function); - email++; } else { found_pci++; } } - if (found_pci && !edd_dev_is_type(edev, "SCSI")) { + if (found_pci && kernel_has_scsi() && edd_dev_is_type(edev, "SCSI")) { sd = edd_find_matching_scsi_device(edev); if (!sd) { p += snprintf(p, left, "Error: BIOS says this is a SCSI device, but\n"); p += snprintf(p, left, " the OS doesn't know about this SCSI device.\n"); p += snprintf(p, left, " Do you have it's driver module loaded?\n"); - email++; } } out: - if (email) { - p += snprintf(p, left, "\nPlease check %s\n", REPORT_URL); - p += snprintf(p, left, "to see if this has been reported. If not,\n"); - p += snprintf(p, left, "please send the information requested there.\n"); - } + p += snprintf(p, left, "\nPlease check %s\n", REPORT_URL); + p += snprintf(p, left, "to see if this device has been reported. If not,\n"); + p += snprintf(p, left, "please send the information requested there.\n"); return (p - buf); } @@ -502,8 +489,8 @@ { struct edd_info *info = edd_dev_get_info(edev); if (!edev || !info) - return 1; - return !info->params.num_default_cylinders; + return 0; + return info->params.num_default_cylinders > 0; } static int @@ -511,8 +498,8 @@ { struct edd_info *info = edd_dev_get_info(edev); if (!edev || !info) - return 1; - return !info->params.num_default_heads; + return 0; + return info->params.num_default_heads > 0; } static int @@ -520,8 +507,8 @@ { struct edd_info *info = edd_dev_get_info(edev); if (!edev || !info) - return 1; - return !info->params.sectors_per_track; + return 0; + return info->params.sectors_per_track > 0; } static int @@ -532,24 +519,24 @@ char c; if (!edev || !info) - return 1; + return 0; if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) { - return 1; + return 0; } for (i = 30; i <= 73; i++) { - c = *(((uint8_t *) edd) + i + 4); + c = *(((uint8_t *) info) + i + 4); if (c) { nonzero_path++; break; } } if (!nonzero_path) { - return 1; + return 0; } - return 0; + return 1; } static EDD_DEVICE_ATTR(raw_data, 0444, edd_show_raw_data, NULL); @@ -590,7 +577,23 @@ NULL, }; +/** + * edd_release - free edd structure + * @kobj: kobject of edd structure + * + * This is called when the refcount of the edd structure + * reaches 0. This should happen right after we unregister, + * but just in case, we use the release callback anyway. + */ + +static void edd_release(struct kobject * kobj) +{ + struct edd_device * dev = to_edd_device(kobj); + kfree(dev); +} + static struct kobj_type ktype_edd = { + .release = edd_release, .sysfs_ops = &edd_attr_ops, .default_attrs = def_attrs, }; @@ -598,27 +601,24 @@ static decl_subsys(edd,&ktype_edd); - /** * edd_dev_is_type() - is this EDD device a 'type' device? * @edev * @type - a host bus or interface identifier string per the EDD spec * - * Returns 0 if it is a 'type' device, nonzero otherwise. + * Returns 1 (TRUE) if it is a 'type' device, 0 otherwise. */ static int edd_dev_is_type(struct edd_device *edev, const char *type) { - int rc; struct edd_info *info = edd_dev_get_info(edev); - if (!edev || !info) - return 1; - rc = strncmp(info->params.host_bus_type, type, strlen(type)); - if (!rc) - return 0; - - return strncmp(info->params.interface_type, type, strlen(type)); + if (edev && type && info) { + if (!strncmp(info->params.host_bus_type, type, strlen(type)) || + !strncmp(info->params.interface_type, type, strlen(type))) + return 1; + } + return 0; } /** @@ -631,16 +631,14 @@ edd_get_pci_dev(struct edd_device *edev) { struct edd_info *info = edd_dev_get_info(edev); - int rc; - - rc = edd_dev_is_type(edev, "PCI"); - if (rc) - return NULL; - return pci_find_slot(info->params.interface_path.pci.bus, - PCI_DEVFN(info->params.interface_path.pci.slot, - info->params.interface_path.pci. - function)); + if (edd_dev_is_type(edev, "PCI")) { + return pci_find_slot(info->params.interface_path.pci.bus, + PCI_DEVFN(info->params.interface_path.pci.slot, + info->params.interface_path.pci. + function)); + } + return NULL; } static int @@ -653,105 +651,117 @@ return sysfs_create_link(&edev->kobj,&pci_dev->dev.kobj,"pci_dev"); } +/* + * FIXME - as of 15-Jan-2003, there are some non-"scsi_device"s on the + * scsi_bus list. The following functions could possibly mis-access + * memory in that case. This is actually a problem with the SCSI + * layer, which is being addressed there. Until then, don't use the + * SCSI functions. + */ + +#undef CONFIG_SCSI +#undef CONFIG_SCSI_MODULE +#if defined(CONFIG_SCSI) || defined(CONFIG_SCSI_MODULE) + +struct edd_match_data { + struct edd_device * edev; + struct scsi_device * sd; +}; + /** * edd_match_scsidev() * @edev - EDD device is a known SCSI device * @sd - scsi_device with host who's parent is a PCI controller * - * returns 0 on success, 1 on failure + * returns 1 if a match is found, 0 if not. */ -static int -edd_match_scsidev(struct edd_device *edev, struct scsi_device *sd) +static int edd_match_scsidev(struct device * dev, void * d) { - struct edd_info *info = edd_dev_get_info(edev); - - if (!edev || !sd || !info) - return 1; - - if ((sd->channel == info->params.interface_path.pci.channel) && - (sd->id == info->params.device_path.scsi.id) && - (sd->lun == info->params.device_path.scsi.lun)) { - return 0; + struct edd_match_data * data = (struct edd_match_data *)d; + struct edd_info *info = edd_dev_get_info(data->edev); + struct scsi_device * sd = to_scsi_device(dev); + + if (info) { + if ((sd->channel == info->params.interface_path.pci.channel) && + (sd->id == info->params.device_path.scsi.id) && + (sd->lun == info->params.device_path.scsi.lun)) { + data->sd = sd; + return 1; + } } - - return 1; + return 0; } /** * edd_find_matching_device() * @edev - edd_device to match * - * Returns struct scsi_device * on success, - * or NULL on failure. - * This assumes that all children of the PCI controller - * are scsi_hosts, and that all children of scsi_hosts - * are scsi_devices. - * The reference counting probably isn't the best it could be. + * Search the SCSI devices for a drive that matches the EDD + * device descriptor we have. If we find a match, return it, + * otherwise, return NULL. */ -#define children_to_dev(n) container_of(n,struct device,node) static struct scsi_device * edd_find_matching_scsi_device(struct edd_device *edev) { - struct list_head *sdev_node; - int rc = 1; - struct scsi_device *sd = NULL; - struct pci_dev *pci_dev; - - rc = edd_dev_is_type(edev, "SCSI"); - if (rc) - return NULL; + struct edd_match_data data; + struct bus_type * scsi_bus = find_bus("scsi"); - pci_dev = edd_get_pci_dev(edev); - if (!pci_dev) + if (!scsi_bus) { return NULL; + } - get_device(&pci_dev->dev); + data.edev = edev; - list_for_each(sdev_node, &pci_dev->dev.children) { - struct device *sdev_dev = children_to_dev(sdev_node); - get_device(sdev_dev); - sd = to_scsi_device(sdev_dev); - rc = edd_match_scsidev(edev, sd); - put_device(sdev_dev); - if (!rc) - break; + if (edd_dev_is_type(edev, "SCSI")) { + if (bus_for_each_dev(scsi_bus,NULL,&data,edd_match_scsidev)) + return data.sd; } - - put_device(&pci_dev->dev); - return rc ? NULL : sd; + return NULL; } static int edd_create_symlink_to_scsidev(struct edd_device *edev) { - - struct scsi_device *sdev; struct pci_dev *pci_dev; - struct edd_info *info = edd_dev_get_info(edev); - int rc; + int rc = -EINVAL; - rc = edd_dev_is_type(edev, "PCI"); - if (rc) - return rc; - - pci_dev = pci_find_slot(info->params.interface_path.pci.bus, - PCI_DEVFN(info->params.interface_path.pci.slot, - info->params.interface_path.pci. - function)); - if (!pci_dev) - return 1; + pci_dev = edd_get_pci_dev(edev); + if (pci_dev) { + struct scsi_device * sdev = edd_find_matching_scsi_device(edev); + if (sdev && get_device(&sdev->sdev_driverfs_dev)) { + rc = sysfs_create_link(&edev->kobj, + &sdev->sdev_driverfs_dev.kobj, + "disc"); + put_device(&sdev->sdev_driverfs_dev); + } + } + return rc; +} - sdev = edd_find_matching_scsi_device(edev); - if (!sdev) - return 1; +static int kernel_has_scsi(void) +{ + return 1; +} - get_device(&sdev->sdev_driverfs_dev); - rc = sysfs_create_link(&edev->kobj,&sdev->sdev_driverfs_dev.kobj, "disc"); - put_device(&sdev->sdev_driverfs_dev); +#else +static int kernel_has_scsi(void) +{ + return 0; +} - return rc; +static struct scsi_device * +edd_find_matching_scsi_device(struct edd_device *edev) +{ + return NULL; } +static int +edd_create_symlink_to_scsidev(struct edd_device *edev) +{ + return -ENOSYS; +} +#endif + static inline void edd_device_unregister(struct edd_device *edev) @@ -759,7 +769,7 @@ kobject_unregister(&edev->kobj); } -static void populate_dir(struct edd_device * edev) +static void edd_populate_dir(struct edd_device * edev) { struct edd_attribute * attr; int error = 0; @@ -767,7 +777,7 @@ for (i = 0; (attr = edd_attrs[i]) && !error; i++) { if (!attr->test || - (attr->test && !attr->test(edev))) + (attr->test && attr->test(edev))) error = sysfs_create_file(&edev->kobj,&attr->attr); } @@ -791,12 +801,12 @@ kobj_set_kset_s(edev,edd_subsys); error = kobject_register(&edev->kobj); if (!error) - populate_dir(edev); + edd_populate_dir(edev); return error; } /** - * edd_init() - creates driverfs tree of EDD data + * edd_init() - creates sysfs tree of EDD data * * This assumes that eddnr and edd were * assigned in setup.c already. @@ -845,10 +855,8 @@ struct edd_device *edev; for (i = 0; i < eddnr && i < EDDMAXNR; i++) { - if ((edev = edd_devices[i])) { + if ((edev = edd_devices[i])) edd_device_unregister(edev); - kfree(edev); - } } firmware_unregister(&edd_subsys); } diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S --- a/arch/i386/kernel/entry.S Sun Feb 9 21:13:30 2003 +++ b/arch/i386/kernel/entry.S Sun Feb 9 21:13:30 2003 @@ -792,8 +792,8 @@ .long sys_io_getevents .long sys_io_submit .long sys_io_cancel - .long sys_ni_syscall /* 250 sys_alloc_hugepages - reuse this */ - .long sys_ni_syscall /* was sys_free_hugepages - reuse this */ + .long sys_fadvise64 /* 250 */ + .long sys_ni_syscall .long sys_exit_group .long sys_lookup_dcookie .long sys_epoll_create diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c --- a/arch/i386/kernel/i386_ksyms.c Sun Feb 9 21:13:37 2003 +++ b/arch/i386/kernel/i386_ksyms.c Sun Feb 9 21:13:37 2003 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff -Nru a/arch/i386/kernel/init_task.c b/arch/i386/kernel/init_task.c --- a/arch/i386/kernel/init_task.c Sun Feb 9 21:13:36 2003 +++ b/arch/i386/kernel/init_task.c Sun Feb 9 21:13:36 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/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c --- a/arch/i386/kernel/io_apic.c Sun Feb 9 21:13:30 2003 +++ b/arch/i386/kernel/io_apic.c Sun Feb 9 21:13:30 2003 @@ -207,19 +207,34 @@ spin_unlock_irqrestore(&ioapic_lock, flags); } -#if CONFIG_SMP - -typedef struct { - unsigned int cpu; - unsigned long timestamp; -} ____cacheline_aligned irq_balance_t; - -static irq_balance_t irq_balance[NR_IRQS] __cacheline_aligned - = { [ 0 ... NR_IRQS-1 ] = { 0, 0 } }; +#if defined(CONFIG_SMP) +# include /* kernel_thread() */ +# include /* kstat */ +# include /* kmalloc() */ +# include /* time_after() */ + +# if CONFIG_BALANCED_IRQ_DEBUG +# define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0) +# define Dprintk(x...) do { TDprintk(x); } while (0) +# else +# define TDprintk(x...) +# define Dprintk(x...) +# endif extern unsigned long irq_affinity [NR_IRQS]; - -#endif +unsigned long __cacheline_aligned irq_balance_mask [NR_IRQS]; +static int irqbalance_disabled __initdata = 0; +static int physical_balance = 0; + +struct irq_cpu_info { + unsigned long * last_irq; + unsigned long * irq_delta; + unsigned long irq; +} irq_cpu_data[NR_CPUS]; + +#define CPU_IRQ(cpu) (irq_cpu_data[cpu].irq) +#define LAST_CPU_IRQ(cpu,irq) (irq_cpu_data[cpu].last_irq[irq]) +#define IRQ_DELTA(cpu,irq) (irq_cpu_data[cpu].irq_delta[irq]) #define IDLE_ENOUGH(cpu,now) \ (idle_cpu(cpu) && ((now) - irq_stat[(cpu)].idle_timestamp > 1)) @@ -227,10 +242,224 @@ #define IRQ_ALLOWED(cpu,allowed_mask) \ ((1 << cpu) & (allowed_mask)) -#if CONFIG_SMP +#define CPU_TO_PACKAGEINDEX(i) \ + ((physical_balance && i > cpu_sibling_map[i]) ? cpu_sibling_map[i] : i) + +#define MAX_BALANCED_IRQ_INTERVAL (5*HZ) +#define MIN_BALANCED_IRQ_INTERVAL (HZ/2) +#define BALANCED_IRQ_MORE_DELTA (HZ/10) +#define BALANCED_IRQ_LESS_DELTA (HZ) + +long balanced_irq_interval = MAX_BALANCED_IRQ_INTERVAL; + +static inline void balance_irq(int cpu, int irq); + +static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) +{ + int i, j; + Dprintk("Rotating IRQs among CPUs.\n"); + for (i = 0; i < NR_CPUS; i++) { + for (j = 0; cpu_online(i) && (j < NR_IRQS); j++) { + if (!irq_desc[j].action) + continue; + /* Is it a significant load ? */ + if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i),j) < useful_load_threshold) + continue; + balance_irq(i, j); + } + } + balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, + balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); + return; +} + +static void do_irq_balance(void) +{ + int i, j; + unsigned long max_cpu_irq = 0, min_cpu_irq = (~0); + unsigned long move_this_load = 0; + int max_loaded = 0, min_loaded = 0; + unsigned long useful_load_threshold = balanced_irq_interval + 10; + int selected_irq; + int tmp_loaded, first_attempt = 1; + unsigned long tmp_cpu_irq; + unsigned long imbalance = 0; + unsigned long allowed_mask; + unsigned long target_cpu_mask; + + for (i = 0; i < NR_CPUS; i++) { + int package_index; + CPU_IRQ(i) = 0; + if (!cpu_online(i)) + continue; + package_index = CPU_TO_PACKAGEINDEX(i); + for (j = 0; j < NR_IRQS; j++) { + unsigned long value_now, delta; + /* Is this an active IRQ? */ + if (!irq_desc[j].action) + continue; + if ( package_index == i ) + IRQ_DELTA(package_index,j) = 0; + /* Determine the total count per processor per IRQ */ + value_now = (unsigned long) kstat_cpu(i).irqs[j]; + + /* Determine the activity per processor per IRQ */ + delta = value_now - LAST_CPU_IRQ(i,j); + + /* Update last_cpu_irq[][] for the next time */ + LAST_CPU_IRQ(i,j) = value_now; + + /* Ignore IRQs whose rate is less than the clock */ + if (delta < useful_load_threshold) + continue; + /* update the load for the processor or package total */ + IRQ_DELTA(package_index,j) += delta; + + /* Keep track of the higher numbered sibling as well */ + if (i != package_index) + CPU_IRQ(i) += delta; + /* + * We have sibling A and sibling B in the package + * + * cpu_irq[A] = load for cpu A + load for cpu B + * cpu_irq[B] = load for cpu B + */ + CPU_IRQ(package_index) += delta; + } + } + /* Find the least loaded processor package */ + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; + if (physical_balance && i > cpu_sibling_map[i]) + continue; + if (min_cpu_irq > CPU_IRQ(i)) { + min_cpu_irq = CPU_IRQ(i); + min_loaded = i; + } + } + max_cpu_irq = ULONG_MAX; + +tryanothercpu: + /* Look for heaviest loaded processor. + * We may come back to get the next heaviest loaded processor. + * Skip processors with trivial loads. + */ + tmp_cpu_irq = 0; + tmp_loaded = -1; + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; + if (physical_balance && i > cpu_sibling_map[i]) + continue; + if (max_cpu_irq <= CPU_IRQ(i)) + continue; + if (tmp_cpu_irq < CPU_IRQ(i)) { + tmp_cpu_irq = CPU_IRQ(i); + tmp_loaded = i; + } + } -#define IRQ_BALANCE_INTERVAL (HZ/50) + if (tmp_loaded == -1) { + /* In the case of small number of heavy interrupt sources, + * loading some of the cpus too much. We use Ingo's original + * approach to rotate them around. + */ + if (!first_attempt && imbalance >= useful_load_threshold) { + rotate_irqs_among_cpus(useful_load_threshold); + return; + } + goto not_worth_the_effort; + } + + first_attempt = 0; /* heaviest search */ + max_cpu_irq = tmp_cpu_irq; /* load */ + max_loaded = tmp_loaded; /* processor */ + imbalance = (max_cpu_irq - min_cpu_irq) / 2; + Dprintk("max_loaded cpu = %d\n", max_loaded); + Dprintk("min_loaded cpu = %d\n", min_loaded); + Dprintk("max_cpu_irq load = %ld\n", max_cpu_irq); + Dprintk("min_cpu_irq load = %ld\n", min_cpu_irq); + Dprintk("load imbalance = %lu\n", imbalance); + + /* if imbalance is less than approx 10% of max load, then + * observe diminishing returns action. - quit + */ + if (imbalance < (max_cpu_irq >> 3)) { + Dprintk("Imbalance too trivial\n"); + goto not_worth_the_effort; + } + +tryanotherirq: + /* if we select an IRQ to move that can't go where we want, then + * see if there is another one to try. + */ + move_this_load = 0; + selected_irq = -1; + for (j = 0; j < NR_IRQS; j++) { + /* Is this an active IRQ? */ + if (!irq_desc[j].action) + continue; + if (imbalance <= IRQ_DELTA(max_loaded,j)) + continue; + /* Try to find the IRQ that is closest to the imbalance + * without going over. + */ + if (move_this_load < IRQ_DELTA(max_loaded,j)) { + move_this_load = IRQ_DELTA(max_loaded,j); + selected_irq = j; + } + } + if (selected_irq == -1) { + goto tryanothercpu; + } + + imbalance = move_this_load; + + /* For physical_balance case, we accumlated both load + * values in the one of the siblings cpu_irq[], + * to use the same code for physical and logical processors + * as much as possible. + * + * NOTE: the cpu_irq[] array holds the sum of the load for + * sibling A and sibling B in the slot for the lowest numbered + * sibling (A), _AND_ the load for sibling B in the slot for + * the higher numbered sibling. + * + * We seek the least loaded sibling by making the comparison + * (A+B)/2 vs B + */ + if (physical_balance && (CPU_IRQ(min_loaded) >> 1) > CPU_IRQ(cpu_sibling_map[min_loaded])) + min_loaded = cpu_sibling_map[min_loaded]; + + allowed_mask = cpu_online_map & irq_affinity[selected_irq]; + target_cpu_mask = 1 << min_loaded; + + if (target_cpu_mask & allowed_mask) { + irq_desc_t *desc = irq_desc + selected_irq; + Dprintk("irq = %d moved to cpu = %d\n", selected_irq, min_loaded); + /* mark for change destination */ + spin_lock(&desc->lock); + irq_balance_mask[selected_irq] = target_cpu_mask; + spin_unlock(&desc->lock); + /* Since we made a change, come back sooner to + * check for more variation. + */ + balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL, + balanced_irq_interval - BALANCED_IRQ_LESS_DELTA); + return; + } + goto tryanotherirq; + +not_worth_the_effort: + /* if we did not find an IRQ to move, then adjust the time interval upward */ + balanced_irq_interval = min((long)MAX_BALANCED_IRQ_INTERVAL, + balanced_irq_interval + BALANCED_IRQ_MORE_DELTA); + Dprintk("IRQ worth rotating not found\n"); + return; +} + static unsigned long move(int curr_cpu, unsigned long allowed_mask, unsigned long now, int direction) { int search_idle = 1; @@ -257,34 +486,113 @@ return cpu; } -static inline void balance_irq(int irq) +static inline void balance_irq (int cpu, int irq) { - irq_balance_t *entry = irq_balance + irq; unsigned long now = jiffies; - + unsigned long allowed_mask; + unsigned int new_cpu; + if (no_balance_irq) return; - if (unlikely(time_after(now, entry->timestamp + IRQ_BALANCE_INTERVAL))) { - unsigned long allowed_mask; - unsigned int new_cpu; - int random_number; - - rdtscl(random_number); - random_number &= 1; - - allowed_mask = cpu_online_map & irq_affinity[irq]; - entry->timestamp = now; - new_cpu = move(entry->cpu, allowed_mask, now, random_number); - if (entry->cpu != new_cpu) { - entry->cpu = new_cpu; - set_ioapic_affinity(irq, cpu_to_logical_apicid(new_cpu)); + allowed_mask = cpu_online_map & irq_affinity[irq]; + new_cpu = move(cpu, allowed_mask, now, 1); + if (cpu != new_cpu) { + irq_desc_t *desc = irq_desc + irq; + spin_lock(&desc->lock); + irq_balance_mask[irq] = cpu_to_logical_apicid(new_cpu); + spin_unlock(&desc->lock); + } +} + +int balanced_irq(void *unused) +{ + int i; + unsigned long prev_balance_time = jiffies; + long time_remaining = balanced_irq_interval; + daemonize(); + sigfillset(¤t->blocked); + sprintf(current->comm, "kirqd"); + + /* push everything to CPU 0 to give us a starting point. */ + for (i = 0 ; i < NR_IRQS ; i++) + irq_balance_mask[i] = 1 << 0; + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + time_remaining = schedule_timeout(time_remaining); + if (time_after(jiffies, prev_balance_time+balanced_irq_interval)) { + Dprintk("balanced_irq: calling do_irq_balance() %lu\n", jiffies); + do_irq_balance(); + prev_balance_time = jiffies; + time_remaining = balanced_irq_interval; } + } +} + +static int __init balanced_irq_init(void) +{ + int i; + struct cpuinfo_x86 *c; + c = &boot_cpu_data; + if (irqbalance_disabled) + return 0; + /* Enable physical balance only if more than 1 physical processor is present */ + if (smp_num_siblings > 1 && cpu_online_map >> 2) + physical_balance = 1; + + for (i = 0; i < NR_CPUS; i++) { + if (!cpu_online(i)) + continue; + irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); + irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); + if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { + printk(KERN_ERR "balanced_irq_init: out of memory"); + goto failed; + } + memset(irq_cpu_data[i].irq_delta,0,sizeof(unsigned long) * NR_IRQS); + memset(irq_cpu_data[i].last_irq,0,sizeof(unsigned long) * NR_IRQS); + } + + printk(KERN_INFO "Starting balanced_irq\n"); + if (kernel_thread(balanced_irq, NULL, CLONE_KERNEL) >= 0) + return 0; + else + printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); +failed: + for (i = 0; i < NR_CPUS; i++) { + if(irq_cpu_data[i].irq_delta) + kfree(irq_cpu_data[i].irq_delta); + if(irq_cpu_data[i].last_irq) + kfree(irq_cpu_data[i].last_irq); } + return 0; } + +static int __init irqbalance_disable(char *str) +{ + irqbalance_disabled = 1; + return 0; +} + +__setup("noirqbalance", irqbalance_disable); + +static void set_ioapic_affinity (unsigned int irq, unsigned long mask); + +static inline void move_irq(int irq) +{ + /* note - we hold the desc->lock */ + if (unlikely(irq_balance_mask[irq])) { + set_ioapic_affinity(irq, irq_balance_mask[irq]); + irq_balance_mask[irq] = 0; + } +} + +__initcall(balanced_irq_init); + #else /* !SMP */ -static inline void balance_irq(int irq) { } -#endif +static inline void move_irq(int irq) { } +#endif /* defined(CONFIG_SMP) */ + /* * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to @@ -1307,7 +1615,7 @@ */ static void ack_edge_ioapic_irq(unsigned int irq) { - balance_irq(irq); + move_irq(irq); if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) == (IRQ_PENDING | IRQ_DISABLED)) mask_IO_APIC_irq(irq); @@ -1347,7 +1655,7 @@ unsigned long v; int i; - balance_irq(irq); + move_irq(irq); /* * It appears there is an erratum which affects at least version 0x11 * of I/O APIC (that's the 82093AA and cores integrated into various diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c --- a/arch/i386/kernel/irq.c Sun Feb 9 21:13:28 2003 +++ b/arch/i386/kernel/irq.c Sun Feb 9 21:13:28 2003 @@ -338,9 +338,9 @@ __asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (8191)); - if (unlikely(esp < (sizeof(struct task_struct) + 1024))) { + if (unlikely(esp < (sizeof(struct thread_info) + 1024))) { printk("do_IRQ: stack overflow: %ld\n", - esp - sizeof(struct task_struct)); + esp - sizeof(struct thread_info)); dump_stack(); } } diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c --- a/arch/i386/kernel/process.c Sun Feb 9 21:13:28 2003 +++ b/arch/i386/kernel/process.c Sun Feb 9 21:13:28 2003 @@ -86,7 +86,7 @@ */ void default_idle(void) { - if (current_cpu_data.hlt_works_ok && !hlt_counter) { + if (!hlt_counter && current_cpu_data.hlt_works_ok) { local_irq_disable(); if (!need_resched()) safe_halt(); diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c --- a/arch/i386/kernel/setup.c Sun Feb 9 21:13:32 2003 +++ b/arch/i386/kernel/setup.c Sun Feb 9 21:13:32 2003 @@ -474,7 +474,7 @@ #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) unsigned char eddnr; -struct edd_info edd[EDDNR]; +struct edd_info edd[EDDMAXNR]; /** * copy_edd() - Copy the BIOS EDD information * from empty_zero_page into a safe place. @@ -900,7 +900,7 @@ * Parse the ACPI tables for possible boot-time SMP configuration. */ if (!acpi_disabled) - acpi_boot_init(*cmdline_p); + acpi_boot_init(); #endif #ifdef CONFIG_X86_LOCAL_APIC if (smp_found_config) diff -Nru a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c --- a/arch/i386/kernel/signal.c Sun Feb 9 21:13:31 2003 +++ b/arch/i386/kernel/signal.c Sun Feb 9 21:13:31 2003 @@ -37,11 +37,11 @@ sigset_t saveset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->eax = -EINTR; while (1) { @@ -66,11 +66,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->eax = -EINTR; while (1) { @@ -224,10 +224,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(regs, &frame->sc, &eax)) goto badframe; @@ -252,10 +252,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax)) goto badframe; @@ -513,7 +513,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]; /* Are we from a system call? */ if (regs->orig_eax >= 0) { @@ -547,11 +547,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c --- a/arch/i386/kernel/time.c Sun Feb 9 21:13:32 2003 +++ b/arch/i386/kernel/time.c Sun Feb 9 21:13:32 2003 @@ -70,7 +70,6 @@ unsigned long cpu_khz; /* Detected as we calibrate the TSC */ -extern rwlock_t xtime_lock; extern unsigned long wall_jiffies; spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; @@ -87,19 +86,21 @@ */ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; + unsigned long seq; unsigned long usec, sec; - read_lock_irqsave(&xtime_lock, flags); - usec = timer->get_offset(); - { - unsigned long lost = jiffies - wall_jiffies; - if (lost) - usec += lost * (1000000 / HZ); - } - sec = xtime.tv_sec; - usec += (xtime.tv_nsec / 1000); - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin(&xtime_lock); + + usec = timer->get_offset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + } while (read_seqretry(&xtime_lock, seq)); while (usec >= 1000000) { usec -= 1000000; @@ -112,7 +113,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* * This is revolting. We need to set "xtime" correctly. However, the * value in this location is the value at the most recent update of @@ -133,7 +134,7 @@ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } /* @@ -266,6 +267,41 @@ } /* + * Lost tick detection and compensation + */ +static inline void detect_lost_tick(void) +{ + /* read time since last interrupt */ + unsigned long delta = timer->get_offset(); + static unsigned long dbg_print; + + /* check if delta is greater then two ticks */ + if(delta >= 2*(1000000/HZ)){ + + /* + * only print debug info first 5 times + */ + /* + * AKPM: disable this for now; it's nice, but irritating. + */ + if (0 && dbg_print < 5) { + printk(KERN_WARNING "\nWarning! Detected %lu " + "micro-second gap between interrupts.\n", + delta); + printk(KERN_WARNING " Compensating for %lu lost " + "ticks.\n", + delta/(1000000/HZ)-1); + dump_stack(); + dbg_print++; + } + /* calculate number of missed ticks */ + delta = delta/(1000000/HZ)-1; + jiffies += delta; + } + +} + +/* * This is the same as the above, except we _also_ save the current * Time Stamp Counter value at the time of the timer interrupt, so that * we later on can estimate the time of day more exactly. @@ -279,13 +315,14 @@ * the irq version of write_lock because as just said we have irq * locally disabled. -arca */ - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); + detect_lost_tick(); timer->mark_offset(); do_timer_interrupt(irq, NULL, regs); - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } diff -Nru a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c --- a/arch/i386/kernel/timers/timer_pit.c Sun Feb 9 21:13:35 2003 +++ b/arch/i386/kernel/timers/timer_pit.c Sun Feb 9 21:13:35 2003 @@ -76,7 +76,7 @@ static unsigned long get_offset_pit(void) { int count; - + unsigned long flags; static int count_p = LATCH; /* for the first call after boot */ static unsigned long jiffies_p = 0; @@ -85,8 +85,7 @@ */ unsigned long jiffies_t; - /* gets recalled with irq locally disabled */ - spin_lock(&i8253_lock); + spin_lock_irqsave(&i8253_lock, flags); /* timer count may underflow right here */ outb_p(0x00, 0x43); /* latch the count ASAP */ @@ -108,7 +107,7 @@ count = LATCH - 1; } - spin_unlock(&i8253_lock); + spin_unlock_irqrestore(&i8253_lock, flags); /* * avoiding timer inconsistencies (they are rare, but they happen)... diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c --- a/arch/i386/kernel/traps.c Sun Feb 9 21:13:29 2003 +++ b/arch/i386/kernel/traps.c Sun Feb 9 21:13:29 2003 @@ -514,6 +514,10 @@ __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); + /* It's safe to allow irq's after DR6 has been saved */ + if (regs->eflags & X86_EFLAGS_IF) + local_irq_enable(); + /* Mask out spurious debug traps due to lazy DR7 setting */ if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { if (!tsk->thread.debugreg[7]) @@ -831,7 +835,7 @@ #endif set_trap_gate(0,÷_error); - set_trap_gate(1,&debug); + set_intr_gate(1,&debug); set_intr_gate(2,&nmi); set_system_gate(3,&int3); /* int3-5 can be called from all */ set_system_gate(4,&overflow); diff -Nru a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c --- a/arch/i386/kernel/vm86.c Sun Feb 9 21:13:29 2003 +++ b/arch/i386/kernel/vm86.c Sun Feb 9 21:13:29 2003 @@ -512,10 +512,10 @@ return 1; /* we let this handle by the calling routine */ if (current->ptrace & PT_PTRACED) { unsigned long flags; - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); sigdelset(¤t->blocked, SIGTRAP); recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); } send_sig(SIGTRAP, current, 1); current->thread.trap_no = trapno; diff -Nru a/arch/i386/mach-voyager/Makefile b/arch/i386/mach-voyager/Makefile --- a/arch/i386/mach-voyager/Makefile Sun Feb 9 21:13:29 2003 +++ b/arch/i386/mach-voyager/Makefile Sun Feb 9 21:13:29 2003 @@ -8,8 +8,6 @@ # Note 2! The CFLAGS definitions are now in the main makefile... EXTRA_CFLAGS += -I../kernel -export-objs := - obj-y := setup.o voyager_basic.o voyager_thread.o obj-$(CONFIG_SMP) += voyager_smp.o voyager_cat.o diff -Nru a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile --- a/arch/i386/mm/Makefile Sun Feb 9 21:13:30 2003 +++ b/arch/i386/mm/Makefile Sun Feb 9 21:13:30 2003 @@ -2,8 +2,6 @@ # Makefile for the linux i386-specific parts of the memory manager. # -export-objs := pageattr.o - obj-y := init.o pgtable.o fault.o ioremap.o extable.o pageattr.o obj-$(CONFIG_DISCONTIGMEM) += discontig.o diff -Nru a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c --- a/arch/i386/mm/hugetlbpage.c Sun Feb 9 21:13:36 2003 +++ b/arch/i386/mm/hugetlbpage.c Sun Feb 9 21:13:36 2003 @@ -26,7 +26,6 @@ int htlbpage_max; static long htlbzone_pages; -struct vm_operations_struct hugetlb_vm_ops; static LIST_HEAD(htlbpage_freelist); static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED; @@ -46,6 +45,7 @@ htlbpagemem--; spin_unlock(&htlbpage_lock); set_page_count(page, 1); + page->lru.prev = (void *)huge_page_release; for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i) clear_highpage(&page[i]); return page; @@ -134,6 +134,7 @@ page = pte_page(pte); if (pages) { page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT); + get_page(page); pages[i] = page; } if (vmas) @@ -150,6 +151,82 @@ return i; } +#if 0 /* This is just for testing */ +struct page * +follow_huge_addr(struct mm_struct *mm, + struct vm_area_struct *vma, unsigned long address, int write) +{ + unsigned long start = address; + int length = 1; + int nr; + struct page *page; + + nr = follow_hugetlb_page(mm, vma, &page, NULL, &start, &length, 0); + if (nr == 1) + return page; + return NULL; +} + +/* + * If virtual address `addr' lies within a huge page, return its controlling + * VMA, else NULL. + */ +struct vm_area_struct *hugepage_vma(struct mm_struct *mm, unsigned long addr) +{ + if (mm->used_hugetlb) { + struct vm_area_struct *vma = find_vma(mm, addr); + if (vma && is_vm_hugetlb_page(vma)) + return vma; + } + return NULL; +} + +int pmd_huge(pmd_t pmd) +{ + return 0; +} + +struct page * +follow_huge_pmd(struct mm_struct *mm, unsigned long address, + pmd_t *pmd, int write) +{ + return NULL; +} + +#else + +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; +} +#endif + void free_huge_page(struct page *page) { BUG_ON(page_count(page)); @@ -171,7 +248,8 @@ free_huge_page(page); } -void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) +void unmap_hugepage_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) { struct mm_struct *mm = vma->vm_mm; unsigned long address; @@ -181,8 +259,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); if (pte_none(*pte)) @@ -195,7 +271,9 @@ flush_tlb_range(vma, start, end); } -void zap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long length) +void +zap_hugepage_range(struct vm_area_struct *vma, + unsigned long start, unsigned long length) { struct mm_struct *mm = vma->vm_mm; spin_lock(&mm->page_table_lock); @@ -206,6 +284,7 @@ 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; @@ -229,6 +308,7 @@ + (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; @@ -240,6 +320,9 @@ 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); } @@ -283,8 +366,8 @@ break; } page = list_entry(p, struct page, list); - if ((page_zone(page))->name[0] != 'H') // Look for non-Highmem - map = page; + if (!PageHighMem(page)) + map = page; } if (map) { list_del(&map->list); @@ -298,8 +381,8 @@ int set_hugetlb_mem_size(int count) { - int j, lcount; - struct page *page, *map; + int lcount; + struct page *page; extern long htlbzone_pages; extern struct list_head htlbpage_freelist; @@ -315,11 +398,6 @@ page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER); if (page == NULL) break; - map = page; - for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) { - SetPageReserved(map); - map++; - } spin_lock(&htlbpage_lock); list_add(&page->list, &htlbpage_freelist); htlbpagemem++; @@ -341,7 +419,8 @@ return (int) htlbzone_pages; } -int hugetlb_sysctl_handler(ctl_table *table, int write, struct file *file, void *buffer, size_t *length) +int hugetlb_sysctl_handler(ctl_table *table, int write, + struct file *file, void *buffer, size_t *length) { proc_dointvec(table, write, file, buffer, length); htlbpage_max = set_hugetlb_mem_size(htlbpage_max); @@ -358,15 +437,13 @@ static int __init hugetlb_init(void) { - int i, j; + int i; struct page *page; for (i = 0; i < htlbpage_max; ++i) { page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER); if (!page) break; - for (j = 0; j < HPAGE_SIZE/PAGE_SIZE; ++j) - SetPageReserved(&page[j]); spin_lock(&htlbpage_lock); list_add(&page->list, &htlbpage_freelist); spin_unlock(&htlbpage_lock); @@ -395,7 +472,14 @@ return 1; } -static struct page *hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int unused) +/* + * We cannot handle pagefaults against hugetlb pages at all. They cause + * handle_mm_fault() to try to instantiate regular-sized pages in the + * hugegpage VMA. do_page_fault() is supposed to trap this, so BUG is we get + * this far. + */ +static struct page *hugetlb_nopage(struct vm_area_struct *vma, + unsigned long address, int unused) { BUG(); return NULL; diff -Nru a/arch/i386/mm/init.c b/arch/i386/mm/init.c --- a/arch/i386/mm/init.c Sun Feb 9 21:13:34 2003 +++ b/arch/i386/mm/init.c Sun Feb 9 21:13:34 2003 @@ -508,20 +508,36 @@ #endif } -#if CONFIG_X86_PAE -struct kmem_cache_s *pae_pgd_cachep; +#include + +kmem_cache_t *pmd_cache; +kmem_cache_t *pgd_cache; + +void pmd_ctor(void *, kmem_cache_t *, unsigned long); +void pgd_ctor(void *, kmem_cache_t *, unsigned long); void __init pgtable_cache_init(void) { + if (PTRS_PER_PMD > 1) { + pmd_cache = kmem_cache_create("pae_pmd", + PTRS_PER_PMD*sizeof(pmd_t), + 0, + SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, + pmd_ctor, + NULL); + + if (!pmd_cache) + panic("pgtable_cache_init(): cannot create pmd cache"); + } + /* * PAE pgds must be 16-byte aligned: */ - pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0, - SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL); - if (!pae_pgd_cachep) - panic("init_pae(): Cannot alloc pae_pgd SLAB cache"); + pgd_cache = kmem_cache_create("pgd", PTRS_PER_PGD*sizeof(pgd_t), 0, + SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, pgd_ctor, NULL); + if (!pgd_cache) + panic("pgtable_cache_init(): Cannot create pgd cache"); } -#endif /* Put this after the callers, so that it cannot be inlined */ static int do_test_wp_bit(void) diff -Nru a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c --- a/arch/i386/mm/pgtable.c Sun Feb 9 21:13:37 2003 +++ b/arch/i386/mm/pgtable.c Sun Feb 9 21:13:37 2003 @@ -166,61 +166,60 @@ return pte; } -#if CONFIG_X86_PAE +extern kmem_cache_t *pmd_cache; +extern kmem_cache_t *pgd_cache; -pgd_t *pgd_alloc(struct mm_struct *mm) +void pmd_ctor(void *__pmd, kmem_cache_t *pmd_cache, unsigned long flags) { - int i; - pgd_t *pgd = kmem_cache_alloc(pae_pgd_cachep, GFP_KERNEL); - - if (pgd) { - for (i = 0; i < USER_PTRS_PER_PGD; i++) { - unsigned long pmd = __get_free_page(GFP_KERNEL); - if (!pmd) - goto out_oom; - clear_page(pmd); - set_pgd(pgd + i, __pgd(1 + __pa(pmd))); - } - memcpy(pgd + USER_PTRS_PER_PGD, - swapper_pg_dir + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); - } - return pgd; -out_oom: - for (i--; i >= 0; i--) - free_page((unsigned long)__va(pgd_val(pgd[i])-1)); - kmem_cache_free(pae_pgd_cachep, pgd); - return NULL; + clear_page(__pmd); } -void pgd_free(pgd_t *pgd) +void pgd_ctor(void *__pgd, kmem_cache_t *pgd_cache, unsigned long flags) { - int i; + pgd_t *pgd = __pgd; - for (i = 0; i < USER_PTRS_PER_PGD; i++) - free_page((unsigned long)__va(pgd_val(pgd[i])-1)); - kmem_cache_free(pae_pgd_cachep, pgd); + if (PTRS_PER_PMD == 1) + memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); + memcpy(pgd + USER_PTRS_PER_PGD, + swapper_pg_dir + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); } -#else - pgd_t *pgd_alloc(struct mm_struct *mm) { - pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL); + int i; + pgd_t *pgd = kmem_cache_alloc(pgd_cache, SLAB_KERNEL); - if (pgd) { - memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); - memcpy(pgd + USER_PTRS_PER_PGD, - swapper_pg_dir + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); + if (PTRS_PER_PMD == 1) + return pgd; + else if (!pgd) + return NULL; + + for (i = 0; i < USER_PTRS_PER_PGD; ++i) { + pmd_t *pmd = kmem_cache_alloc(pmd_cache, SLAB_KERNEL); + if (!pmd) + goto out_oom; + set_pgd(pgd + i, __pgd(1 + __pa((unsigned long long)((unsigned long)pmd)))); } return pgd; + +out_oom: + for (i--; i >= 0; --i) + kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); + kmem_cache_free(pgd_cache, (void *)pgd); + return NULL; } void pgd_free(pgd_t *pgd) { - free_page((unsigned long)pgd); -} + int i; -#endif /* CONFIG_X86_PAE */ + if (PTRS_PER_PMD > 1) { + for (i = 0; i < USER_PTRS_PER_PGD; ++i) { + kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); + set_pgd(pgd + i, __pgd(0)); + } + } + kmem_cache_free(pgd_cache, (void *)pgd); +} diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Sun Feb 9 21:13:36 2003 +++ b/arch/ia64/Kconfig Sun Feb 9 21:13:36 2003 @@ -502,7 +502,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. if !IA64_HP_SIM @@ -611,7 +611,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -640,7 +640,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -767,6 +767,9 @@ menu "Kernel hacking" + +config FSYS + bool "Light-weight system-call support (via epc)" choice prompt "Physical memory granularity" diff -Nru a/arch/ia64/Makefile b/arch/ia64/Makefile --- a/arch/ia64/Makefile Sun Feb 9 21:13:28 2003 +++ b/arch/ia64/Makefile Sun Feb 9 21:13:28 2003 @@ -5,7 +5,7 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 1998-2002 by David Mosberger-Tang +# Copyright (C) 1998-2003 by David Mosberger-Tang # NM := $(CROSS_COMPILE)nm -B @@ -23,6 +23,16 @@ GCC_VERSION=$(shell $(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.') +GAS_STATUS=$(shell arch/ia64/scripts/check-gas $(CC)) + +ifeq ($(GAS_STATUS),buggy) +$(error Sorry, you need a newer version of the assember, one that is built from \ + a source-tree that post-dates 18-Dec-2002. You can find a pre-compiled \ + static binary of such an assembler at: \ + \ + ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz) +endif + ifneq ($(GCC_VERSION),2) cflags-y += -frename-registers --param max-inline-insns=5000 endif @@ -31,7 +41,7 @@ cflags-$(CONFIG_IA64_SGI_SN) += -DBRINGUP CFLAGS += $(cflags-y) -HEAD := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o +head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o libs-y += arch/ia64/lib/ core-y += arch/ia64/kernel/ arch/ia64/mm/ @@ -48,26 +58,36 @@ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ drivers-$(CONFIG_IA64_SGI_SN) += arch/ia64/sn/fakeprom/ -makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/ia64/boot $(1) -maketool =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/ia64/tools $(1) +boot := arch/ia64/boot +tools := arch/ia64/tools -.PHONY: boot compressed archclean archmrproper include/asm-ia64/offsets.h +.PHONY: boot compressed include/asm-ia64/offsets.h -all compressed: vmlinux.gz +all: vmlinux + +compressed: vmlinux.gz vmlinux.gz: vmlinux - $(call makeboot,vmlinux.gz) + $(Q)$(MAKE) $(build)=$(boot) vmlinux.gz + +check: vmlinux + arch/ia64/scripts/unwcheck.sh vmlinux -archmrproper: archclean: - $(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/ia64/boot + $(Q)$(MAKE) $(clean)=$(boot) + $(Q)$(MAKE) $(clean)=$(tools) CLEAN_FILES += include/asm-ia64/offsets.h vmlinux.gz bootloader prepare: include/asm-ia64/offsets.h boot: lib/lib.a vmlinux - $(call makeboot,$@) + $(Q)$(MAKE) $(build)=$(boot) $@ include/asm-ia64/offsets.h: include/asm include/linux/version.h include/config/MARKER - $(call maketool,$@) + $(Q)$(MAKE) $(build)=$(tools) $@ + +define archhelp + echo ' compressed - Build compressed kernel image' + echo ' boot - Build vmlinux and bootloader for Ski simulator' +endef diff -Nru a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c --- a/arch/ia64/dig/setup.c Sun Feb 9 21:13:30 2003 +++ b/arch/ia64/dig/setup.c Sun Feb 9 21:13:30 2003 @@ -3,7 +3,7 @@ * * Copyright (C) 1999 Intel Corp. * Copyright (C) 1999, 2001 Hewlett-Packard Co - * Copyright (C) 1999, 2001 David Mosberger-Tang + * Copyright (C) 1999, 2001, 2003 David Mosberger-Tang * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999 Walt Drummond * Copyright (C) 1999 Vijay Chander @@ -56,7 +56,7 @@ if (!ia64_boot_param->console_info.num_rows || !ia64_boot_param->console_info.num_cols) { - printk("dig_setup: warning: invalid screen-info, guessing 80x25\n"); + printk(KERN_WARNING "dig_setup: warning: invalid screen-info, guessing 80x25\n"); orig_x = 0; orig_y = 0; num_cols = 80; diff -Nru a/arch/ia64/hp/common/Makefile b/arch/ia64/hp/common/Makefile --- a/arch/ia64/hp/common/Makefile Sun Feb 9 21:13:35 2003 +++ b/arch/ia64/hp/common/Makefile Sun Feb 9 21:13:35 2003 @@ -5,6 +5,4 @@ # Copyright (C) Alex Williamson (alex_williamson@hp.com) # -export-objs := sba_iommu.o - obj-y := sba_iommu.o diff -Nru a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c --- a/arch/ia64/hp/common/sba_iommu.c Sun Feb 9 21:13:29 2003 +++ b/arch/ia64/hp/common/sba_iommu.c Sun Feb 9 21:13:29 2003 @@ -288,20 +288,19 @@ unsigned long *rptr = (unsigned long *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsigned long) - 1)]); uint rcnt; - /* printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n", */ - printk("SBA: %s rp %p bit %d rval 0x%lx\n", + printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n", msg, rptr, pide & (BITS_PER_LONG - 1), *rptr); rcnt = 0; while (rcnt < BITS_PER_LONG) { - printk("%s %2d %p %016Lx\n", - (rcnt == (pide & (BITS_PER_LONG - 1))) - ? " -->" : " ", - rcnt, ptr, *ptr ); + printk(KERN_DEBUG "%s %2d %p %016Lx\n", + (rcnt == (pide & (BITS_PER_LONG - 1))) + ? " -->" : " ", + rcnt, ptr, *ptr ); rcnt++; ptr++; } - printk("%s", msg); + printk(KERN_DEBUG "%s", msg); } @@ -363,11 +362,9 @@ sba_dump_sg(struct ioc *ioc, struct scatterlist *startsg, int nents) { while (nents-- > 0) { - printk(" %d : DMA %08lx/%05x CPU %p\n", - nents, - (unsigned long) sba_sg_iova(startsg), - sba_sg_iova_len(startsg), - sba_sg_address(startsg)); + printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents, + (unsigned long) sba_sg_iova(startsg), sba_sg_iova_len(startsg), + sba_sg_address(startsg)); startsg++; } } @@ -1451,9 +1448,10 @@ sba_dev->ioc[i].res_map; } else { u64 reserved_iov; - + /* Yet another 1.x hack */ - printk("zx1 1.x: Starting resource hint offset into IOV space to avoid initial zero value IOVA\n"); + printk(KERN_DEBUG "zx1 1.x: Starting resource hint offset into " + "IOV space to avoid initial zero value IOVA\n"); sba_dev->ioc[i].res_hint = (unsigned long *) &(sba_dev->ioc[i].res_map[L1_CACHE_BYTES]); @@ -1632,7 +1630,7 @@ device->slot_name, hpa); if ((hw_rev & 0xFF) < 0x20) { - printk("%s: SBA rev less than 2.0 not supported", DRIVER_NAME); + printk(KERN_INFO "%s: SBA rev less than 2.0 not supported", DRIVER_NAME); return; } diff -Nru a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c --- a/arch/ia64/hp/sim/simeth.c Sun Feb 9 21:13:33 2003 +++ b/arch/ia64/hp/sim/simeth.c Sun Feb 9 21:13:33 2003 @@ -1,7 +1,7 @@ /* * Simulated Ethernet Driver * - * Copyright (C) 1999-2001 Hewlett-Packard Co + * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co * Stephane Eranian */ #include @@ -116,7 +116,7 @@ { int r; - printk("simeth: v%s\n", simeth_version); + printk(KERN_INFO "simeth: v%s\n", simeth_version); r = simeth_probe1(); @@ -235,7 +235,8 @@ /* Fill in the fields of the device structure with ethernet-generic values. */ ether_setup(dev); - printk("%s: hosteth=%s simfd=%d, HwAddr", dev->name, simeth_device, local->simfd); + printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr", + dev->name, simeth_device, local->simfd); for(i = 0; i < ETH_ALEN; i++) { printk(" %2.2x", dev->dev_addr[i]); } @@ -251,7 +252,7 @@ simeth_open(struct net_device *dev) { if (request_irq(dev->irq, simeth_interrupt, 0, "simeth", dev)) { - printk ("simeth: unable to get IRQ %d.\n", dev->irq); + printk(KERN_WARNING "simeth: unable to get IRQ %d.\n", dev->irq); return -EAGAIN; } @@ -312,11 +313,12 @@ if (strcmp(dev->name, ifa->ifa_label) == 0) break; } if ( ifa == NULL ) { - printk("simeth_open: can't find device %s's ifa\n", dev->name); + printk(KERN_ERR "simeth_open: can't find device %s's ifa\n", dev->name); return NOTIFY_DONE; } - printk("simeth_device_event: %s ipaddr=0x%x\n", dev->name, htonl(ifa->ifa_local)); + printk(KERN_INFO "simeth_device_event: %s ipaddr=0x%x\n", + dev->name, htonl(ifa->ifa_local)); /* * XXX Fix me @@ -330,7 +332,8 @@ netdev_attach(local->simfd, dev->irq, htonl(ifa->ifa_local)): netdev_detach(local->simfd); - printk("simeth: netdev_attach/detach: event=%s ->%d\n", event == NETDEV_UP ? "attach":"detach", r); + printk(KERN_INFO "simeth: netdev_attach/detach: event=%s ->%d\n", + event == NETDEV_UP ? "attach":"detach", r); return NOTIFY_DONE; } @@ -460,7 +463,8 @@ */ len = netdev_read(local->simfd, skb->data, SIMETH_FRAME_SIZE); if ( len == 0 ) { - if ( simeth_debug > 0 ) printk(KERN_WARNING "%s: count=%d netdev_read=0\n", dev->name, SIMETH_RECV_MAX-rcv_count); + if ( simeth_debug > 0 ) printk(KERN_WARNING "%s: count=%d netdev_read=0\n", + dev->name, SIMETH_RECV_MAX-rcv_count); break; } #if 0 diff -Nru a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c --- a/arch/ia64/hp/sim/simscsi.c Sun Feb 9 21:13:31 2003 +++ b/arch/ia64/hp/sim/simscsi.c Sun Feb 9 21:13:31 2003 @@ -1,7 +1,7 @@ /* * Simulated SCSI driver. * - * Copyright (C) 1999, 2001-2002 Hewlett-Packard Co + * Copyright (C) 1999, 2001-2003 Hewlett-Packard Co * David Mosberger-Tang * Stephane Eranian * @@ -87,7 +87,8 @@ { /* XXX Fix me we may need to strcpy() ? */ if (strlen(s) > MAX_ROOT_LEN) { - printk("simscsi_setup: prefix too long---using default %s\n", simscsi_root); + printk(KERN_ERR "simscsi_setup: prefix too long---using default %s\n", + simscsi_root); } simscsi_root = s; return 1; @@ -354,7 +355,7 @@ break; case START_STOP: - printk("START_STOP\n"); + printk(KERN_ERR "START_STOP\n"); break; default: @@ -380,7 +381,7 @@ int simscsi_host_reset (Scsi_Cmnd *sc) { - printk ("simscsi_host_reset: not implemented\n"); + printk(KERN_ERR "simscsi_host_reset: not implemented\n"); return 0; } diff -Nru a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c --- a/arch/ia64/hp/sim/simserial.c Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/hp/sim/simserial.c Sun Feb 9 21:13:32 2003 @@ -7,7 +7,7 @@ * case means sys_sim.c console (goes via the simulator). The code hereafter * is completely leveraged from the serial.c driver. * - * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co + * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co * Stephane Eranian * David Mosberger-Tang * @@ -195,7 +195,7 @@ */ info = IRQ_ports[irq]; if (!info || !info->tty) { - printk("simrs_interrupt_single: info|tty=0 info=%p problem\n", info); + printk(KERN_INFO "simrs_interrupt_single: info|tty=0 info=%p problem\n", info); return; } /* @@ -219,13 +219,13 @@ static void do_serial_bh(void) { run_task_queue(&tq_serial); - printk("do_serial_bh: called\n"); + printk(KERN_ERR "do_serial_bh: called\n"); } #endif static void do_softint(void *private_) { - printk("simserial: do_softint called\n"); + printk(KERN_ERR "simserial: do_softint called\n"); } static void rs_put_char(struct tty_struct *tty, unsigned char ch) @@ -439,7 +439,7 @@ { if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty)); - printk("simrs_throttle called\n"); + printk(KERN_INFO "simrs_throttle called\n"); } static void rs_unthrottle(struct tty_struct * tty) @@ -452,7 +452,7 @@ else rs_send_xchar(tty, START_CHAR(tty)); } - printk("simrs_unthrottle called\n"); + printk(KERN_INFO "simrs_unthrottle called\n"); } /* @@ -474,29 +474,29 @@ switch (cmd) { case TIOCMGET: - printk("rs_ioctl: TIOCMGET called\n"); + printk(KERN_INFO "rs_ioctl: TIOCMGET called\n"); return -EINVAL; case TIOCMBIS: case TIOCMBIC: case TIOCMSET: - printk("rs_ioctl: TIOCMBIS/BIC/SET called\n"); + printk(KERN_INFO "rs_ioctl: TIOCMBIS/BIC/SET called\n"); return -EINVAL; case TIOCGSERIAL: - printk("simrs_ioctl TIOCGSERIAL called\n"); + printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n"); return 0; case TIOCSSERIAL: - printk("simrs_ioctl TIOCSSERIAL called\n"); + printk(KERN_INFO "simrs_ioctl TIOCSSERIAL called\n"); return 0; case TIOCSERCONFIG: - printk("rs_ioctl: TIOCSERCONFIG called\n"); + printk(KERN_INFO "rs_ioctl: TIOCSERCONFIG called\n"); return -EINVAL; case TIOCSERGETLSR: /* Get line status register */ - printk("rs_ioctl: TIOCSERGETLSR called\n"); + printk(KERN_INFO "rs_ioctl: TIOCSERGETLSR called\n"); return -EINVAL; case TIOCSERGSTRUCT: - printk("rs_ioctl: TIOCSERGSTRUCT called\n"); + printk(KERN_INFO "rs_ioctl: TIOCSERGSTRUCT called\n"); #if 0 if (copy_to_user((struct async_struct *) arg, info, sizeof(struct async_struct))) @@ -511,7 +511,7 @@ * Caller should use TIOCGICOUNT to see which one it was */ case TIOCMIWAIT: - printk("rs_ioctl: TIOCMIWAIT: called\n"); + printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n"); return 0; /* * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) @@ -520,13 +520,13 @@ * RI where only 0->1 is counted. */ case TIOCGICOUNT: - printk("rs_ioctl: TIOCGICOUNT called\n"); + printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n"); return 0; case TIOCSERGWILD: case TIOCSERSWILD: /* "setserial -W" is called in Debian boot */ - printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); + printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n"); return 0; default: @@ -596,7 +596,7 @@ IRQ_T(info), "serial", NULL); if (retval) - printk("serial shutdown: request_irq: error %d" + printk(KERN_ERR "serial shutdown: request_irq: error %d" " Couldn't reacquire IRQ.\n", retval); } else free_irq(state->irq, NULL); @@ -654,12 +654,12 @@ * one, we've got real problems, since it means the * serial port won't be shutdown. */ - printk("rs_close: bad serial port count; tty->count is 1, " + printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, " "state->count is %d\n", state->count); state->count = 1; } if (--state->count < 0) { - printk("rs_close: bad serial port count for ttys%d: %d\n", + printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n", info->line, state->count); state->count = 0; } @@ -1013,7 +1013,7 @@ static inline void show_serial_version(void) { printk(KERN_INFO "%s version %s with", serial_name, serial_version); - printk(" no serial options enabled\n"); + printk(KERN_INFO " no serial options enabled\n"); } /* diff -Nru a/arch/ia64/hp/zx1/hpzx1_misc.c b/arch/ia64/hp/zx1/hpzx1_misc.c --- a/arch/ia64/hp/zx1/hpzx1_misc.c Sun Feb 9 21:13:31 2003 +++ b/arch/ia64/hp/zx1/hpzx1_misc.c Sun Feb 9 21:13:31 2003 @@ -1,9 +1,9 @@ /* * Misc. support for HP zx1 chipset support * - * Copyright (C) 2002 Hewlett-Packard Co - * Copyright (C) 2002 Alex Williamson - * Copyright (C) 2002 Bjorn Helgaas + * Copyright (C) 2002-2003 Hewlett-Packard Co + * Alex Williamson + * Bjorn Helgaas */ @@ -17,7 +17,7 @@ #include #include -extern acpi_status acpi_evaluate_integer (acpi_handle, acpi_string, acpi_object_list *, +extern acpi_status acpi_evaluate_integer (acpi_handle, acpi_string, struct acpi_object_list *, unsigned long *); #define PFX "hpzx1: " @@ -190,31 +190,31 @@ hpzx1_devices++; } -typedef struct { +struct acpi_hp_vendor_long { u8 guid_id; u8 guid[16]; u8 csr_base[8]; u8 csr_length[8]; -} acpi_hp_vendor_long; +}; #define HP_CCSR_LENGTH 0x21 #define HP_CCSR_TYPE 0x2 #define HP_CCSR_GUID EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, \ 0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad) -extern acpi_status acpi_get_crs(acpi_handle, acpi_buffer *); -extern acpi_resource *acpi_get_crs_next(acpi_buffer *, int *); -extern acpi_resource_data *acpi_get_crs_type(acpi_buffer *, int *, int); -extern void acpi_dispose_crs(acpi_buffer *); +extern acpi_status acpi_get_crs(acpi_handle, struct acpi_buffer *); +extern struct acpi_resource *acpi_get_crs_next(struct acpi_buffer *, int *); +extern union acpi_resource_data *acpi_get_crs_type(struct acpi_buffer *, int *, int); +extern void acpi_dispose_crs(struct acpi_buffer *); static acpi_status hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length) { int i, offset = 0; acpi_status status; - acpi_buffer buf; - acpi_resource_vendor *res; - acpi_hp_vendor_long *hp_res; + struct acpi_buffer buf; + struct acpi_resource_vendor *res; + struct acpi_hp_vendor_long *hp_res; efi_guid_t vendor_guid; *csr_base = 0; @@ -226,14 +226,14 @@ return status; } - res = (acpi_resource_vendor *)acpi_get_crs_type(&buf, &offset, ACPI_RSTYPE_VENDOR); + res = (struct acpi_resource_vendor *)acpi_get_crs_type(&buf, &offset, ACPI_RSTYPE_VENDOR); if (!res) { printk(KERN_ERR PFX "Failed to find config space for device\n"); acpi_dispose_crs(&buf); return AE_NOT_FOUND; } - hp_res = (acpi_hp_vendor_long *)(res->reserved); + hp_res = (struct acpi_hp_vendor_long *)(res->reserved); if (res->length != HP_CCSR_LENGTH || hp_res->guid_id != HP_CCSR_TYPE) { printk(KERN_ERR PFX "Unknown Vendor data\n"); @@ -288,7 +288,7 @@ { u64 csr_base = 0, csr_length = 0; acpi_status status; - NATIVE_UINT busnum; + acpi_native_uint busnum; char *name = context; char fullname[32]; diff -Nru a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c --- a/arch/ia64/ia32/binfmt_elf32.c Sun Feb 9 21:13:36 2003 +++ b/arch/ia64/ia32/binfmt_elf32.c Sun Feb 9 21:13:36 2003 @@ -44,7 +44,6 @@ static void elf32_set_personality (void); -#define ELF_PLAT_INIT(_r) ia64_elf32_init(_r) #define setup_arg_pages(bprm) ia32_setup_arg_pages(bprm) #define elf_map elf32_map diff -Nru a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S --- a/arch/ia64/ia32/ia32_entry.S Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/ia32/ia32_entry.S Sun Feb 9 21:13:32 2003 @@ -95,12 +95,19 @@ GLOBAL_ENTRY(ia32_ret_from_clone) PT_REGS_UNWIND_INFO(0) #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) +{ /* + * Some versions of gas generate bad unwind info if the first instruction of a + * procedure doesn't go into the first slot of a bundle. This is a workaround. + */ + nop.m 0 + nop.i 0 /* * We need to call schedule_tail() to complete the scheduling process. * Called by ia64_switch_to after do_fork()->copy_thread(). r8 contains the * address of the previously executing task. */ br.call.sptk.many rp=ia64_invoke_schedule_tail +} .ret1: #endif adds r2=TI_FLAGS+IA64_TASK_SIZE,r13 @@ -264,7 +271,7 @@ data8 sys_setreuid /* 16-bit version */ /* 70 */ data8 sys_setregid /* 16-bit version */ data8 sys32_sigsuspend - data8 sys32_sigpending + data8 compat_sys_sigpending data8 sys_sethostname data8 sys32_setrlimit /* 75 */ data8 sys32_old_getrlimit @@ -290,8 +297,8 @@ data8 sys_getpriority data8 sys_setpriority data8 sys32_ni_syscall /* old profil syscall holder */ - data8 sys32_statfs - data8 sys32_fstatfs /* 100 */ + data8 compat_sys_statfs + data8 compat_sys_fstatfs /* 100 */ data8 sys32_ioperm data8 sys32_socketcall data8 sys_syslog @@ -317,7 +324,7 @@ data8 sys32_modify_ldt data8 sys32_ni_syscall /* adjtimex */ data8 sys32_mprotect /* 125 */ - data8 sys32_sigprocmask + data8 compat_sys_sigprocmask data8 sys32_ni_syscall /* create_module */ data8 sys32_ni_syscall /* init_module */ data8 sys32_ni_syscall /* delete_module */ diff -Nru a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c --- a/arch/ia64/ia32/ia32_ioctl.c Sun Feb 9 21:13:34 2003 +++ b/arch/ia64/ia32/ia32_ioctl.c Sun Feb 9 21:13:34 2003 @@ -510,6 +510,6 @@ return(sg_ioctl_trans(fd, cmd, arg)); } - printk("%x:unimplemented IA32 ioctl system call\n", cmd); + printk(KERN_ERR "%x:unimplemented IA32 ioctl system call\n", cmd); return -EINVAL; } diff -Nru a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c --- a/arch/ia64/ia32/ia32_signal.c Sun Feb 9 21:13:28 2003 +++ b/arch/ia64/ia32/ia32_signal.c Sun Feb 9 21:13:28 2003 @@ -56,7 +56,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]; }; @@ -463,7 +463,7 @@ } asmlinkage long -ia32_rt_sigsuspend (sigset32_t *uset, unsigned int sigsetsize, struct sigscratch *scr) +ia32_rt_sigsuspend (compat_sigset_t *uset, unsigned int sigsetsize, struct sigscratch *scr) { extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall); sigset_t oldset, set; @@ -479,13 +479,13 @@ sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); { oldset = current->blocked; current->blocked = set; recalc_sigpending(); } - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); /* * The return below usually returns to the signal handler. We need to pre-set the @@ -504,7 +504,7 @@ asmlinkage long ia32_sigsuspend (unsigned int mask, struct sigscratch *scr) { - return ia32_rt_sigsuspend((sigset32_t *)&mask, sizeof(mask), scr); + return ia32_rt_sigsuspend((compat_sigset_t *)&mask, sizeof(mask), scr); } asmlinkage long @@ -530,14 +530,14 @@ int ret; /* 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) { ret = get_user(handler, &act->sa_handler); ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags); ret |= get_user(restorer, &act->sa_restorer); - ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(sigset32_t)); + ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(compat_sigset_t)); if (ret) return -EFAULT; @@ -550,7 +550,7 @@ ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler); ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags); ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer); - ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(sigset32_t)); + ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(compat_sigset_t)); } return ret; } @@ -560,7 +560,7 @@ size_t sigsetsize); asmlinkage long -sys32_rt_sigprocmask (int how, sigset32_t *set, sigset32_t *oset, unsigned int sigsetsize) +sys32_rt_sigprocmask (int how, compat_sigset_t *set, compat_sigset_t *oset, unsigned int sigsetsize) { mm_segment_t old_fs = get_fs(); sigset_t s; @@ -587,13 +587,7 @@ } asmlinkage long -sys32_sigprocmask (int how, unsigned int *set, unsigned int *oset) -{ - return sys32_rt_sigprocmask(how, (sigset32_t *) set, (sigset32_t *) oset, sizeof(*set)); -} - -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, unsigned int sigsetsize) { extern asmlinkage long sys_rt_sigtimedwait (const sigset_t *, siginfo_t *, @@ -605,16 +599,13 @@ sigset_t s; int ret; - if (copy_from_user(&s.sig, uthese, sizeof(sigset32_t))) + if (copy_from_user(&s.sig, uthese, sizeof(compat_sigset_t))) + return -EFAULT; + if (uts && get_compat_timespec(&t, uts)) return -EFAULT; - if (uts) { - ret = get_user(t.tv_sec, &uts->tv_sec); - ret |= get_user(t.tv_nsec, &uts->tv_nsec); - if (ret) - 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_siginfo_to_user32(uinfo, &info)) @@ -648,7 +639,7 @@ int ret; if (act) { - old_sigset32_t mask; + compat_old_sigset_t mask; ret = get_user(handler, &act->sa_handler); ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags); @@ -866,7 +857,7 @@ err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]); - if (_IA32_NSIG_WORDS > 1) + if (_COMPAT_NSIG_WORDS > 1) err |= __copy_to_user(frame->extramask, (char *) &set->sig + 4, sizeof(frame->extramask)); @@ -1011,15 +1002,15 @@ goto badframe; if (__get_user(set.sig[0], &frame->sc.oldmask) - || (_IA32_NSIG_WORDS > 1 && __copy_from_user((char *) &set.sig + 4, &frame->extramask, + || (_COMPAT_NSIG_WORDS > 1 && __copy_from_user((char *) &set.sig + 4, &frame->extramask, sizeof(frame->extramask)))) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = (sigset_t) set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext_ia32(regs, &frame->sc, &eax)) goto badframe; @@ -1047,10 +1038,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext_ia32(regs, &frame->uc.uc_mcontext, &eax)) goto badframe; diff -Nru a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c --- a/arch/ia64/ia32/ia32_support.c Sun Feb 9 21:13:28 2003 +++ b/arch/ia64/ia32/ia32_support.c Sun Feb 9 21:13:28 2003 @@ -95,8 +95,6 @@ struct pt_regs *regs = ia64_task_regs(t); int nr = smp_processor_id(); /* LDT and TSS depend on CPU number: */ - nr = smp_processor_id(); - eflag = t->thread.eflag; fsr = t->thread.fsr; fcr = t->thread.fcr; diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c --- a/arch/ia64/ia32/sys_ia32.c Sun Feb 9 21:13:33 2003 +++ b/arch/ia64/ia32/sys_ia32.c Sun Feb 9 21:13:33 2003 @@ -6,7 +6,7 @@ * Copyright (C) 1999 Arun Sharma * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) - * Copyright (C) 2000-2002 Hewlett-Packard Co + * Copyright (C) 2000-2003 Hewlett-Packard Co * David Mosberger-Tang * * These routines maintain argument size conversion between 32bit and 64bit @@ -609,61 +609,6 @@ return retval; } -static inline int -put_statfs (struct statfs32 *ubuf, struct statfs *kbuf) -{ - int err; - - if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf))) - return -EFAULT; - - err = __put_user(kbuf->f_type, &ubuf->f_type); - err |= __put_user(kbuf->f_bsize, &ubuf->f_bsize); - err |= __put_user(kbuf->f_blocks, &ubuf->f_blocks); - err |= __put_user(kbuf->f_bfree, &ubuf->f_bfree); - err |= __put_user(kbuf->f_bavail, &ubuf->f_bavail); - err |= __put_user(kbuf->f_files, &ubuf->f_files); - err |= __put_user(kbuf->f_ffree, &ubuf->f_ffree); - err |= __put_user(kbuf->f_namelen, &ubuf->f_namelen); - err |= __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]); - err |= __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]); - return err; -} - -extern asmlinkage long sys_statfs(const char * path, struct statfs * buf); - -asmlinkage long -sys32_statfs (const char *path, struct statfs32 *buf) -{ - int ret; - struct statfs s; - mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); - ret = sys_statfs(path, &s); - set_fs(old_fs); - if (put_statfs(buf, &s)) - return -EFAULT; - return ret; -} - -extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf); - -asmlinkage long -sys32_fstatfs (unsigned int fd, struct statfs32 *buf) -{ - int ret; - struct statfs s; - mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); - ret = sys_fstatfs(fd, &s); - set_fs(old_fs); - if (put_statfs(buf, &s)) - return -EFAULT; - return ret; -} - static inline long get_tv32 (struct timeval *o, struct compat_timeval *i) { @@ -1849,10 +1794,10 @@ struct ipc64_perm32 { key_t key; - __kernel_uid32_t32 uid; - __kernel_gid32_t32 gid; - __kernel_uid32_t32 cuid; - __kernel_gid32_t32 cgid; + compat_uid32_t uid; + compat_gid32_t gid; + compat_uid32_t cuid; + compat_gid32_t cgid; compat_mode_t mode; unsigned short __pad1; unsigned short seq; @@ -1895,8 +1840,8 @@ unsigned short msg_cbytes; unsigned short msg_qnum; unsigned short msg_qbytes; - __kernel_ipc_pid_t32 msg_lspid; - __kernel_ipc_pid_t32 msg_lrpid; + compat_ipc_pid_t msg_lspid; + compat_ipc_pid_t msg_lrpid; }; struct msqid64_ds32 { @@ -1922,8 +1867,8 @@ compat_time_t shm_atime; compat_time_t shm_dtime; compat_time_t shm_ctime; - __kernel_ipc_pid_t32 shm_cpid; - __kernel_ipc_pid_t32 shm_lpid; + compat_ipc_pid_t shm_cpid; + compat_ipc_pid_t shm_lpid; unsigned short shm_nattch; }; @@ -2011,6 +1956,10 @@ else fourth.__pad = (void *)A(pad); switch (third) { + default: + err = -EINVAL; + break; + case IPC_INFO: case IPC_RMID: case IPC_SET: @@ -2399,7 +2348,7 @@ static long semtimedop32(int semid, struct sembuf *tsems, int nsems, - const struct timespec32 *timeout32) + const struct compat_timespec *timeout32) { struct timespec t; if (get_user (t.tv_sec, &timeout32->tv_sec) || @@ -2422,7 +2371,7 @@ return sys_semtimedop(first, (struct sembuf *)AA(ptr), second, NULL); case SEMTIMEDOP: return semtimedop32(first, (struct sembuf *)AA(ptr), second, - (const struct timespec32 *)AA(fifth)); + (const struct compat_timespec *)AA(fifth)); case SEMGET: return sys_semget(first, second, third); case SEMCTL: @@ -3475,12 +3424,6 @@ return ret; } -asmlinkage long -sys32_sigpending (unsigned int *set) -{ - return do_sigpending(set, sizeof(*set)); -} - struct sysinfo32 { s32 uptime; u32 loads[3]; @@ -3536,7 +3479,7 @@ set_fs(KERNEL_DS); ret = sys_sched_rr_get_interval(pid, &t); set_fs(old_fs); - if (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; } diff -Nru a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile --- a/arch/ia64/kernel/Makefile Sun Feb 9 21:13:37 2003 +++ b/arch/ia64/kernel/Makefile Sun Feb 9 21:13:37 2003 @@ -4,14 +4,13 @@ EXTRA_TARGETS := head.o init_task.o -export-objs := ia64_ksyms.o - obj-y := acpi.o entry.o gate.o efi.o efi_stub.o ia64_ksyms.o \ irq.o irq_ia64.o irq_lsapic.o ivt.o \ machvec.o pal.o process.o perfmon.o ptrace.o sal.o \ semaphore.o setup.o \ signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o +obj-$(CONFIG_FSYS) += fsys.o obj-$(CONFIG_IOSAPIC) += iosapic.o obj-$(CONFIG_IA64_PALINFO) += palinfo.o obj-$(CONFIG_EFI_VARS) += efivars.o diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c --- a/arch/ia64/kernel/acpi.c Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/kernel/acpi.c Sun Feb 9 21:13:32 2003 @@ -3,7 +3,7 @@ * * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999,2000 Walt Drummond - * Copyright (C) 2000, 2002 Hewlett-Packard Co. + * Copyright (C) 2000, 2002-2003 Hewlett-Packard Co. * David Mosberger-Tang * Copyright (C) 2000 Intel Corp. * Copyright (C) 2000,2001 J.I. Lee @@ -75,20 +75,20 @@ rsdp_phys = acpi_find_rsdp(); if (!rsdp_phys) { - printk("ACPI 2.0 RSDP not found, default to \"dig\"\n"); + printk(KERN_ERR "ACPI 2.0 RSDP not found, default to \"dig\"\n"); return "dig"; } rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys); if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) { - printk("ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n"); + printk(KERN_ERR "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n"); return "dig"; } xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address); hdr = &xsdt->header; if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) { - printk("ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n"); + printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n"); return "dig"; } @@ -128,7 +128,7 @@ * with a list of acpi_resource structures. */ acpi_status -acpi_get_crs (acpi_handle obj, acpi_buffer *buf) +acpi_get_crs (acpi_handle obj, struct acpi_buffer *buf) { acpi_status result; buf->length = 0; @@ -144,10 +144,10 @@ return acpi_get_current_resources(obj, buf); } -acpi_resource * -acpi_get_crs_next (acpi_buffer *buf, int *offset) +struct acpi_resource * +acpi_get_crs_next (struct acpi_buffer *buf, int *offset) { - acpi_resource *res; + struct acpi_resource *res; if (*offset >= buf->length) return NULL; @@ -157,11 +157,11 @@ return res; } -acpi_resource_data * -acpi_get_crs_type (acpi_buffer *buf, int *offset, int type) +union acpi_resource_data * +acpi_get_crs_type (struct acpi_buffer *buf, int *offset, int type) { for (;;) { - acpi_resource *res = acpi_get_crs_next(buf, offset); + struct acpi_resource *res = acpi_get_crs_next(buf, offset); if (!res) return NULL; if (res->id == type) @@ -170,7 +170,7 @@ } void -acpi_dispose_crs (acpi_buffer *buf) +acpi_dispose_crs (struct acpi_buffer *buf) { kfree(buf->pointer); } @@ -199,7 +199,7 @@ /* correctable platform error interrupt */ vector = platform_intr_list[int_type]; } else - printk("acpi_request_vector(): invalid interrupt type\n"); + printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n"); return vector; } @@ -249,7 +249,7 @@ acpi_table_print_madt_entry(header); - printk("CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid); + printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid); if (lsapic->flags.enabled) { available_cpus++; @@ -478,8 +478,8 @@ len = sizeof(struct acpi_table_header) + 8 + slit->localities * slit->localities; if (slit->header.length != len) { - printk("ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", - len, slit->header.length); + printk(KERN_ERR "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", + len, slit->header.length); memset(numa_slit, 10, sizeof(numa_slit)); return; } @@ -514,8 +514,8 @@ size = (size << 32) | ma->length_lo; if (num_memblks >= NR_MEMBLKS) { - printk("Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx\n", - size/(1024*1024), paddr); + printk(KERN_ERR "Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx\n", + size/(1024*1024), paddr); return; } @@ -545,8 +545,8 @@ if (min_hole_size) { if (min_hole_size > size) { - printk("Too huge memory hole. Ignoring %ld MBytes at %lx\n", - size/(1024*1024), paddr); + printk(KERN_ERR "Too huge memory hole. Ignoring %ld MBytes at %lx\n", + size/(1024*1024), paddr); return; } } @@ -605,8 +605,8 @@ for (i = 0; i < srat_num_cpus; i++) node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid]; - printk("Number of logical nodes in system = %d\n", numnodes); - printk("Number of memory chunks in system = %d\n", num_memblks); + printk(KERN_INFO "Number of logical nodes in system = %d\n", numnodes); + printk(KERN_INFO "Number of memory chunks in system = %d\n", num_memblks); if (!slit_table) return; memset(numa_slit, -1, sizeof(numa_slit)); @@ -638,7 +638,7 @@ acpi_parse_fadt (unsigned long phys_addr, unsigned long size) { struct acpi_table_header *fadt_header; - fadt_descriptor_rev2 *fadt; + struct fadt_descriptor_rev2 *fadt; u32 sci_irq, gsi_base; char *iosapic_address; @@ -649,7 +649,7 @@ if (fadt_header->revision != 3) return -ENODEV; /* Only deal with ACPI 2.0 FADT */ - fadt = (fadt_descriptor_rev2 *) fadt_header; + fadt = (struct fadt_descriptor_rev2 *) fadt_header; if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER)) acpi_kbd_controller_present = 0; @@ -806,7 +806,7 @@ #ifdef CONFIG_SMP if (available_cpus == 0) { - printk("ACPI: Found 0 CPUS; assuming 1\n"); + printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n"); available_cpus = 1; /* We've got at least one of these, no? */ } smp_boot_data.cpu_count = total_cpus; @@ -817,7 +817,7 @@ #endif #endif /* Make boot-up look pretty */ - printk("%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); + printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); return 0; } @@ -886,6 +886,28 @@ return isa_irq_to_vector(irq); return gsi_to_vector(irq); +} + +int __init +acpi_register_irq (u32 gsi, u32 polarity, u32 trigger) +{ + int vector = 0; + u32 irq_base; + char *iosapic_address; + + if (acpi_madt->flags.pcat_compat && (gsi < 16)) + return isa_irq_to_vector(gsi); + + if (!iosapic_register_intr) + return 0; + + /* Find the IOSAPIC */ + if (!acpi_find_iosapic(gsi, &irq_base, &iosapic_address)) { + /* Turn it on */ + vector = iosapic_register_intr (gsi, polarity, trigger, + irq_base, iosapic_address); + } + return vector; } #endif /* CONFIG_ACPI_BOOT */ diff -Nru a/arch/ia64/kernel/brl_emu.c b/arch/ia64/kernel/brl_emu.c --- a/arch/ia64/kernel/brl_emu.c Sun Feb 9 21:13:35 2003 +++ b/arch/ia64/kernel/brl_emu.c Sun Feb 9 21:13:35 2003 @@ -195,7 +195,7 @@ /* * The target address contains unimplemented bits. */ - printk("Woah! Unimplemented Instruction Address Trap!\n"); + printk(KERN_DEBUG "Woah! Unimplemented Instruction Address Trap!\n"); siginfo.si_signo = SIGILL; siginfo.si_errno = 0; siginfo.si_flags = 0; diff -Nru a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c --- a/arch/ia64/kernel/efi.c Sun Feb 9 21:13:28 2003 +++ b/arch/ia64/kernel/efi.c Sun Feb 9 21:13:28 2003 @@ -5,7 +5,7 @@ * * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999 Walt Drummond - * Copyright (C) 1999-2002 Hewlett-Packard Co. + * Copyright (C) 1999-2003 Hewlett-Packard Co. * David Mosberger-Tang * Stephane Eranian * @@ -33,15 +33,6 @@ #define EFI_DEBUG 0 -#ifdef CONFIG_HUGETLB_PAGE - -/* By default at total of 512MB is reserved huge pages. */ -#define HTLBZONE_SIZE_DEFAULT 0x20000000 - -unsigned long htlbzone_pages = (HTLBZONE_SIZE_DEFAULT >> HPAGE_SHIFT); - -#endif - extern efi_status_t efi_call_phys (void *, ...); struct efi efi; @@ -374,7 +365,7 @@ prev_valid = 1; } else { if (curr.start < prev.start) - printk("Oops: EFI memory table not ordered!\n"); + printk(KERN_ERR "Oops: EFI memory table not ordered!\n"); if (prev.end == curr.start) { /* merge two consecutive memory ranges */ @@ -446,7 +437,8 @@ * dedicated ITR for the PAL code. */ if ((vaddr & mask) == (KERNEL_START & mask)) { - printk("%s: no need to install ITR for PAL code\n", __FUNCTION__); + printk(KERN_INFO "%s: no need to install ITR for PAL code\n", + __FUNCTION__); continue; } @@ -454,7 +446,7 @@ panic("Woah! PAL code size bigger than a granule!"); mask = ~((1 << IA64_GRANULE_SHIFT) - 1); - printk("CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n", + printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n", smp_processor_id(), md->phys_addr, md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE); @@ -497,27 +489,8 @@ ++cp; } } -#ifdef CONFIG_HUGETLB_PAGE - /* Just duplicating the above algo for lpzone start */ - for (cp = saved_command_line; *cp; ) { - if (memcmp(cp, "lpmem=", 6) == 0) { - cp += 6; - htlbzone_pages = memparse(cp, &end); - htlbzone_pages = (htlbzone_pages >> HPAGE_SHIFT); - if (end != cp) - break; - cp = end; - } else { - while (*cp != ' ' && *cp) - ++cp; - while (*cp == ' ') - ++cp; - } - } - printk("Total HugeTLB_Page memory pages requested 0x%lx \n", htlbzone_pages); -#endif if (mem_limit != ~0UL) - printk("Ignoring memory above %luMB\n", mem_limit >> 20); + printk(KERN_INFO "Ignoring memory above %luMB\n", mem_limit >> 20); efi.systab = __va(ia64_boot_param->efi_systab); @@ -529,7 +502,7 @@ if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) panic("Woah! EFI system table signature incorrect\n"); if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0) - printk("Warning: EFI system table major version mismatch: " + printk(KERN_WARNING "Warning: EFI system table major version mismatch: " "got %d.%02d, expected %d.%02d\n", efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, EFI_SYSTEM_TABLE_REVISION >> 16, EFI_SYSTEM_TABLE_REVISION & 0xffff); @@ -544,7 +517,7 @@ vendor[i] = '\0'; } - printk("EFI v%u.%.02u by %s:", + printk(KERN_INFO "EFI v%u.%.02u by %s:", efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor); for (i = 0; i < efi.systab->nr_tables; i++) { @@ -636,7 +609,7 @@ | _PAGE_PL_0 | _PAGE_AR_RW)); #else - printk("EFI_MEMORY_WC mapping\n"); + printk(KERN_INFO "EFI_MEMORY_WC mapping\n"); md->virt_addr = (u64) ioremap(md->phys_addr, 0); #endif } else if (md->attribute & EFI_MEMORY_WT) { @@ -646,7 +619,7 @@ | _PAGE_PL_0 | _PAGE_AR_RW)); #else - printk("EFI_MEMORY_WT mapping\n"); + printk(KERN_INFO "EFI_MEMORY_WT mapping\n"); md->virt_addr = (u64) ioremap(md->phys_addr, 0); #endif } @@ -658,7 +631,8 @@ efi_desc_size, ia64_boot_param->efi_memdesc_version, ia64_boot_param->efi_memmap); if (status != EFI_SUCCESS) { - printk("Warning: unable to switch EFI into virtual mode (status=%lu)\n", status); + printk(KERN_WARNING "warning: unable to switch EFI into virtual mode " + "(status=%lu)\n", status); return; } diff -Nru a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S --- a/arch/ia64/kernel/entry.S Sun Feb 9 21:13:30 2003 +++ b/arch/ia64/kernel/entry.S Sun Feb 9 21:13:30 2003 @@ -3,7 +3,7 @@ * * Kernel entry points. * - * Copyright (C) 1998-2002 Hewlett-Packard Co + * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999 Walt Drummond @@ -22,8 +22,8 @@ /* * Global (preserved) predicate usage on syscall entry/exit path: * - * pKern: See entry.h. - * pUser: See entry.h. + * pKStk: See entry.h. + * pUStk: See entry.h. * pSys: See entry.h. * pNonSys: !pSys */ @@ -63,7 +63,7 @@ sxt4 r8=r8 // return 64-bit result ;; stf.spill [sp]=f0 -(p6) cmp.ne pKern,pUser=r0,r0 // a successful execve() lands us in user-mode... +(p6) cmp.ne pKStk,pUStk=r0,r0 // a successful execve() lands us in user-mode... mov rp=loc0 (p6) mov ar.pfs=r0 // clear ar.pfs on success (p7) br.ret.sptk.many rp @@ -193,7 +193,7 @@ ;; (p6) srlz.d ld8 sp=[r21] // load kernel stack pointer of new task - mov IA64_KR(CURRENT)=r20 // update "current" application register + mov IA64_KR(CURRENT)=in0 // update "current" application register mov r8=r13 // return pointer to previously running task mov r13=in0 // set "current" pointer ;; @@ -507,7 +507,14 @@ GLOBAL_ENTRY(ia64_trace_syscall) PT_REGS_UNWIND_INFO(0) +{ /* + * Some versions of gas generate bad unwind info if the first instruction of a + * procedure doesn't go into the first slot of a bundle. This is a workaround. + */ + nop.m 0 + nop.i 0 br.call.sptk.many rp=invoke_syscall_trace // give parent a chance to catch syscall args +} .ret6: br.call.sptk.many rp=b6 // do the syscall strace_check_retval: cmp.lt p6,p0=r8,r0 // syscall failed? @@ -537,12 +544,19 @@ GLOBAL_ENTRY(ia64_ret_from_clone) PT_REGS_UNWIND_INFO(0) +{ /* + * Some versions of gas generate bad unwind info if the first instruction of a + * procedure doesn't go into the first slot of a bundle. This is a workaround. + */ + nop.m 0 + nop.i 0 /* * We need to call schedule_tail() to complete the scheduling process. * Called by ia64_switch_to() after do_fork()->copy_thread(). r8 contains the * address of the previously executing task. */ br.call.sptk.many rp=ia64_invoke_schedule_tail +} .ret8: adds r2=TI_FLAGS+IA64_TASK_SIZE,r13 ;; @@ -569,11 +583,12 @@ // fall through GLOBAL_ENTRY(ia64_leave_kernel) PT_REGS_UNWIND_INFO(0) - // work.need_resched etc. mustn't get changed by this CPU before it returns to userspace: -(pUser) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUser -(pUser) rsm psr.i + // work.need_resched etc. mustn't get changed by this CPU before it returns to + // user- or fsys-mode: +(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk +(pUStk) rsm psr.i ;; -(pUser) adds r17=TI_FLAGS+IA64_TASK_SIZE,r13 +(pUStk) adds r17=TI_FLAGS+IA64_TASK_SIZE,r13 ;; .work_processed: (p6) ld4 r18=[r17] // load current_thread_info()->flags @@ -635,9 +650,9 @@ ;; srlz.i // ensure interruption collection is off mov b7=r15 + bsw.0 // switch back to bank 0 (no stop bit required beforehand...) ;; - bsw.0 // switch back to bank 0 - ;; +(pUStk) mov r18=IA64_KR(CURRENT) // Itanium 2: 12 cycle read latency adds r16=16,r12 adds r17=24,r12 ;; @@ -665,16 +680,21 @@ ;; ld8.fill r12=[r16],16 ld8.fill r13=[r17],16 +(pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18 ;; ld8.fill r14=[r16] ld8.fill r15=[r17] +(pUStk) mov r17=1 + ;; +(pUStk) st1 [r18]=r17 // restore current->thread.on_ustack shr.u r18=r19,16 // get byte size of existing "dirty" partition ;; mov r16=ar.bsp // get existing backing store pointer movl r17=THIS_CPU(ia64_phys_stacked_size_p8) ;; ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 -(pKern) br.cond.dpnt skip_rbs_switch +(pKStk) br.cond.dpnt skip_rbs_switch + /* * Restore user backing store. * @@ -710,21 +730,9 @@ shr.u loc1=r18,9 // RNaTslots <= dirtySize / (64*8) + 1 sub r17=r17,r18 // r17 = (physStackedSize + 8) - dirtySize ;; -#if 1 - .align 32 // see comment below about gas bug... -#endif mov ar.rsc=r19 // load ar.rsc to be used for "loadrs" shladd in0=loc1,3,r17 mov in1=0 -#if 0 - // gas-2.12.90 is unable to generate a stop bit after .align, which is bad, - // because alloc must be at the beginning of an insn-group. - .align 32 -#else - nop 0 - nop 0 - nop 0 -#endif ;; rse_clear_invalid: #ifdef CONFIG_ITANIUM @@ -788,12 +796,12 @@ skip_rbs_switch: mov b6=rB6 mov ar.pfs=rARPFS -(pUser) mov ar.bspstore=rARBSPSTORE +(pUStk) mov ar.bspstore=rARBSPSTORE (p9) mov cr.ifs=rCRIFS mov cr.ipsr=rCRIPSR mov cr.iip=rCRIIP ;; -(pUser) mov ar.rnat=rARRNAT // must happen with RSE in lazy mode +(pUStk) mov ar.rnat=rARRNAT // must happen with RSE in lazy mode mov ar.rsc=rARRSC mov ar.unat=rARUNAT mov pr=rARPR,-1 @@ -963,17 +971,16 @@ END(sys_rt_sigreturn) GLOBAL_ENTRY(ia64_prepare_handle_unaligned) - // - // r16 = fake ar.pfs, we simply need to make sure - // privilege is still 0 - // - mov r16=r0 .prologue + /* + * r16 = fake ar.pfs, we simply need to make sure privilege is still 0 + */ + mov r16=r0 DO_SAVE_SWITCH_STACK - br.call.sptk.many rp=ia64_handle_unaligned // stack frame setup in ivt + br.call.sptk.many rp=ia64_handle_unaligned // stack frame setup in ivt .ret21: .body DO_LOAD_SWITCH_STACK - br.cond.sptk.many rp // goes to ia64_leave_kernel + br.cond.sptk.many rp // goes to ia64_leave_kernel END(ia64_prepare_handle_unaligned) // @@ -1235,8 +1242,8 @@ data8 sys_sched_setaffinity data8 sys_sched_getaffinity data8 sys_set_tid_address - data8 ia64_ni_syscall // available. (was sys_alloc_hugepages) - data8 ia64_ni_syscall // available (was sys_free_hugepages) + data8 ia64_ni_syscall + data8 ia64_ni_syscall // 1235 data8 sys_exit_group data8 sys_lookup_dcookie data8 sys_io_setup diff -Nru a/arch/ia64/kernel/entry.h b/arch/ia64/kernel/entry.h --- a/arch/ia64/kernel/entry.h Sun Feb 9 21:13:31 2003 +++ b/arch/ia64/kernel/entry.h Sun Feb 9 21:13:31 2003 @@ -4,8 +4,8 @@ * Preserved registers that are shared between code in ivt.S and entry.S. Be * careful not to step on these! */ -#define pKern p2 /* will leave_kernel return to kernel-mode? */ -#define pUser p3 /* will leave_kernel return to user-mode? */ +#define pKStk p2 /* will leave_kernel return to kernel-stacks? */ +#define pUStk p3 /* will leave_kernel return to user-stacks? */ #define pSys p4 /* are we processing a (synchronous) system call? */ #define pNonSys p5 /* complement of pSys */ diff -Nru a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ia64/kernel/fsys.S Sun Feb 9 21:13:37 2003 @@ -0,0 +1,384 @@ +/* + * This file contains the light-weight system call handlers (fsyscall-handlers). + * + * Copyright (C) 2003 Hewlett-Packard Co + * David Mosberger-Tang + */ + +#include +#include +#include +#include + +/* + * See Documentation/ia64/fsys.txt for details on fsyscalls. + * + * On entry to an fsyscall handler: + * r10 = 0 (i.e., defaults to "successful syscall return") + * r11 = saved ar.pfs (a user-level value) + * r15 = system call number + * r16 = "current" task pointer (in normal kernel-mode, this is in r13) + * r32-r39 = system call arguments + * b6 = return address (a user-level value) + * ar.pfs = previous frame-state (a user-level value) + * PSR.be = cleared to zero (i.e., little-endian byte order is in effect) + * all other registers may contain values passed in from user-mode + * + * On return from an fsyscall handler: + * r11 = saved ar.pfs (as passed into the fsyscall handler) + * r15 = system call number (as passed into the fsyscall handler) + * r32-r39 = system call arguments (as passed into the fsyscall handler) + * b6 = return address (as passed into the fsyscall handler) + * ar.pfs = previous frame-state (as passed into the fsyscall handler) + */ + +ENTRY(fsys_ni_syscall) + mov r8=ENOSYS + mov r10=-1 + MCKINLEY_E9_WORKAROUND + br.ret.sptk.many b6 +END(fsys_ni_syscall) + +ENTRY(fsys_getpid) + add r9=TI_FLAGS+IA64_TASK_SIZE,r16 + ;; + ld4 r9=[r9] + add r8=IA64_TASK_TGID_OFFSET,r16 + ;; + and r9=TIF_ALLWORK_MASK,r9 + ld4 r8=[r8] // r8 = current->tgid + ;; + cmp.ne p8,p0=0,r9 +(p8) br.spnt.many fsys_fallback_syscall + MCKINLEY_E9_WORKAROUND + br.ret.sptk.many b6 +END(fsys_getpid) + +ENTRY(fsys_getppid) + add r17=IA64_TASK_GROUP_LEADER_OFFSET,r16 + ;; + ld8 r17=[r17] // r17 = current->group_leader + add r9=TI_FLAGS+IA64_TASK_SIZE,r16 + ;; + + ld4 r9=[r9] + add r17=IA64_TASK_REAL_PARENT_OFFSET,r17 // r17 = ¤t->group_leader->real_parent + ;; + and r9=TIF_ALLWORK_MASK,r9 + +1: ld8 r18=[r17] // r18 = current->group_leader->real_parent + ;; + cmp.ne p8,p0=0,r9 + add r8=IA64_TASK_TGID_OFFSET,r18 // r8 = ¤t->group_leader->real_parent->tgid + ;; + + /* + * The .acq is needed to ensure that the read of tgid has returned its data before + * we re-check "real_parent". + */ + ld4.acq r8=[r8] // r8 = current->group_leader->real_parent->tgid +#ifdef CONFIG_SMP + /* + * Re-read current->group_leader->real_parent. + */ + ld8 r19=[r17] // r19 = current->group_leader->real_parent +(p8) br.spnt.many fsys_fallback_syscall + ;; + cmp.ne p6,p0=r18,r19 // did real_parent change? + mov r19=0 // i must not leak kernel bits... +(p6) br.cond.spnt.few 1b // yes -> redo the read of tgid and the check + ;; + mov r17=0 // i must not leak kernel bits... + mov r18=0 // i must not leak kernel bits... +#else + mov r17=0 // i must not leak kernel bits... + mov r18=0 // i must not leak kernel bits... + mov r19=0 // i must not leak kernel bits... +#endif + MCKINLEY_E9_WORKAROUND + br.ret.sptk.many b6 +END(fsys_getppid) + +ENTRY(fsys_set_tid_address) + add r9=TI_FLAGS+IA64_TASK_SIZE,r16 + ;; + ld4 r9=[r9] + tnat.z p6,p7=r32 // check argument register for being NaT + ;; + and r9=TIF_ALLWORK_MASK,r9 + add r8=IA64_TASK_PID_OFFSET,r16 + add r18=IA64_TASK_CLEAR_CHILD_TID_OFFSET,r16 + ;; + ld4 r8=[r8] + cmp.ne p8,p0=0,r9 + mov r17=-1 + ;; +(p6) st8 [r18]=r32 +(p7) st8 [r18]=r17 +(p8) br.spnt.many fsys_fallback_syscall + ;; + mov r17=0 // i must not leak kernel bits... + mov r18=0 // i must not leak kernel bits... + MCKINLEY_E9_WORKAROUND + br.ret.sptk.many b6 +END(fsys_set_tid_address) + + .rodata + .align 8 + .globl fsyscall_table +fsyscall_table: + data8 fsys_ni_syscall + data8 fsys_fallback_syscall // exit // 1025 + data8 fsys_fallback_syscall // read + data8 fsys_fallback_syscall // write + data8 fsys_fallback_syscall // open + data8 fsys_fallback_syscall // close + data8 fsys_fallback_syscall // creat // 1030 + data8 fsys_fallback_syscall // link + data8 fsys_fallback_syscall // unlink + data8 fsys_fallback_syscall // execve + data8 fsys_fallback_syscall // chdir + data8 fsys_fallback_syscall // fchdir // 1035 + data8 fsys_fallback_syscall // utimes + data8 fsys_fallback_syscall // mknod + data8 fsys_fallback_syscall // chmod + data8 fsys_fallback_syscall // chown + data8 fsys_fallback_syscall // lseek // 1040 + data8 fsys_getpid + data8 fsys_getppid // getppid + data8 fsys_fallback_syscall // mount + data8 fsys_fallback_syscall // umount + data8 fsys_fallback_syscall // setuid // 1045 + data8 fsys_fallback_syscall // getuid + data8 fsys_fallback_syscall // geteuid + data8 fsys_fallback_syscall // ptrace + data8 fsys_fallback_syscall // access + data8 fsys_fallback_syscall // sync // 1050 + data8 fsys_fallback_syscall // fsync + data8 fsys_fallback_syscall // fdatasync + data8 fsys_fallback_syscall // kill + data8 fsys_fallback_syscall // rename + data8 fsys_fallback_syscall // mkdir // 1055 + data8 fsys_fallback_syscall // rmdir + data8 fsys_fallback_syscall // dup + data8 fsys_fallback_syscall // pipe + data8 fsys_fallback_syscall // times + data8 fsys_fallback_syscall // brk // 1060 + data8 fsys_fallback_syscall // setgid + data8 fsys_fallback_syscall // getgid + data8 fsys_fallback_syscall // getegid + data8 fsys_fallback_syscall // acct + data8 fsys_fallback_syscall // ioctl // 1065 + data8 fsys_fallback_syscall // fcntl + data8 fsys_fallback_syscall // umask + data8 fsys_fallback_syscall // chroot + data8 fsys_fallback_syscall // ustat + data8 fsys_fallback_syscall // dup2 // 1070 + data8 fsys_fallback_syscall // setreuid + data8 fsys_fallback_syscall // setregid + data8 fsys_fallback_syscall // getresuid + data8 fsys_fallback_syscall // setresuid + data8 fsys_fallback_syscall // getresgid // 1075 + data8 fsys_fallback_syscall // setresgid + data8 fsys_fallback_syscall // getgroups + data8 fsys_fallback_syscall // setgroups + data8 fsys_fallback_syscall // getpgid + data8 fsys_fallback_syscall // setpgid // 1080 + data8 fsys_fallback_syscall // setsid + data8 fsys_fallback_syscall // getsid + data8 fsys_fallback_syscall // sethostname + data8 fsys_fallback_syscall // setrlimit + data8 fsys_fallback_syscall // getrlimit // 1085 + data8 fsys_fallback_syscall // getrusage + data8 fsys_fallback_syscall // gettimeofday + data8 fsys_fallback_syscall // settimeofday + data8 fsys_fallback_syscall // select + data8 fsys_fallback_syscall // poll // 1090 + data8 fsys_fallback_syscall // symlink + data8 fsys_fallback_syscall // readlink + data8 fsys_fallback_syscall // uselib + data8 fsys_fallback_syscall // swapon + data8 fsys_fallback_syscall // swapoff // 1095 + data8 fsys_fallback_syscall // reboot + data8 fsys_fallback_syscall // truncate + data8 fsys_fallback_syscall // ftruncate + data8 fsys_fallback_syscall // fchmod + data8 fsys_fallback_syscall // fchown // 1100 + data8 fsys_fallback_syscall // getpriority + data8 fsys_fallback_syscall // setpriority + data8 fsys_fallback_syscall // statfs + data8 fsys_fallback_syscall // fstatfs + data8 fsys_fallback_syscall // gettid // 1105 + data8 fsys_fallback_syscall // semget + data8 fsys_fallback_syscall // semop + data8 fsys_fallback_syscall // semctl + data8 fsys_fallback_syscall // msgget + data8 fsys_fallback_syscall // msgsnd // 1110 + data8 fsys_fallback_syscall // msgrcv + data8 fsys_fallback_syscall // msgctl + data8 fsys_fallback_syscall // shmget + data8 fsys_fallback_syscall // shmat + data8 fsys_fallback_syscall // shmdt // 1115 + data8 fsys_fallback_syscall // shmctl + data8 fsys_fallback_syscall // syslog + data8 fsys_fallback_syscall // setitimer + data8 fsys_fallback_syscall // getitimer + data8 fsys_fallback_syscall // 1120 + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall // vhangup + data8 fsys_fallback_syscall // lchown + data8 fsys_fallback_syscall // remap_file_pages // 1125 + data8 fsys_fallback_syscall // wait4 + data8 fsys_fallback_syscall // sysinfo + data8 fsys_fallback_syscall // clone + data8 fsys_fallback_syscall // setdomainname + data8 fsys_fallback_syscall // newuname // 1130 + data8 fsys_fallback_syscall // adjtimex + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall // init_module + data8 fsys_fallback_syscall // delete_module + data8 fsys_fallback_syscall // 1135 + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall // quotactl + data8 fsys_fallback_syscall // bdflush + data8 fsys_fallback_syscall // sysfs + data8 fsys_fallback_syscall // personality // 1140 + data8 fsys_fallback_syscall // afs_syscall + data8 fsys_fallback_syscall // setfsuid + data8 fsys_fallback_syscall // setfsgid + data8 fsys_fallback_syscall // getdents + data8 fsys_fallback_syscall // flock // 1145 + data8 fsys_fallback_syscall // readv + data8 fsys_fallback_syscall // writev + data8 fsys_fallback_syscall // pread64 + data8 fsys_fallback_syscall // pwrite64 + data8 fsys_fallback_syscall // sysctl // 1150 + data8 fsys_fallback_syscall // mmap + data8 fsys_fallback_syscall // munmap + data8 fsys_fallback_syscall // mlock + data8 fsys_fallback_syscall // mlockall + data8 fsys_fallback_syscall // mprotect // 1155 + data8 fsys_fallback_syscall // mremap + data8 fsys_fallback_syscall // msync + data8 fsys_fallback_syscall // munlock + data8 fsys_fallback_syscall // munlockall + data8 fsys_fallback_syscall // sched_getparam // 1160 + data8 fsys_fallback_syscall // sched_setparam + data8 fsys_fallback_syscall // sched_getscheduler + data8 fsys_fallback_syscall // sched_setscheduler + data8 fsys_fallback_syscall // sched_yield + data8 fsys_fallback_syscall // sched_get_priority_max // 1165 + data8 fsys_fallback_syscall // sched_get_priority_min + data8 fsys_fallback_syscall // sched_rr_get_interval + data8 fsys_fallback_syscall // nanosleep + data8 fsys_fallback_syscall // nfsservctl + data8 fsys_fallback_syscall // prctl // 1170 + data8 fsys_fallback_syscall // getpagesize + data8 fsys_fallback_syscall // mmap2 + data8 fsys_fallback_syscall // pciconfig_read + data8 fsys_fallback_syscall // pciconfig_write + data8 fsys_fallback_syscall // perfmonctl // 1175 + data8 fsys_fallback_syscall // sigaltstack + data8 fsys_fallback_syscall // rt_sigaction + data8 fsys_fallback_syscall // rt_sigpending + data8 fsys_fallback_syscall // rt_sigprocmask + data8 fsys_fallback_syscall // rt_sigqueueinfo // 1180 + data8 fsys_fallback_syscall // rt_sigreturn + data8 fsys_fallback_syscall // rt_sigsuspend + data8 fsys_fallback_syscall // rt_sigtimedwait + data8 fsys_fallback_syscall // getcwd + data8 fsys_fallback_syscall // capget // 1185 + data8 fsys_fallback_syscall // capset + data8 fsys_fallback_syscall // sendfile + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall // socket // 1190 + data8 fsys_fallback_syscall // bind + data8 fsys_fallback_syscall // connect + data8 fsys_fallback_syscall // listen + data8 fsys_fallback_syscall // accept + data8 fsys_fallback_syscall // getsockname // 1195 + data8 fsys_fallback_syscall // getpeername + data8 fsys_fallback_syscall // socketpair + data8 fsys_fallback_syscall // send + data8 fsys_fallback_syscall // sendto + data8 fsys_fallback_syscall // recv // 1200 + data8 fsys_fallback_syscall // recvfrom + data8 fsys_fallback_syscall // shutdown + data8 fsys_fallback_syscall // setsockopt + data8 fsys_fallback_syscall // getsockopt + data8 fsys_fallback_syscall // sendmsg // 1205 + data8 fsys_fallback_syscall // recvmsg + data8 fsys_fallback_syscall // pivot_root + data8 fsys_fallback_syscall // mincore + data8 fsys_fallback_syscall // madvise + data8 fsys_fallback_syscall // newstat // 1210 + data8 fsys_fallback_syscall // newlstat + data8 fsys_fallback_syscall // newfstat + data8 fsys_fallback_syscall // clone2 + data8 fsys_fallback_syscall // getdents64 + data8 fsys_fallback_syscall // getunwind // 1215 + data8 fsys_fallback_syscall // readahead + data8 fsys_fallback_syscall // setxattr + data8 fsys_fallback_syscall // lsetxattr + data8 fsys_fallback_syscall // fsetxattr + data8 fsys_fallback_syscall // getxattr // 1220 + data8 fsys_fallback_syscall // lgetxattr + data8 fsys_fallback_syscall // fgetxattr + data8 fsys_fallback_syscall // listxattr + data8 fsys_fallback_syscall // llistxattr + data8 fsys_fallback_syscall // flistxattr // 1225 + data8 fsys_fallback_syscall // removexattr + data8 fsys_fallback_syscall // lremovexattr + data8 fsys_fallback_syscall // fremovexattr + data8 fsys_fallback_syscall // tkill + data8 fsys_fallback_syscall // futex // 1230 + data8 fsys_fallback_syscall // sched_setaffinity + data8 fsys_fallback_syscall // sched_getaffinity + data8 fsys_set_tid_address // set_tid_address + data8 fsys_fallback_syscall // unused + data8 fsys_fallback_syscall // unused // 1235 + data8 fsys_fallback_syscall // exit_group + data8 fsys_fallback_syscall // lookup_dcookie + data8 fsys_fallback_syscall // io_setup + data8 fsys_fallback_syscall // io_destroy + data8 fsys_fallback_syscall // io_getevents // 1240 + data8 fsys_fallback_syscall // io_submit + data8 fsys_fallback_syscall // io_cancel + data8 fsys_fallback_syscall // epoll_create + data8 fsys_fallback_syscall // epoll_ctl + data8 fsys_fallback_syscall // epoll_wait // 1245 + data8 fsys_fallback_syscall // restart_syscall + data8 fsys_fallback_syscall // semtimedop + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall // 1250 + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall // 1255 + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall // 1260 + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall // 1265 + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall // 1270 + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall // 1275 + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall + data8 fsys_fallback_syscall diff -Nru a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S --- a/arch/ia64/kernel/gate.S Sun Feb 9 21:13:35 2003 +++ b/arch/ia64/kernel/gate.S Sun Feb 9 21:13:35 2003 @@ -2,7 +2,7 @@ * This file contains the code that gets mapped at the upper end of each task's text * region. For now, it contains the signal trampoline code only. * - * Copyright (C) 1999-2002 Hewlett-Packard Co + * Copyright (C) 1999-2003 Hewlett-Packard Co * David Mosberger-Tang */ @@ -14,6 +14,87 @@ #include .section .text.gate, "ax" +.start_gate: + + +#if CONFIG_FSYS + +#include + +/* + * On entry: + * r11 = saved ar.pfs + * r15 = system call # + * b0 = saved return address + * b6 = return address + * On exit: + * r11 = saved ar.pfs + * r15 = system call # + * b0 = saved return address + * all other "scratch" registers: undefined + * all "preserved" registers: same as on entry + */ +GLOBAL_ENTRY(syscall_via_epc) + .prologue + .altrp b6 + .body +{ + /* + * Note: the kernel cannot assume that the first two instructions in this + * bundle get executed. The remaining code must be safe even if + * they do not get executed. + */ + adds r17=-1024,r15 + mov r10=0 // default to successful syscall execution + epc +} + ;; + rsm psr.be + movl r18=fsyscall_table + + mov r16=IA64_KR(CURRENT) + mov r19=255 + ;; + shladd r18=r17,3,r18 + cmp.geu p6,p0=r19,r17 // (syscall > 0 && syscall <= 1024+255)? + ;; + srlz.d // ensure little-endian byteorder is in effect +(p6) ld8 r18=[r18] + ;; +(p6) mov b7=r18 +(p6) br.sptk.many b7 + + mov r10=-1 + mov r8=ENOSYS + MCKINLEY_E9_WORKAROUND + br.ret.sptk.many b6 +END(syscall_via_epc) + +GLOBAL_ENTRY(syscall_via_break) + .prologue + .altrp b6 + .body + break 0x100000 + br.ret.sptk.many b6 +END(syscall_via_break) + +GLOBAL_ENTRY(fsys_fallback_syscall) + /* + * It would be better/fsyser to do the SAVE_MIN magic directly here, but for now + * we simply fall back on doing a system-call via break. Good enough + * to get started. (Note: we have to do this through the gate page again, since + * the br.ret will switch us back to user-level privilege.) + * + * XXX Move this back to fsys.S after changing it over to avoid break 0x100000. + */ + movl r2=(syscall_via_break - .start_gate) + GATE_ADDR + ;; + MCKINLEY_E9_WORKAROUND + mov b7=r2 + br.ret.sptk.many b7 +END(fsys_fallback_syscall) + +#endif /* CONFIG_FSYS */ # define ARG0_OFF (16 + IA64_SIGFRAME_ARG0_OFFSET) # define ARG1_OFF (16 + IA64_SIGFRAME_ARG1_OFFSET) @@ -63,15 +144,18 @@ * call stack. */ +#define SIGTRAMP_SAVES \ + .unwabi @svr4, 's' // mark this as a sigtramp handler (saves scratch regs) \ + .savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF \ + .savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF \ + .savesp pr, PR_OFF+SIGCONTEXT_OFF \ + .savesp rp, RP_OFF+SIGCONTEXT_OFF \ + .vframesp SP_OFF+SIGCONTEXT_OFF + GLOBAL_ENTRY(ia64_sigtramp) // describe the state that is active when we get here: .prologue - .unwabi @svr4, 's' // mark this as a sigtramp handler (saves scratch regs) - .savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF - .savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF - .savesp pr, PR_OFF+SIGCONTEXT_OFF - .savesp rp, RP_OFF+SIGCONTEXT_OFF - .vframesp SP_OFF+SIGCONTEXT_OFF + SIGTRAMP_SAVES .body .label_state 1 @@ -156,10 +240,11 @@ ldf.fill f14=[base0],32 ldf.fill f15=[base1],32 mov r15=__NR_rt_sigreturn + .restore sp // pop .prologue break __BREAK_SYSCALL - .body - .copy_state 1 + .prologue + SIGTRAMP_SAVES setup_rbs: mov ar.rsc=0 // put RSE into enforced lazy mode ;; @@ -171,6 +256,7 @@ ;; .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF st8 [r14]=r16 // save sc_ar_rnat + .body adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp mov.m r16=ar.bsp // sc_loadrs <- (new bsp - new bspstore) << 16 @@ -182,10 +268,11 @@ ;; st8 [r14]=r15 // save sc_loadrs mov ar.rsc=0xf // set RSE into eager mode, pl 3 + .restore sp // pop .prologue br.cond.sptk back_from_setup_rbs .prologue - .copy_state 1 + SIGTRAMP_SAVES .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF .body restore_rbs: diff -Nru a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S --- a/arch/ia64/kernel/head.S Sun Feb 9 21:13:34 2003 +++ b/arch/ia64/kernel/head.S Sun Feb 9 21:13:34 2003 @@ -5,7 +5,7 @@ * to set up the kernel's global pointer and jump to the kernel * entry point. * - * Copyright (C) 1998-2001 Hewlett-Packard Co + * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co * David Mosberger-Tang * Stephane Eranian * Copyright (C) 1999 VA Linux Systems @@ -143,17 +143,14 @@ movl r2=init_thread_union cmp.eq isBP,isAP=r0,r0 #endif - ;; - extr r3=r2,0,61 // r3 == phys addr of task struct mov r16=KERNEL_TR_PAGE_NUM ;; // load the "current" pointer (r13) and ar.k6 with the current task - mov r13=r2 - mov IA64_KR(CURRENT)=r3 // Physical address - + mov IA64_KR(CURRENT)=r2 // virtual address // initialize k4 to a safe value (64-128MB is mapped by TR_KERNEL) mov IA64_KR(CURRENT_STACK)=r16 + mov r13=r2 /* * Reserve space at the top of the stack for "struct pt_regs". Kernel threads * don't store interesting values in that structure, but the space still needs diff -Nru a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c --- a/arch/ia64/kernel/ia64_ksyms.c Sun Feb 9 21:13:31 2003 +++ b/arch/ia64/kernel/ia64_ksyms.c Sun Feb 9 21:13:32 2003 @@ -142,4 +142,8 @@ EXPORT_SYMBOL(ia64_mv); #endif EXPORT_SYMBOL(machvec_noop); - +#ifdef CONFIG_PERFMON +#include +EXPORT_SYMBOL(pfm_install_alternate_syswide_subsystem); +EXPORT_SYMBOL(pfm_remove_alternate_syswide_subsystem); +#endif diff -Nru a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c --- a/arch/ia64/kernel/iosapic.c Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/kernel/iosapic.c Sun Feb 9 21:13:32 2003 @@ -4,7 +4,7 @@ * Copyright (C) 1999 Intel Corp. * Copyright (C) 1999 Asit Mallick * Copyright (C) 2000-2002 J.I. Lee - * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co. + * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co. * David Mosberger-Tang * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999,2000 Walt Drummond @@ -433,7 +433,7 @@ || iosapic_intr_info[vector].polarity || iosapic_intr_info[vector].trigger) { new_vector = ia64_alloc_vector(); - printk("Reassigning vector %d to %d\n", vector, new_vector); + printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], sizeof(struct iosapic_intr_info)); memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); @@ -468,17 +468,17 @@ #else if (iosapic_address) { if (iosapic_intr_info[vector].addr && (iosapic_intr_info[vector].addr != iosapic_address)) - printk("WARN: register_intr: diff IOSAPIC ADDRESS for GSI 0x%x, vector %d\n", - gsi, vector); + printk(KERN_WARNING "warning: register_intr: diff IOSAPIC ADDRESS for " + "GSI 0x%x, vector %d\n", gsi, vector); iosapic_intr_info[vector].addr = iosapic_address; if (iosapic_intr_info[vector].gsi_base && (iosapic_intr_info[vector].gsi_base != gsi_base)) { - printk("WARN: register_intr: diff GSI base 0x%x for GSI 0x%x, vector %d\n", - gsi_base, gsi, vector); + printk(KERN_WARNING "warning: register_intr: diff GSI base 0x%x for " + "GSI 0x%x, vector %d\n", gsi_base, gsi, vector); } iosapic_intr_info[vector].gsi_base = gsi_base; } else if (!iosapic_intr_info[vector].addr) - printk("WARN: register_intr: invalid override for GSI 0x%x, vector %d\n", - gsi, vector); + printk(KERN_WARNING "warning: register_intr: invalid override for GSI 0x%x, " + "vector %d\n", gsi, vector); #endif if (edge_triggered) { iosapic_intr_info[vector].trigger = IOSAPIC_EDGE; @@ -491,9 +491,8 @@ idesc = irq_desc(vector); if (idesc->handler != irq_type) { if (idesc->handler != &no_irq_type) - printk("%s: changing vector %d from %s to %s\n", - __FUNCTION__, vector, idesc->handler->typename, - irq_type->typename); + printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", + __FUNCTION__, vector, idesc->handler->typename, irq_type->typename); idesc->handler = irq_type; } } @@ -518,7 +517,7 @@ register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered, gsi_base, iosapic_address); - printk("GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", + printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", gsi, (polarity ? "high" : "low"), (edge_triggered ? "edge" : "level"), dest, vector); @@ -560,14 +559,14 @@ delivery = IOSAPIC_LOWEST_PRIORITY; break; default: - printk("iosapic_register_platform_irq(): invalid int type\n"); + printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type\n"); return -1; } register_intr(gsi, vector, delivery, polarity, edge_triggered, gsi_base, iosapic_address); - printk("PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", + printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n", int_type, gsi, (polarity ? "high" : "low"), (edge_triggered ? "edge" : "level"), dest, vector); @@ -594,7 +593,7 @@ index = find_iosapic(gsi); if (index < 0) { - printk("ISA: No corresponding IOSAPIC found : ISA IRQ %u -> GSI 0x%x\n", + printk(KERN_ERR "ISA: No corresponding IOSAPIC found : ISA IRQ %u -> GSI 0x%x\n", isa_irq, gsi); return; } @@ -634,7 +633,7 @@ * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support * enabled. */ - printk("%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__); + printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__); outb(0xff, 0xA1); outb(0xff, 0x21); } @@ -655,7 +654,7 @@ iosapic_lists[num_iosapic].num_rte = num_rte; num_iosapic++; - printk(KERN_INFO" IOSAPIC v%x.%x, address 0x%lx, GSIs 0x%x-0x%x\n", + printk(KERN_INFO " IOSAPIC v%x.%x, address 0x%lx, GSIs 0x%x-0x%x\n", (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, gsi_base, gsi_base + num_rte - 1); if ((gsi_base == 0) && pcat_compat) { @@ -692,7 +691,7 @@ idesc = irq_desc(vector); if (idesc->handler != irq_type) { if (idesc->handler != &no_irq_type) - printk("IOSAPIC: changing vector %d from %s to %s\n", + printk(KERN_INFO "IOSAPIC: changing vector %d from %s to %s\n", vector, idesc->handler->typename, irq_type->typename); idesc->handler = irq_type; } @@ -723,7 +722,8 @@ #endif set_rte(vector, dest); - printk("IOSAPIC: %s -> GSI 0x%x -> CPU 0x%04x vector %d\n", pci_id, gsi, dest, vector); + printk(KERN_INFO "IOSAPIC: %s -> GSI 0x%x -> CPU 0x%04x vector %d\n", + pci_id, gsi, dest, vector); } void __init @@ -751,8 +751,8 @@ index = find_iosapic(gsi); if (index < 0) { - printk(KERN_WARNING"IOSAPIC: GSI 0x%x has no IOSAPIC!\n", gsi); - return; + printk(KERN_WARNING "IOSAPIC: GSI 0x%x has no IOSAPIC!\n", gsi); + continue; } addr = iosapic_lists[index].addr; gsi_base = iosapic_lists[index].gsi_base; diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c --- a/arch/ia64/kernel/irq.c Sun Feb 9 21:13:35 2003 +++ b/arch/ia64/kernel/irq.c Sun Feb 9 21:13:35 2003 @@ -108,7 +108,7 @@ * a generic callback i think. */ #if CONFIG_X86 - printk("unexpected IRQ trap at vector %02x\n", irq); + printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq); #ifdef CONFIG_X86_LOCAL_APIC /* * Currently unexpected vectors happen only on SMP and APIC. @@ -122,7 +122,7 @@ #endif #endif #if CONFIG_IA64 - printk("Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id()); + printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id()); #endif } @@ -317,7 +317,7 @@ desc->depth--; break; case 0: - printk("enable_irq(%u) unbalanced from %p\n", + printk(KERN_ERR "enable_irq(%u) unbalanced from %p\n", irq, (void *) __builtin_return_address(0)); } spin_unlock_irqrestore(&desc->lock, flags); @@ -466,7 +466,7 @@ */ if (irqflags & SA_SHIRQ) { if (!dev_id) - printk("Bad boy: %s called us without a dev_id!\n", devname); + printk(KERN_ERR "Bad boy: %s called us without a dev_id!\n", devname); } #endif @@ -547,7 +547,7 @@ kfree(action); return; } - printk("Trying to free free IRQ%d\n",irq); + printk(KERN_ERR "Trying to free free IRQ%d\n",irq); spin_unlock_irqrestore(&desc->lock,flags); return; } diff -Nru a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c --- a/arch/ia64/kernel/irq_ia64.c Sun Feb 9 21:13:31 2003 +++ b/arch/ia64/kernel/irq_ia64.c Sun Feb 9 21:13:31 2003 @@ -178,7 +178,7 @@ register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction); #endif #ifdef CONFIG_PERFMON - perfmon_init_percpu(); + pfm_init_percpu(); #endif platform_irq_init(); } diff -Nru a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S --- a/arch/ia64/kernel/ivt.S Sun Feb 9 21:13:29 2003 +++ b/arch/ia64/kernel/ivt.S Sun Feb 9 21:13:29 2003 @@ -192,7 +192,7 @@ rfi END(vhpt_miss) - .align 1024 + .org ia64_ivt+0x400 ///////////////////////////////////////////////////////////////////////////////////////// // 0x0400 Entry 1 (size 64 bundles) ITLB (21) ENTRY(itlb_miss) @@ -206,7 +206,7 @@ mov r16=cr.ifa // get virtual address mov r29=b0 // save b0 mov r31=pr // save predicates -itlb_fault: +.itlb_fault: mov r17=cr.iha // get virtual address of L3 PTE movl r30=1f // load nested fault continuation point ;; @@ -230,7 +230,7 @@ rfi END(itlb_miss) - .align 1024 + .org ia64_ivt+0x0800 ///////////////////////////////////////////////////////////////////////////////////////// // 0x0800 Entry 2 (size 64 bundles) DTLB (9,48) ENTRY(dtlb_miss) @@ -268,7 +268,7 @@ rfi END(dtlb_miss) - .align 1024 + .org ia64_ivt+0x0c00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19) ENTRY(alt_itlb_miss) @@ -288,7 +288,7 @@ ;; (p8) mov cr.iha=r17 (p8) mov r29=b0 // save b0 -(p8) br.cond.dptk itlb_fault +(p8) br.cond.dptk .itlb_fault #endif extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl and r19=r19,r16 // clear ed, reserved bits, and PTE control bits @@ -306,7 +306,7 @@ rfi END(alt_itlb_miss) - .align 1024 + .org ia64_ivt+0x1000 ///////////////////////////////////////////////////////////////////////////////////////// // 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46) ENTRY(alt_dtlb_miss) @@ -379,7 +379,7 @@ br.call.sptk.many b6=ia64_do_page_fault // ignore return address END(page_fault) - .align 1024 + .org ia64_ivt+0x1400 ///////////////////////////////////////////////////////////////////////////////////////// // 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45) ENTRY(nested_dtlb_miss) @@ -440,7 +440,7 @@ br.sptk.many b0 // return to continuation point END(nested_dtlb_miss) - .align 1024 + .org ia64_ivt+0x1800 ///////////////////////////////////////////////////////////////////////////////////////// // 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24) ENTRY(ikey_miss) @@ -448,7 +448,7 @@ FAULT(6) END(ikey_miss) - .align 1024 + .org ia64_ivt+0x1c00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) ENTRY(dkey_miss) @@ -456,7 +456,7 @@ FAULT(7) END(dkey_miss) - .align 1024 + .org ia64_ivt+0x2000 ///////////////////////////////////////////////////////////////////////////////////////// // 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54) ENTRY(dirty_bit) @@ -512,7 +512,7 @@ rfi END(idirty_bit) - .align 1024 + .org ia64_ivt+0x2400 ///////////////////////////////////////////////////////////////////////////////////////// // 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27) ENTRY(iaccess_bit) @@ -571,7 +571,7 @@ rfi END(iaccess_bit) - .align 1024 + .org ia64_ivt+0x2800 ///////////////////////////////////////////////////////////////////////////////////////// // 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55) ENTRY(daccess_bit) @@ -618,7 +618,7 @@ rfi END(daccess_bit) - .align 1024 + .org ia64_ivt+0x2c00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x2c00 Entry 11 (size 64 bundles) Break instruction (33) ENTRY(break_fault) @@ -690,7 +690,7 @@ // NOT REACHED END(break_fault) -ENTRY(demine_args) +ENTRY_MIN_ALIGN(demine_args) alloc r2=ar.pfs,8,0,0,0 tnat.nz p8,p0=in0 tnat.nz p9,p0=in1 @@ -719,7 +719,7 @@ br.ret.sptk.many rp END(demine_args) - .align 1024 + .org ia64_ivt+0x3000 ///////////////////////////////////////////////////////////////////////////////////////// // 0x3000 Entry 12 (size 64 bundles) External Interrupt (4) ENTRY(interrupt) @@ -746,19 +746,19 @@ br.call.sptk.many b6=ia64_handle_irq END(interrupt) - .align 1024 + .org ia64_ivt+0x3400 ///////////////////////////////////////////////////////////////////////////////////////// // 0x3400 Entry 13 (size 64 bundles) Reserved DBG_FAULT(13) FAULT(13) - .align 1024 + .org ia64_ivt+0x3800 ///////////////////////////////////////////////////////////////////////////////////////// // 0x3800 Entry 14 (size 64 bundles) Reserved DBG_FAULT(14) FAULT(14) - .align 1024 + .org ia64_ivt+0x3c00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x3c00 Entry 15 (size 64 bundles) Reserved DBG_FAULT(15) @@ -803,7 +803,7 @@ br.sptk.many ia64_leave_kernel END(dispatch_illegal_op_fault) - .align 1024 + .org ia64_ivt+0x4000 ///////////////////////////////////////////////////////////////////////////////////////// // 0x4000 Entry 16 (size 64 bundles) Reserved DBG_FAULT(16) @@ -893,7 +893,7 @@ #endif /* CONFIG_IA32_SUPPORT */ - .align 1024 + .org ia64_ivt+0x4400 ///////////////////////////////////////////////////////////////////////////////////////// // 0x4400 Entry 17 (size 64 bundles) Reserved DBG_FAULT(17) @@ -925,7 +925,7 @@ br.call.sptk.many b6=ia64_bad_break // avoid WAW on CFM and ignore return addr END(non_syscall) - .align 1024 + .org ia64_ivt+0x4800 ///////////////////////////////////////////////////////////////////////////////////////// // 0x4800 Entry 18 (size 64 bundles) Reserved DBG_FAULT(18) @@ -959,7 +959,7 @@ br.sptk.many ia64_prepare_handle_unaligned END(dispatch_unaligned_handler) - .align 1024 + .org ia64_ivt+0x4c00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x4c00 Entry 19 (size 64 bundles) Reserved DBG_FAULT(19) @@ -1005,7 +1005,7 @@ // --- End of long entries, Beginning of short entries // - .align 1024 + .org ia64_ivt+0x5000 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49) ENTRY(page_not_present) @@ -1025,7 +1025,7 @@ br.sptk.many page_fault END(page_not_present) - .align 256 + .org ia64_ivt+0x5100 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52) ENTRY(key_permission) @@ -1038,7 +1038,7 @@ br.sptk.many page_fault END(key_permission) - .align 256 + .org ia64_ivt+0x5200 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26) ENTRY(iaccess_rights) @@ -1051,7 +1051,7 @@ br.sptk.many page_fault END(iaccess_rights) - .align 256 + .org ia64_ivt+0x5300 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53) ENTRY(daccess_rights) @@ -1064,7 +1064,7 @@ br.sptk.many page_fault END(daccess_rights) - .align 256 + .org ia64_ivt+0x5400 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39) ENTRY(general_exception) @@ -1079,7 +1079,7 @@ br.sptk.many dispatch_to_fault_handler END(general_exception) - .align 256 + .org ia64_ivt+0x5500 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35) ENTRY(disabled_fp_reg) @@ -1092,7 +1092,7 @@ br.sptk.many dispatch_to_fault_handler END(disabled_fp_reg) - .align 256 + .org ia64_ivt+0x5600 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50) ENTRY(nat_consumption) @@ -1100,7 +1100,7 @@ FAULT(26) END(nat_consumption) - .align 256 + .org ia64_ivt+0x5700 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5700 Entry 27 (size 16 bundles) Speculation (40) ENTRY(speculation_vector) @@ -1137,13 +1137,13 @@ rfi // and go back END(speculation_vector) - .align 256 + .org ia64_ivt+0x5800 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5800 Entry 28 (size 16 bundles) Reserved DBG_FAULT(28) FAULT(28) - .align 256 + .org ia64_ivt+0x5900 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56) ENTRY(debug_vector) @@ -1151,7 +1151,7 @@ FAULT(29) END(debug_vector) - .align 256 + .org ia64_ivt+0x5a00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57) ENTRY(unaligned_access) @@ -1162,91 +1162,103 @@ br.sptk.many dispatch_unaligned_handler END(unaligned_access) - .align 256 + .org ia64_ivt+0x5b00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57) +ENTRY(unsupported_data_reference) DBG_FAULT(31) FAULT(31) +END(unsupported_data_reference) - .align 256 + .org ia64_ivt+0x5c00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64) +ENTRY(floating_point_fault) DBG_FAULT(32) FAULT(32) +END(floating_point_fault) - .align 256 + .org ia64_ivt+0x5d00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66) +ENTRY(floating_point_trap) DBG_FAULT(33) FAULT(33) +END(floating_point_trap) - .align 256 + .org ia64_ivt+0x5e00 ///////////////////////////////////////////////////////////////////////////////////////// -// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Tranfer Trap (66) +// 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Transfer Trap (66) +ENTRY(lower_privilege_trap) DBG_FAULT(34) FAULT(34) +END(lower_privilege_trap) - .align 256 + .org ia64_ivt+0x5f00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68) +ENTRY(taken_branch_trap) DBG_FAULT(35) FAULT(35) +END(taken_branch_trap) - .align 256 + .org ia64_ivt+0x6000 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69) +ENTRY(single_step_trap) DBG_FAULT(36) FAULT(36) +END(single_step_trap) - .align 256 + .org ia64_ivt+0x6100 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6100 Entry 37 (size 16 bundles) Reserved DBG_FAULT(37) FAULT(37) - .align 256 + .org ia64_ivt+0x6200 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6200 Entry 38 (size 16 bundles) Reserved DBG_FAULT(38) FAULT(38) - .align 256 + .org ia64_ivt+0x6300 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6300 Entry 39 (size 16 bundles) Reserved DBG_FAULT(39) FAULT(39) - .align 256 + .org ia64_ivt+0x6400 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6400 Entry 40 (size 16 bundles) Reserved DBG_FAULT(40) FAULT(40) - .align 256 + .org ia64_ivt+0x6500 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6500 Entry 41 (size 16 bundles) Reserved DBG_FAULT(41) FAULT(41) - .align 256 + .org ia64_ivt+0x6600 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6600 Entry 42 (size 16 bundles) Reserved DBG_FAULT(42) FAULT(42) - .align 256 + .org ia64_ivt+0x6700 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6700 Entry 43 (size 16 bundles) Reserved DBG_FAULT(43) FAULT(43) - .align 256 + .org ia64_ivt+0x6800 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6800 Entry 44 (size 16 bundles) Reserved DBG_FAULT(44) FAULT(44) - .align 256 + .org ia64_ivt+0x6900 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77) ENTRY(ia32_exception) @@ -1254,7 +1266,7 @@ FAULT(45) END(ia32_exception) - .align 256 + .org ia64_ivt+0x6a00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept (30,31,59,70,71) ENTRY(ia32_intercept) @@ -1284,7 +1296,7 @@ FAULT(46) END(ia32_intercept) - .align 256 + .org ia64_ivt+0x6b00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt (74) ENTRY(ia32_interrupt) @@ -1297,121 +1309,121 @@ #endif END(ia32_interrupt) - .align 256 + .org ia64_ivt+0x6c00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6c00 Entry 48 (size 16 bundles) Reserved DBG_FAULT(48) FAULT(48) - .align 256 + .org ia64_ivt+0x6d00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6d00 Entry 49 (size 16 bundles) Reserved DBG_FAULT(49) FAULT(49) - .align 256 + .org ia64_ivt+0x6e00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6e00 Entry 50 (size 16 bundles) Reserved DBG_FAULT(50) FAULT(50) - .align 256 + .org ia64_ivt+0x6f00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x6f00 Entry 51 (size 16 bundles) Reserved DBG_FAULT(51) FAULT(51) - .align 256 + .org ia64_ivt+0x7000 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7000 Entry 52 (size 16 bundles) Reserved DBG_FAULT(52) FAULT(52) - .align 256 + .org ia64_ivt+0x7100 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7100 Entry 53 (size 16 bundles) Reserved DBG_FAULT(53) FAULT(53) - .align 256 + .org ia64_ivt+0x7200 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7200 Entry 54 (size 16 bundles) Reserved DBG_FAULT(54) FAULT(54) - .align 256 + .org ia64_ivt+0x7300 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7300 Entry 55 (size 16 bundles) Reserved DBG_FAULT(55) FAULT(55) - .align 256 + .org ia64_ivt+0x7400 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7400 Entry 56 (size 16 bundles) Reserved DBG_FAULT(56) FAULT(56) - .align 256 + .org ia64_ivt+0x7500 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7500 Entry 57 (size 16 bundles) Reserved DBG_FAULT(57) FAULT(57) - .align 256 + .org ia64_ivt+0x7600 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7600 Entry 58 (size 16 bundles) Reserved DBG_FAULT(58) FAULT(58) - .align 256 + .org ia64_ivt+0x7700 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7700 Entry 59 (size 16 bundles) Reserved DBG_FAULT(59) FAULT(59) - .align 256 + .org ia64_ivt+0x7800 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7800 Entry 60 (size 16 bundles) Reserved DBG_FAULT(60) FAULT(60) - .align 256 + .org ia64_ivt+0x7900 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7900 Entry 61 (size 16 bundles) Reserved DBG_FAULT(61) FAULT(61) - .align 256 + .org ia64_ivt+0x7a00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7a00 Entry 62 (size 16 bundles) Reserved DBG_FAULT(62) FAULT(62) - .align 256 + .org ia64_ivt+0x7b00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7b00 Entry 63 (size 16 bundles) Reserved DBG_FAULT(63) FAULT(63) - .align 256 + .org ia64_ivt+0x7c00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7c00 Entry 64 (size 16 bundles) Reserved DBG_FAULT(64) FAULT(64) - .align 256 + .org ia64_ivt+0x7d00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7d00 Entry 65 (size 16 bundles) Reserved DBG_FAULT(65) FAULT(65) - .align 256 + .org ia64_ivt+0x7e00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7e00 Entry 66 (size 16 bundles) Reserved DBG_FAULT(66) FAULT(66) - .align 256 + .org ia64_ivt+0x7f00 ///////////////////////////////////////////////////////////////////////////////////////// // 0x7f00 Entry 67 (size 16 bundles) Reserved DBG_FAULT(67) diff -Nru a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c --- a/arch/ia64/kernel/machvec.c Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/kernel/machvec.c Sun Feb 9 21:13:32 2003 @@ -47,7 +47,7 @@ panic("generic kernel failed to find machine vector for platform %s!", name); } ia64_mv = *mv; - printk("booting generic kernel on platform %s\n", name); + printk(KERN_INFO "booting generic kernel on platform %s\n", name); } #endif /* CONFIG_IA64_GENERIC */ diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c --- a/arch/ia64/kernel/mca.c Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/kernel/mca.c Sun Feb 9 21:13:32 2003 @@ -231,7 +231,7 @@ { /* Register the CPE interrupt vector with SAL */ if (ia64_sal_mc_set_params(SAL_MC_PARAM_CPE_INT, SAL_MC_PARAM_MECHANISM_INT, cpev, 0, 0)) { - printk("ia64_mca_platform_init: failed to register Corrected " + printk(KERN_ERR "ia64_mca_platform_init: failed to register Corrected " "Platform Error interrupt vector with SAL.\n"); return; } @@ -398,7 +398,7 @@ IA64_MCA_RENDEZ_TIMEOUT, 0))) { - printk("ia64_mca_init: Failed to register rendezvous interrupt " + printk(KERN_ERR "ia64_mca_init: Failed to register rendezvous interrupt " "with SAL. rc = %ld\n", rc); return; } @@ -409,8 +409,8 @@ IA64_MCA_WAKEUP_VECTOR, 0, 0))) { - printk("ia64_mca_init: Failed to register wakeup interrupt with SAL. rc = %ld\n", - rc); + printk(KERN_ERR "ia64_mca_init: Failed to register wakeup interrupt with SAL. " + "rc = %ld\n", rc); return; } @@ -430,8 +430,8 @@ ia64_mc_info.imi_mca_handler_size, 0, 0, 0))) { - printk("ia64_mca_init: Failed to register os mca handler with SAL. rc = %ld\n", - rc); + printk(KERN_ERR "ia64_mca_init: Failed to register os mca handler with SAL. " + "rc = %ld\n", rc); return; } @@ -459,8 +459,8 @@ __pa(ia64_get_gp()), ia64_mc_info.imi_slave_init_handler_size))) { - printk("ia64_mca_init: Failed to register m/s init handlers with SAL. rc = %ld\n", - rc); + printk(KERN_ERR "ia64_mca_init: Failed to register m/s init handlers with SAL. " + "rc = %ld\n", rc); return; } @@ -495,7 +495,8 @@ } ia64_mca_register_cpev(cpev); } else - printk("ia64_mca_init: Failed to get routed CPEI vector from ACPI.\n"); + printk(KERN_ERR + "ia64_mca_init: Failed to get routed CPEI vector from ACPI.\n"); } /* Initialize the areas set aside by the OS to buffer the @@ -511,7 +512,7 @@ mca_test(); #endif /* #if defined(MCA_TEST) */ - printk("Mca related initialization done\n"); + printk(KERN_INFO "Mca related initialization done\n"); /* commented out because this is done elsewhere */ #if 0 @@ -807,7 +808,7 @@ sal_log_processor_info_t *proc_ptr; ia64_err_rec_t *plog_ptr; - printk("Entered OS INIT handler\n"); + printk(KERN_INFO "Entered OS INIT handler\n"); /* Get the INIT processor log */ if (!ia64_log_get(SAL_INFO_TYPE_INIT, (prfunc_t)printk)) @@ -1736,8 +1737,7 @@ /* * Now process processor device error record section */ - ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh, - printk); + ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh, printk); } IA64_MCA_DEBUG("ia64_mca_log_print: " diff -Nru a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h --- a/arch/ia64/kernel/minstate.h Sun Feb 9 21:13:35 2003 +++ b/arch/ia64/kernel/minstate.h Sun Feb 9 21:13:35 2003 @@ -30,25 +30,23 @@ * on interrupts. */ #define MINSTATE_START_SAVE_MIN_VIRT \ -(pUser) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ - dep r1=-1,r1,61,3; /* r1 = current (virtual) */ \ +(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ ;; \ -(pUser) mov.m rARRNAT=ar.rnat; \ -(pUser) addl rKRBS=IA64_RBS_OFFSET,r1; /* compute base of RBS */ \ -(pKern) mov r1=sp; /* get sp */ \ - ;; \ -(pUser) lfetch.fault.excl.nt1 [rKRBS]; \ -(pUser) mov rARBSPSTORE=ar.bspstore; /* save ar.bspstore */ \ -(pUser) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ +(pUStk) mov.m rARRNAT=ar.rnat; \ +(pUStk) addl rKRBS=IA64_RBS_OFFSET,r1; /* compute base of RBS */ \ +(pKStk) mov r1=sp; /* get sp */ \ ;; \ -(pUser) mov ar.bspstore=rKRBS; /* switch to kernel RBS */ \ -(pKern) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ +(pUStk) lfetch.fault.excl.nt1 [rKRBS]; \ +(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ +(pUStk) mov rARBSPSTORE=ar.bspstore; /* save ar.bspstore */ \ ;; \ -(pUser) mov r18=ar.bsp; \ -(pUser) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ +(pUStk) mov ar.bspstore=rKRBS; /* switch to kernel RBS */ \ +(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ + ;; \ +(pUStk) mov r18=ar.bsp; \ +(pUStk) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ #define MINSTATE_END_SAVE_MIN_VIRT \ - or r13=r13,r14; /* make `current' a kernel virtual address */ \ bsw.1; /* switch back to bank 1 (must be last in insn group) */ \ ;; @@ -57,21 +55,21 @@ * go virtual and dont want to destroy the iip or ipsr. */ #define MINSTATE_START_SAVE_MIN_PHYS \ -(pKern) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE; \ -(pUser) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ -(pUser) addl rKRBS=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ - ;; \ -(pUser) mov rARRNAT=ar.rnat; \ -(pKern) dep r1=0,sp,61,3; /* compute physical addr of sp */ \ -(pUser) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ -(pUser) mov rARBSPSTORE=ar.bspstore; /* save ar.bspstore */ \ -(pUser) dep rKRBS=-1,rKRBS,61,3; /* compute kernel virtual addr of RBS */\ +(pKStk) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE; \ +(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ +(pUStk) addl rKRBS=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ + ;; \ +(pUStk) mov rARRNAT=ar.rnat; \ +(pKStk) dep r1=0,sp,61,3; /* compute physical addr of sp */ \ +(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1; /* compute base of memory stack */ \ +(pUStk) mov rARBSPSTORE=ar.bspstore; /* save ar.bspstore */ \ +(pUStk) dep rKRBS=-1,rKRBS,61,3; /* compute kernel virtual addr of RBS */\ ;; \ -(pKern) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ -(pUser) mov ar.bspstore=rKRBS; /* switch to kernel RBS */ \ +(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ +(pUStk) mov ar.bspstore=rKRBS; /* switch to kernel RBS */ \ ;; \ -(pUser) mov r18=ar.bsp; \ -(pUser) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ +(pUStk) mov r18=ar.bsp; \ +(pUStk) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian, loadrs=0 */ \ #define MINSTATE_END_SAVE_MIN_PHYS \ or r12=r12,r14; /* make sp a kernel virtual address */ \ @@ -79,11 +77,13 @@ ;; #ifdef MINSTATE_VIRT +# define MINSTATE_GET_CURRENT(reg) mov reg=IA64_KR(CURRENT) # define MINSTATE_START_SAVE_MIN MINSTATE_START_SAVE_MIN_VIRT # define MINSTATE_END_SAVE_MIN MINSTATE_END_SAVE_MIN_VIRT #endif #ifdef MINSTATE_PHYS +# define MINSTATE_GET_CURRENT(reg) mov reg=IA64_KR(CURRENT);; dep reg=0,reg,61,3 # define MINSTATE_START_SAVE_MIN MINSTATE_START_SAVE_MIN_PHYS # define MINSTATE_END_SAVE_MIN MINSTATE_END_SAVE_MIN_PHYS #endif @@ -110,23 +110,26 @@ * we can pass interruption state as arguments to a handler. */ #define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA) \ - mov rARRSC=ar.rsc; \ - mov rARPFS=ar.pfs; \ - mov rR1=r1; \ - mov rARUNAT=ar.unat; \ - mov rCRIPSR=cr.ipsr; \ - mov rB6=b6; /* rB6 = branch reg 6 */ \ - mov rCRIIP=cr.iip; \ - mov r1=IA64_KR(CURRENT); /* r1 = current (physical) */ \ - COVER; \ + mov rARRSC=ar.rsc; /* M */ \ + mov rARUNAT=ar.unat; /* M */ \ + mov rR1=r1; /* A */ \ + MINSTATE_GET_CURRENT(r1); /* M (or M;;I) */ \ + mov rCRIPSR=cr.ipsr; /* M */ \ + mov rARPFS=ar.pfs; /* I */ \ + mov rCRIIP=cr.iip; /* M */ \ + mov rB6=b6; /* I */ /* rB6 = branch reg 6 */ \ + COVER; /* B;; (or nothing) */ \ ;; \ - invala; \ - extr.u r16=rCRIPSR,32,2; /* extract psr.cpl */ \ + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r1; \ ;; \ - cmp.eq pKern,pUser=r0,r16; /* are we in kernel mode already? (psr.cpl==0) */ \ + ld1 r17=[r16]; /* load current->thread.on_ustack flag */ \ + st1 [r16]=r0; /* clear current->thread.on_ustack flag */ \ /* switch from user to kernel RBS: */ \ ;; \ + invala; /* M */ \ SAVE_IFS; \ + cmp.eq pKStk,pUStk=r0,r17; /* are we in kernel mode already? (psr.cpl==0) */ \ + ;; \ MINSTATE_START_SAVE_MIN \ add r17=L1_CACHE_BYTES,r1 /* really: biggest cache-line size */ \ ;; \ @@ -138,23 +141,23 @@ ;; \ lfetch.fault.excl.nt1 [r17]; \ adds r17=8,r1; /* initialize second base pointer */ \ -(pKern) mov r18=r0; /* make sure r18 isn't NaT */ \ +(pKStk) mov r18=r0; /* make sure r18 isn't NaT */ \ ;; \ st8 [r17]=rCRIIP,16; /* save cr.iip */ \ st8 [r16]=rCRIFS,16; /* save cr.ifs */ \ -(pUser) sub r18=r18,rKRBS; /* r18=RSE.ndirty*8 */ \ +(pUStk) sub r18=r18,rKRBS; /* r18=RSE.ndirty*8 */ \ ;; \ st8 [r17]=rARUNAT,16; /* save ar.unat */ \ st8 [r16]=rARPFS,16; /* save ar.pfs */ \ shl r18=r18,16; /* compute ar.rsc to be used for "loadrs" */ \ ;; \ st8 [r17]=rARRSC,16; /* save ar.rsc */ \ -(pUser) st8 [r16]=rARRNAT,16; /* save ar.rnat */ \ -(pKern) adds r16=16,r16; /* skip over ar_rnat field */ \ +(pUStk) st8 [r16]=rARRNAT,16; /* save ar.rnat */ \ +(pKStk) adds r16=16,r16; /* skip over ar_rnat field */ \ ;; /* avoid RAW on r16 & r17 */ \ -(pUser) st8 [r17]=rARBSPSTORE,16; /* save ar.bspstore */ \ +(pUStk) st8 [r17]=rARBSPSTORE,16; /* save ar.bspstore */ \ st8 [r16]=rARPR,16; /* save predicates */ \ -(pKern) adds r17=16,r17; /* skip over ar_bspstore field */ \ +(pKStk) adds r17=16,r17; /* skip over ar_bspstore field */ \ ;; \ st8 [r17]=rB6,16; /* save b6 */ \ st8 [r16]=r18,16; /* save ar.rsc value for "loadrs" */ \ diff -Nru a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S --- a/arch/ia64/kernel/pal.S Sun Feb 9 21:13:37 2003 +++ b/arch/ia64/kernel/pal.S Sun Feb 9 21:13:37 2003 @@ -4,7 +4,7 @@ * * Copyright (C) 1999 Don Dugger * Copyright (C) 1999 Walt Drummond - * Copyright (C) 1999-2001 Hewlett-Packard Co + * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co * David Mosberger * Stephane Eranian * @@ -114,7 +114,7 @@ ;; rsm psr.i mov b7 = loc2 - ;; + ;; br.call.sptk.many rp=b7 // now make the call .ret0: mov psr.l = loc3 mov ar.pfs = loc1 @@ -131,15 +131,15 @@ * in0 Index of PAL service * in2 - in3 Remaning PAL arguments * - * PSR_DB, PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel. + * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel. * So we don't need to clear them. */ -#define PAL_PSR_BITS_TO_CLEAR \ - (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT | \ - IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \ +#define PAL_PSR_BITS_TO_CLEAR \ + (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB | IA64_PSR_RT | \ + IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \ IA64_PSR_DFL | IA64_PSR_DFH) -#define PAL_PSR_BITS_TO_SET \ +#define PAL_PSR_BITS_TO_SET \ (IA64_PSR_BN) @@ -161,7 +161,7 @@ ;; mov loc3 = psr // save psr adds r8 = 1f-1b,r8 // calculate return address for call - ;; + ;; mov loc4=ar.rsc // save RSE configuration dep.z loc2=loc2,0,61 // convert pal entry point to physical dep.z r8=r8,0,61 // convert rp to physical @@ -275,7 +275,6 @@ * Inputs: * in0 Address of stack storage for fp regs */ - GLOBAL_ENTRY(ia64_load_scratch_fpregs) alloc r3=ar.pfs,1,0,0,0 add r2=16,in0 diff -Nru a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c --- a/arch/ia64/kernel/palinfo.c Sun Feb 9 21:13:28 2003 +++ b/arch/ia64/kernel/palinfo.c Sun Feb 9 21:13:28 2003 @@ -6,7 +6,7 @@ * Intel IA-64 Architecture Software Developer's Manual v1.0. * * - * Copyright (C) 2000-2001 Hewlett-Packard Co + * Copyright (C) 2000-2001, 2003 Hewlett-Packard Co * Stephane Eranian * * 05/26/2000 S.Eranian initial release @@ -225,15 +225,12 @@ int i,j, k; s64 status; - if ((status=ia64_pal_cache_summary(&levels, &unique_caches)) != 0) { - printk("ia64_pal_cache_summary=%ld\n", status); - return 0; + if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) { + printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status); + return 0; } - p += sprintf(p, "Cache levels : %ld\n" \ - "Unique caches : %ld\n\n", - levels, - unique_caches); + p += sprintf(p, "Cache levels : %ld\nUnique caches : %ld\n\n", levels, unique_caches); for (i=0; i < levels; i++) { @@ -308,8 +305,8 @@ int i, j; s64 status; - if ((status=ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) { - printk("ia64_pal_vm_summary=%ld\n", status); + if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) { + printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status); return 0; } @@ -339,8 +336,8 @@ } p += sprintf(p, "\n"); - if ((status=ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) { - printk("ia64_pal_vm_page_size=%ld\n", status); + if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) { + printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status); return 0; } @@ -360,7 +357,7 @@ p = bitvector_process(p, vw_pages); if ((status=ia64_get_ptce(&ptce)) != 0) { - printk("ia64_get_ptce=%ld\n",status); + printk(KERN_ERR "ia64_get_ptce=%ld\n", status); return 0; } @@ -710,8 +707,8 @@ u64 rv2:32; } *rid_reg; - if ((status=ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) { - printk("ia64_pal_vm_summary=%ld\n", status); + if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) { + printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status); return 0; } max[0] = vm_info_1.pal_vm_info_1_s.max_itr_entry+1; @@ -722,7 +719,8 @@ status = ia64_pal_tr_read(j, i, tr_buffer, &tr_valid); if (status != 0) { - printk("palinfo: pal call failed on tr[%d:%d]=%ld\n", i, j, status); + printk(KERN_ERR "palinfo: pal call failed on tr[%d:%d]=%ld\n", + i, j, status); continue; } @@ -841,7 +839,7 @@ { palinfo_smp_data_t *data = (palinfo_smp_data_t *)info; if (data == NULL) { - printk("%s palinfo: data pointer is NULL\n", KERN_ERR); + printk(KERN_ERR "palinfo: data pointer is NULL\n"); data->ret = 0; /* no output */ return; } @@ -868,7 +866,8 @@ /* will send IPI to other CPU and wait for completion of remote call */ if ((ret=smp_call_function_single(f->req_cpu, palinfo_smp_call, &ptr, 0, 1))) { - printk("palinfo: remote CPU call from %d to %d on function %d: error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret); + printk(KERN_ERR "palinfo: remote CPU call from %d to %d on function %d: " + "error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret); return 0; } return ptr.ret; @@ -877,7 +876,7 @@ static int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page) { - printk("palinfo: should not be called with non SMP kernel\n"); + printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n"); return 0; } #endif /* CONFIG_SMP */ diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c --- a/arch/ia64/kernel/perfmon.c Sun Feb 9 21:13:36 2003 +++ b/arch/ia64/kernel/perfmon.c Sun Feb 9 21:13:36 2003 @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -56,8 +55,8 @@ /* * Reset register flags */ -#define PFM_RELOAD_LONG_RESET 1 -#define PFM_RELOAD_SHORT_RESET 2 +#define PFM_PMD_LONG_RESET 1 +#define PFM_PMD_SHORT_RESET 2 /* * Misc macros and definitions @@ -83,8 +82,10 @@ #define PFM_REG_CONFIG (0x4<<4|PFM_REG_IMPL) /* refine configuration */ #define PFM_REG_BUFFER (0x5<<4|PFM_REG_IMPL) /* PMD used as buffer */ +#define PMC_IS_LAST(i) (pmu_conf.pmc_desc[i].type & PFM_REG_END) +#define PMD_IS_LAST(i) (pmu_conf.pmd_desc[i].type & PFM_REG_END) -#define PFM_IS_DISABLED() pmu_conf.pfm_is_disabled +#define PFM_IS_DISABLED() pmu_conf.disabled #define PMC_OVFL_NOTIFY(ctx, i) ((ctx)->ctx_soft_pmds[i].flags & PFM_REGFL_OVFL_NOTIFY) #define PFM_FL_INHERIT_MASK (PFM_FL_INHERIT_NONE|PFM_FL_INHERIT_ONCE|PFM_FL_INHERIT_ALL) @@ -102,7 +103,6 @@ #define PMD_PMD_DEP(i) pmu_conf.pmd_desc[i].dep_pmd[0] #define PMC_PMD_DEP(i) pmu_conf.pmc_desc[i].dep_pmd[0] - /* k assume unsigned */ #define IBR_IS_IMPL(k) (kctx_soft_pmds[i].val + (ia64_get_pmd(i) & pmu_conf.perf_ovfl_val); + return ctx->ctx_soft_pmds[i].val + (ia64_get_pmd(i) & pmu_conf.ovfl_val); } static inline void pfm_write_soft_counter(pfm_context_t *ctx, int i, unsigned long val) { - ctx->ctx_soft_pmds[i].val = val & ~pmu_conf.perf_ovfl_val; + ctx->ctx_soft_pmds[i].val = val & ~pmu_conf.ovfl_val; /* * writing to unimplemented part is ignore, so we do not need to * mask off top part */ - ia64_set_pmd(i, val & pmu_conf.perf_ovfl_val); + ia64_set_pmd(i, val & pmu_conf.ovfl_val); } /* - * finds the number of PM(C|D) registers given - * the bitvector returned by PAL - */ -static unsigned long __init -find_num_pm_regs(long *buffer) -{ - int i=3; /* 4 words/per bitvector */ - - /* start from the most significant word */ - while (i>=0 && buffer[i] == 0 ) i--; - if (i< 0) { - printk(KERN_ERR "perfmon: No bit set in pm_buffer\n"); - return 0; - } - return 1+ ia64_fls(buffer[i]) + 64 * i; -} - - -/* * Generates a unique (per CPU) timestamp */ static inline unsigned long @@ -562,7 +593,7 @@ pfm_smpl_buffer_desc_t *psb = (pfm_smpl_buffer_desc_t *)vma->vm_private_data; if (psb == NULL) { - printk("perfmon: psb is null in [%d]\n", current->pid); + printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid); return; } /* @@ -627,7 +658,7 @@ * some sanity checks first */ if (ctx == NULL || task->mm == NULL || ctx->ctx_smpl_vaddr == 0 || ctx->ctx_psb == NULL) { - printk("perfmon: invalid context mm=%p\n", task->mm); + printk(KERN_DEBUG "perfmon: invalid context mm=%p\n", task->mm); return -1; } psb = ctx->ctx_psb; @@ -638,11 +669,11 @@ up_write(&task->mm->mmap_sem); if (r !=0) { - printk("perfmon: pid %d unable to unmap sampling buffer @0x%lx size=%ld\n", - task->pid, ctx->ctx_smpl_vaddr, psb->psb_size); + printk(KERN_DEBUG "perfmon: pid %d unable to unmap sampling buffer " + "@0x%lx size=%ld\n", task->pid, ctx->ctx_smpl_vaddr, psb->psb_size); } - DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d refcnt=%lu psb_flags=0x%x\n", + DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d refcnt=%lu psb_flags=0x%x\n", task->pid, ctx->ctx_smpl_vaddr, psb->psb_size, r, psb->psb_refcnt, psb->psb_flags)); return 0; @@ -677,7 +708,7 @@ page = pfm_kvirt_to_pa(buf); if (remap_page_range(vma, addr, page, PAGE_SIZE, PAGE_READONLY)) return -ENOMEM; - + addr += PAGE_SIZE; buf += PAGE_SIZE; size -= PAGE_SIZE; @@ -834,7 +865,7 @@ vma->vm_end = vma->vm_start + size; DBprintk(("entries=%ld aligned size=%ld, unmapped @0x%lx\n", entries, size, vma->vm_start)); - + /* can only be applied to current, need to have the mm semaphore held when called */ if (pfm_remap_buffer(vma, (unsigned long)smpl_buf, vma->vm_start, size)) { DBprintk(("Can't remap buffer\n")); @@ -875,6 +906,121 @@ return -ENOMEM; } +static int +pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned long cpu_mask) +{ + unsigned long m, undo_mask; + unsigned int n, i; + + /* + * validy checks on cpu_mask have been done upstream + */ + LOCK_PFS(); + + if (is_syswide) { + /* + * cannot mix system wide and per-task sessions + */ + if (pfm_sessions.pfs_task_sessions > 0UL) { + DBprintk(("system wide not possible, %u conflicting task_sessions\n", + pfm_sessions.pfs_task_sessions)); + goto abort; + } + + m = cpu_mask; undo_mask = 0UL; n = 0; + DBprintk(("cpu_mask=0x%lx\n", cpu_mask)); + for(i=0; m; i++, m>>=1) { + + if ((m & 0x1) == 0UL) continue; + + if (pfm_sessions.pfs_sys_session[i]) goto undo; + + DBprintk(("reserving CPU%d currently on CPU%d\n", i, smp_processor_id())); + + pfm_sessions.pfs_sys_session[i] = task; + undo_mask |= 1UL << i; + n++; + } + pfm_sessions.pfs_sys_sessions += n; + } else { + if (pfm_sessions.pfs_sys_sessions) goto abort; + pfm_sessions.pfs_task_sessions++; + } + DBprintk(("task_sessions=%u sys_session[%d]=%d", + pfm_sessions.pfs_task_sessions, + smp_processor_id(), pfm_sessions.pfs_sys_session[smp_processor_id()] ? 1 : 0)); + UNLOCK_PFS(); + return 0; +undo: + DBprintk(("system wide not possible, conflicting session [%d] on CPU%d\n", + pfm_sessions.pfs_sys_session[i]->pid, i)); + + for(i=0; undo_mask; i++, undo_mask >>=1) { + pfm_sessions.pfs_sys_session[i] = NULL; + } +abort: + UNLOCK_PFS(); + + return -EBUSY; + +} + +static int +pfm_unreserve_session(struct task_struct *task, int is_syswide, unsigned long cpu_mask) +{ + pfm_context_t *ctx; + unsigned long m; + unsigned int n, i; + + ctx = task ? task->thread.pfm_context : NULL; + + /* + * validy checks on cpu_mask have been done upstream + */ + LOCK_PFS(); + + DBprintk(("[%d] sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu_mask=0x%lx\n", + task->pid, + pfm_sessions.pfs_sys_sessions, + pfm_sessions.pfs_task_sessions, + pfm_sessions.pfs_sys_use_dbregs, + is_syswide, + cpu_mask)); + + + if (is_syswide) { + m = cpu_mask; n = 0; + for(i=0; m; i++, m>>=1) { + if ((m & 0x1) == 0UL) continue; + pfm_sessions.pfs_sys_session[i] = NULL; + n++; + } + /* + * would not work with perfmon+more than one bit in cpu_mask + */ + if (ctx && ctx->ctx_fl_using_dbreg) { + if (pfm_sessions.pfs_sys_use_dbregs == 0) { + printk(KERN_DEBUG "perfmon: invalid release for [%d] " + "sys_use_dbregs=0\n", task->pid); + } else { + pfm_sessions.pfs_sys_use_dbregs--; + } + } + pfm_sessions.pfs_sys_sessions -= n; + + DBprintk(("CPU%d sys_sessions=%u\n", + smp_processor_id(), pfm_sessions.pfs_sys_sessions)); + } else { + pfm_sessions.pfs_task_sessions--; + DBprintk(("[%d] task_sessions=%u\n", + task->pid, pfm_sessions.pfs_task_sessions)); + } + + UNLOCK_PFS(); + + return 0; +} + /* * XXX: do something better here */ @@ -891,6 +1037,7 @@ static int pfx_is_sane(struct task_struct *task, pfarg_context_t *pfx) { + unsigned long smpl_pmds = pfx->ctx_smpl_regs[0]; int ctx_flags; int cpu; @@ -957,6 +1104,11 @@ } #endif } + /* verify validity of smpl_regs */ + if ((smpl_pmds & pmu_conf.impl_pmds[0]) != smpl_pmds) { + DBprintk(("invalid smpl_regs 0x%lx\n", smpl_pmds)); + return -EINVAL; + } /* probably more to add here */ return 0; @@ -968,7 +1120,7 @@ { pfarg_context_t tmp; void *uaddr = NULL; - int ret, cpu = 0; + int ret; int ctx_flags; pid_t notify_pid; @@ -987,40 +1139,8 @@ ctx_flags = tmp.ctx_flags; - ret = -EBUSY; - - LOCK_PFS(); - - if (ctx_flags & PFM_FL_SYSTEM_WIDE) { - - /* at this point, we know there is at least one bit set */ - cpu = ffz(~tmp.ctx_cpu_mask); - - DBprintk(("requesting CPU%d currently on CPU%d\n",cpu, smp_processor_id())); - - if (pfm_sessions.pfs_task_sessions > 0) { - DBprintk(("system wide not possible, task_sessions=%ld\n", pfm_sessions.pfs_task_sessions)); - goto abort; - } - - if (pfm_sessions.pfs_sys_session[cpu]) { - DBprintk(("system wide not possible, conflicting session [%d] on CPU%d\n",pfm_sessions.pfs_sys_session[cpu]->pid, cpu)); - goto abort; - } - pfm_sessions.pfs_sys_session[cpu] = task; - /* - * count the number of system wide sessions - */ - pfm_sessions.pfs_sys_sessions++; - - } else if (pfm_sessions.pfs_sys_sessions == 0) { - pfm_sessions.pfs_task_sessions++; - } else { - /* no per-process monitoring while there is a system wide session */ - goto abort; - } - - UNLOCK_PFS(); + ret = pfm_reserve_session(task, ctx_flags & PFM_FL_SYSTEM_WIDE, tmp.ctx_cpu_mask); + if (ret) goto abort; ret = -ENOMEM; @@ -1103,6 +1223,7 @@ ctx->ctx_fl_inherit = ctx_flags & PFM_FL_INHERIT_MASK; ctx->ctx_fl_block = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0; ctx->ctx_fl_system = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0; + ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0; ctx->ctx_fl_frozen = 0; /* * setting this flag to 0 here means, that the creator or the task that the @@ -1113,14 +1234,10 @@ ctx->ctx_fl_protected = 0; /* for system wide mode only (only 1 bit set) */ - ctx->ctx_cpu = cpu; + ctx->ctx_cpu = ffz(~tmp.ctx_cpu_mask); atomic_set(&ctx->ctx_last_cpu,-1); /* SMP only, means no CPU */ - /* may be redudant with memset() but at least it's easier to remember */ - atomic_set(&ctx->ctx_saving_in_progress, 0); - atomic_set(&ctx->ctx_is_busy, 0); - sema_init(&ctx->ctx_restart_sem, 0); /* init this semaphore to locked */ if (__copy_to_user(req, &tmp, sizeof(tmp))) { @@ -1131,9 +1248,9 @@ DBprintk(("context=%p, pid=%d notify_task=%p\n", (void *)ctx, task->pid, ctx->ctx_notify_task)); - DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d\n", + DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d excl_idle=%d\n", (void *)ctx, task->pid, ctx_flags, ctx->ctx_fl_inherit, - ctx->ctx_fl_block, ctx->ctx_fl_system)); + ctx->ctx_fl_block, ctx->ctx_fl_system, ctx->ctx_fl_excl_idle)); /* * when no notification is required, we can make this visible at the last moment @@ -1146,8 +1263,8 @@ */ if (ctx->ctx_fl_system) { ctx->ctx_saved_cpus_allowed = task->cpus_allowed; - set_cpus_allowed(task, 1UL << cpu); - DBprintk(("[%d] rescheduled allowed=0x%lx\n", task->pid,task->cpus_allowed)); + set_cpus_allowed(task, tmp.ctx_cpu_mask); + DBprintk(("[%d] rescheduled allowed=0x%lx\n", task->pid, task->cpus_allowed)); } return 0; @@ -1155,20 +1272,8 @@ buffer_error: pfm_context_free(ctx); error: - /* - * undo session reservation - */ - LOCK_PFS(); - - if (ctx_flags & PFM_FL_SYSTEM_WIDE) { - pfm_sessions.pfs_sys_session[cpu] = NULL; - pfm_sessions.pfs_sys_sessions--; - } else { - pfm_sessions.pfs_task_sessions--; - } + pfm_unreserve_session(task, ctx_flags & PFM_FL_SYSTEM_WIDE , tmp.ctx_cpu_mask); abort: - UNLOCK_PFS(); - /* make sure we don't leave anything behind */ task->thread.pfm_context = NULL; @@ -1200,9 +1305,7 @@ unsigned long mask = ovfl_regs[0]; unsigned long reset_others = 0UL; unsigned long val; - int i, is_long_reset = (flag & PFM_RELOAD_LONG_RESET); - - DBprintk(("masks=0x%lx\n", mask)); + int i, is_long_reset = (flag == PFM_PMD_LONG_RESET); /* * now restore reset value on sampling overflowed counters @@ -1213,7 +1316,7 @@ val = pfm_new_counter_value(ctx->ctx_soft_pmds + i, is_long_reset); reset_others |= ctx->ctx_soft_pmds[i].reset_pmds[0]; - DBprintk(("[%d] %s reset soft_pmd[%d]=%lx\n", current->pid, + DBprintk_ovfl(("[%d] %s reset soft_pmd[%d]=%lx\n", current->pid, is_long_reset ? "long" : "short", i, val)); /* upper part is ignored on rval */ @@ -1235,7 +1338,7 @@ } else { ia64_set_pmd(i, val); } - DBprintk(("[%d] %s reset_others pmd[%d]=%lx\n", current->pid, + DBprintk_ovfl(("[%d] %s reset_others pmd[%d]=%lx\n", current->pid, is_long_reset ? "long" : "short", i, val)); } ia64_srlz_d(); @@ -1246,7 +1349,7 @@ { struct thread_struct *th = &task->thread; pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg; - unsigned long value; + unsigned long value, reset_pmds; unsigned int cnum, reg_flags, flags; int i; int ret = -EINVAL; @@ -1262,10 +1365,11 @@ if (__copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT; - cnum = tmp.reg_num; - reg_flags = tmp.reg_flags; - value = tmp.reg_value; - flags = 0; + cnum = tmp.reg_num; + reg_flags = tmp.reg_flags; + value = tmp.reg_value; + reset_pmds = tmp.reg_reset_pmds[0]; + flags = 0; /* * we reject all non implemented PMC as well @@ -1283,6 +1387,8 @@ * any other configuration is rejected. */ if (PMC_IS_MONITOR(cnum) || PMC_IS_COUNTING(cnum)) { + DBprintk(("pmc[%u].pm=%ld\n", cnum, PMC_PM(cnum, value))); + if (ctx->ctx_fl_system ^ PMC_PM(cnum, value)) { DBprintk(("pmc_pm=%ld fl_system=%d\n", PMC_PM(cnum, value), ctx->ctx_fl_system)); goto error; @@ -1310,6 +1416,11 @@ if (reg_flags & PFM_REGFL_RANDOM) flags |= PFM_REGFL_RANDOM; + /* verify validity of reset_pmds */ + if ((reset_pmds & pmu_conf.impl_pmds[0]) != reset_pmds) { + DBprintk(("invalid reset_pmds 0x%lx for pmc%u\n", reset_pmds, cnum)); + goto error; + } } else if (reg_flags & (PFM_REGFL_OVFL_NOTIFY|PFM_REGFL_RANDOM)) { DBprintk(("cannot set ovfl_notify or random on pmc%u\n", cnum)); goto error; @@ -1348,13 +1459,10 @@ ctx->ctx_soft_pmds[cnum].flags = flags; if (PMC_IS_COUNTING(cnum)) { - /* - * copy reset vector - */ - ctx->ctx_soft_pmds[cnum].reset_pmds[0] = tmp.reg_reset_pmds[0]; - ctx->ctx_soft_pmds[cnum].reset_pmds[1] = tmp.reg_reset_pmds[1]; - ctx->ctx_soft_pmds[cnum].reset_pmds[2] = tmp.reg_reset_pmds[2]; - ctx->ctx_soft_pmds[cnum].reset_pmds[3] = tmp.reg_reset_pmds[3]; + ctx->ctx_soft_pmds[cnum].reset_pmds[0] = reset_pmds; + + /* mark all PMDS to be accessed as used */ + CTX_USED_PMD(ctx, reset_pmds); } /* @@ -1397,7 +1505,7 @@ unsigned long value, hw_value; unsigned int cnum; int i; - int ret; + int ret = 0; /* we don't quite support this right now */ if (task != current) return -EINVAL; @@ -1448,9 +1556,9 @@ /* update virtualized (64bits) counter */ if (PMD_IS_COUNTING(cnum)) { ctx->ctx_soft_pmds[cnum].lval = value; - ctx->ctx_soft_pmds[cnum].val = value & ~pmu_conf.perf_ovfl_val; + ctx->ctx_soft_pmds[cnum].val = value & ~pmu_conf.ovfl_val; - hw_value = value & pmu_conf.perf_ovfl_val; + hw_value = value & pmu_conf.ovfl_val; ctx->ctx_soft_pmds[cnum].long_reset = tmp.reg_long_reset; ctx->ctx_soft_pmds[cnum].short_reset = tmp.reg_short_reset; @@ -1478,7 +1586,7 @@ ctx->ctx_soft_pmds[cnum].val, ctx->ctx_soft_pmds[cnum].short_reset, ctx->ctx_soft_pmds[cnum].long_reset, - ia64_get_pmd(cnum) & pmu_conf.perf_ovfl_val, + ia64_get_pmd(cnum) & pmu_conf.ovfl_val, PMC_OVFL_NOTIFY(ctx, cnum) ? 'Y':'N', ctx->ctx_used_pmds[0], ctx->ctx_soft_pmds[cnum].reset_pmds[0])); @@ -1504,15 +1612,18 @@ return ret; } - static int pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) { struct thread_struct *th = &task->thread; - unsigned long val = 0UL; + unsigned long val, lval; pfarg_reg_t *req = (pfarg_reg_t *)arg; unsigned int cnum, reg_flags = 0; - int i, ret = -EINVAL; + int i, ret = 0; + +#if __GNUC__ < 3 + int foo; +#endif if (!CTX_IS_ENABLED(ctx)) return -EINVAL; @@ -1528,9 +1639,16 @@ DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), task->pid)); for (i = 0; i < count; i++, req++) { - +#if __GNUC__ < 3 + foo = __get_user(cnum, &req->reg_num); + if (foo) return -EFAULT; + foo = __get_user(reg_flags, &req->reg_flags); + if (foo) return -EFAULT; +#else if (__get_user(cnum, &req->reg_num)) return -EFAULT; if (__get_user(reg_flags, &req->reg_flags)) return -EFAULT; +#endif + lval = 0UL; if (!PMD_IS_IMPL(cnum)) goto abort_mission; /* @@ -1553,34 +1671,16 @@ val = ia64_get_pmd(cnum); DBprintk(("reading pmd[%u]=0x%lx from hw\n", cnum, val)); } else { -#ifdef CONFIG_SMP - int cpu; - /* - * for SMP system, the context may still be live on another - * CPU so we need to fetch it before proceeding with the read - * This call we only be made once for the whole loop because - * of ctx_last_cpu becoming == -1. - * - * We cannot reuse ctx_last_cpu as it may change before we get to the - * actual IPI call. In this case, we will do the call for nothing but - * there is no way around it. The receiving side will simply do nothing. - */ - cpu = atomic_read(&ctx->ctx_last_cpu); - if (cpu != -1) { - DBprintk(("must fetch on CPU%d for [%d]\n", cpu, task->pid)); - pfm_fetch_regs(cpu, task, ctx); - } -#endif - /* context has been saved */ val = th->pmd[cnum]; } if (PMD_IS_COUNTING(cnum)) { /* * XXX: need to check for overflow */ - - val &= pmu_conf.perf_ovfl_val; + val &= pmu_conf.ovfl_val; val += ctx->ctx_soft_pmds[cnum].val; + + lval = ctx->ctx_soft_pmds[cnum].lval; } /* @@ -1592,10 +1692,11 @@ val = v; } - PFM_REG_RETFLAG_SET(reg_flags, 0); + PFM_REG_RETFLAG_SET(reg_flags, ret); DBprintk(("read pmd[%u] ret=%d value=0x%lx pmc=0x%lx\n", - cnum, ret, val, ia64_get_pmc(cnum))); + cnum, ret, val, ia64_get_pmc(cnum))); + /* * update register return value, abort all if problem during copy. * we only modify the reg_flags field. no check mode is fine because @@ -1604,16 +1705,19 @@ if (__put_user(cnum, &req->reg_num)) return -EFAULT; if (__put_user(val, &req->reg_value)) return -EFAULT; if (__put_user(reg_flags, &req->reg_flags)) return -EFAULT; + if (__put_user(lval, &req->reg_last_reset_value)) return -EFAULT; } return 0; abort_mission: PFM_REG_RETFLAG_SET(reg_flags, PFM_REG_RETFL_EINVAL); + /* + * XXX: if this fails, we stick with the original failure, flag not updated! + */ + __put_user(reg_flags, &req->reg_flags); - if (__put_user(reg_flags, &req->reg_flags)) ret = -EFAULT; - - return ret; + return -EINVAL; } #ifdef PFM_PMU_USES_DBR @@ -1655,7 +1759,7 @@ else pfm_sessions.pfs_ptrace_use_dbregs++; - DBprintk(("ptrace_use_dbregs=%lu sys_use_dbregs=%lu by [%d] ret = %d\n", + DBprintk(("ptrace_use_dbregs=%u sys_use_dbregs=%u by [%d] ret = %d\n", pfm_sessions.pfs_ptrace_use_dbregs, pfm_sessions.pfs_sys_use_dbregs, task->pid, ret)); @@ -1673,7 +1777,6 @@ * perfmormance monitoring, so we only decrement the number * of "ptraced" debug register users to keep the count up to date */ - int pfm_release_debug_registers(struct task_struct *task) { @@ -1681,7 +1784,8 @@ LOCK_PFS(); if (pfm_sessions.pfs_ptrace_use_dbregs == 0) { - printk("perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid); + printk(KERN_DEBUG "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", + task->pid); ret = -1; } else { pfm_sessions.pfs_ptrace_use_dbregs--; @@ -1702,6 +1806,7 @@ { return 0; } + int pfm_release_debug_registers(struct task_struct *task) { @@ -1721,9 +1826,12 @@ if (!CTX_IS_ENABLED(ctx)) return -EINVAL; if (task == current) { - DBprintk(("restarting self %d frozen=%d \n", current->pid, ctx->ctx_fl_frozen)); + DBprintk(("restarting self %d frozen=%d ovfl_regs=0x%lx\n", + task->pid, + ctx->ctx_fl_frozen, + ctx->ctx_ovfl_regs[0])); - pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_RELOAD_LONG_RESET); + pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET); ctx->ctx_ovfl_regs[0] = 0UL; @@ -1739,8 +1847,7 @@ } /* simply unfreeze */ - ia64_set_pmc(0, 0); - ia64_srlz_d(); + pfm_unfreeze_pmu(); return 0; } @@ -1806,18 +1913,18 @@ ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP); /* stop monitoring */ - __asm__ __volatile__ ("rsm psr.pp;;"::: "memory"); + pfm_clear_psr_pp(); ia64_srlz_i(); - __get_cpu_var(pfm_dcr_pp) = 0; + PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP); ia64_psr(regs)->pp = 0; } else { /* stop monitoring */ - __asm__ __volatile__ ("rum psr.up;;"::: "memory"); + pfm_clear_psr_up(); ia64_srlz_i(); @@ -1939,7 +2046,7 @@ pfm_sysctl.debug = mode == 0 ? 0 : 1; - printk("perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off"); + printk(KERN_INFO "perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off"); return 0; } @@ -1979,14 +2086,9 @@ int i, ret = 0; /* - * for range restriction: psr.db must be cleared or the - * the PMU will ignore the debug registers. - * - * XXX: may need more in system wide mode, - * no task can have this bit set? + * we do not need to check for ipsr.db because we do clear ibr.x, dbr.r, and dbr.w + * ensuring that no real breakpoint can be installed via this call. */ - if (ia64_psr(regs)->db == 1) return -EINVAL; - first_time = ctx->ctx_fl_using_dbreg == 0; @@ -2055,7 +2157,6 @@ * Now install the values into the registers */ for (i = 0; i < count; i++, req++) { - if (__copy_from_user(&tmp, req, sizeof(tmp))) goto abort_mission; @@ -2145,7 +2246,7 @@ * XXX: for now we can only come here on EINVAL */ PFM_REG_RETFLAG_SET(tmp.dbreg_flags, PFM_REG_RETFL_EINVAL); - __put_user(tmp.dbreg_flags, &req->dbreg_flags); + if (__put_user(tmp.dbreg_flags, &req->dbreg_flags)) ret = -EFAULT; } return ret; } @@ -2209,19 +2310,19 @@ current)); if (PMU_OWNER() != task) { - printk("perfmon: pfm_start task [%d] not pmu owner\n", task->pid); + printk(KERN_DEBUG "perfmon: pfm_start task [%d] not pmu owner\n", task->pid); return -EINVAL; } if (ctx->ctx_fl_system) { - __get_cpu_var(pfm_dcr_pp) = 1; + PFM_CPUINFO_SET(PFM_CPUINFO_DCR_PP); /* set user level psr.pp */ ia64_psr(regs)->pp = 1; /* start monitoring at kernel level */ - __asm__ __volatile__ ("ssm psr.pp;;"::: "memory"); + pfm_set_psr_pp(); /* enable dcr pp */ ia64_set_dcr(ia64_get_dcr()|IA64_DCR_PP); @@ -2230,14 +2331,15 @@ } else { if ((task->thread.flags & IA64_THREAD_PM_VALID) == 0) { - printk("perfmon: pfm_start task flag not set for [%d]\n", task->pid); + printk(KERN_DEBUG "perfmon: pfm_start task flag not set for [%d]\n", + task->pid); return -EINVAL; } /* set user level psr.up */ ia64_psr(regs)->up = 1; /* start monitoring at kernel level */ - __asm__ __volatile__ ("sum psr.up;;"::: "memory"); + pfm_set_psr_up(); ia64_srlz_i(); } @@ -2264,11 +2366,12 @@ ia64_psr(regs)->up = 0; /* just to make sure! */ /* make sure monitoring is stopped */ - __asm__ __volatile__ ("rsm psr.pp;;"::: "memory"); + pfm_clear_psr_pp(); ia64_srlz_i(); - __get_cpu_var(pfm_dcr_pp) = 0; - __get_cpu_var(pfm_syst_wide) = 1; + PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP); + PFM_CPUINFO_SET(PFM_CPUINFO_SYST_WIDE); + if (ctx->ctx_fl_excl_idle) PFM_CPUINFO_SET(PFM_CPUINFO_EXCL_IDLE); } else { /* * needed in case the task was a passive task during @@ -2279,7 +2382,7 @@ ia64_psr(regs)->up = 0; /* make sure monitoring is stopped */ - __asm__ __volatile__ ("rum psr.up;;"::: "memory"); + pfm_clear_psr_up(); ia64_srlz_i(); DBprintk(("clearing psr.sp for [%d]\n", current->pid)); @@ -2297,8 +2400,7 @@ atomic_set(&ctx->ctx_last_cpu, smp_processor_id()); /* simply unfreeze */ - ia64_set_pmc(0, 0); - ia64_srlz_d(); + pfm_unfreeze_pmu(); return 0; } @@ -2331,6 +2433,7 @@ abort_mission: PFM_REG_RETFLAG_SET(tmp.reg_flags, PFM_REG_RETFL_EINVAL); if (__copy_to_user(req, &tmp, sizeof(tmp))) ret = -EFAULT; + return ret; } @@ -2400,7 +2503,7 @@ return ret; } -asmlinkage int +asmlinkage long sys_perfmonctl (pid_t pid, int cmd, void *arg, int count, long arg5, long arg6, long arg7, long arg8, long stack) { @@ -2503,7 +2606,7 @@ * do some sanity checks first */ if (!ctx) { - printk("perfmon: [%d] has no PFM context\n", current->pid); + printk(KERN_DEBUG "perfmon: [%d] has no PFM context\n", current->pid); return; } @@ -2532,7 +2635,7 @@ * use the local reference */ - pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_RELOAD_LONG_RESET); + pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET); ctx->ctx_ovfl_regs[0] = 0UL; @@ -2545,8 +2648,7 @@ ctx->ctx_psb->psb_index = 0; } - ia64_set_pmc(0, 0); - ia64_srlz_d(); + pfm_unfreeze_pmu(); /* state restored, can go back to work (user mode) */ } @@ -2591,19 +2693,11 @@ h->pid = current->pid; h->cpu = smp_processor_id(); h->last_reset_value = ovfl_mask ? ctx->ctx_soft_pmds[ffz(~ovfl_mask)].lval : 0UL; - /* - * where did the fault happen - */ - h->ip = regs ? regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3): 0x0UL; - - /* - * which registers overflowed - */ - h->regs = ovfl_mask; + h->ip = regs ? regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3): 0x0UL; + h->regs = ovfl_mask; /* which registers overflowed */ /* guaranteed to monotonically increase on each cpu */ h->stamp = pfm_get_stamp(); - h->period = 0UL; /* not yet used */ /* position for first pmd */ e = (unsigned long *)(h+1); @@ -2683,16 +2777,16 @@ * Don't think this could happen given upfront tests */ if ((t->flags & IA64_THREAD_PM_VALID) == 0 && ctx->ctx_fl_system == 0) { - printk("perfmon: Spurious overflow interrupt: process %d not using perfmon\n", - task->pid); + printk(KERN_DEBUG "perfmon: Spurious overflow interrupt: process %d not " + "using perfmon\n", task->pid); return 0x1; } /* * sanity test. Should never happen */ if ((pmc0 & 0x1) == 0) { - printk("perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n", - task->pid, pmc0); + printk(KERN_DEBUG "perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n", + task->pid, pmc0); return 0x0; } @@ -2724,7 +2818,7 @@ * pfm_read_pmds(). */ old_val = ctx->ctx_soft_pmds[i].val; - ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.perf_ovfl_val; + ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.ovfl_val; /* * check for overflow condition @@ -2739,9 +2833,7 @@ } DBprintk_ovfl(("soft_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx\n", i, ctx->ctx_soft_pmds[i].val, old_val, - ia64_get_pmd(i) & pmu_conf.perf_ovfl_val, ovfl_pmds, ovfl_notify)); - - + ia64_get_pmd(i) & pmu_conf.ovfl_val, ovfl_pmds, ovfl_notify)); } /* @@ -2776,7 +2868,7 @@ */ if (ovfl_notify == 0UL) { if (ovfl_pmds) - pfm_reset_regs(ctx, &ovfl_pmds, PFM_RELOAD_SHORT_RESET); + pfm_reset_regs(ctx, &ovfl_pmds, PFM_PMD_SHORT_RESET); return 0x0; } @@ -2859,8 +2951,8 @@ * this call is safe in an interrupt handler, so does read_lock() on tasklist_lock */ ret = send_sig_info(SIGPROF, &si, ctx->ctx_notify_task); - if (ret != 0) - printk("send_sig_info(process %d, SIGPROF)=%d\n", + if (ret != 0) + printk(KERN_DEBUG "send_sig_info(process %d, SIGPROF)=%d\n", ctx->ctx_notify_task->pid, ret); /* * now undo the protections in order @@ -2924,7 +3016,7 @@ } static void -perfmon_interrupt (int irq, void *arg, struct pt_regs *regs) +pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs) { u64 pmc0; struct task_struct *task; @@ -2932,6 +3024,14 @@ pfm_stats[smp_processor_id()].pfm_ovfl_intr_count++; + /* + * if an alternate handler is registered, just bypass the default one + */ + if (pfm_alternate_intr_handler) { + (*pfm_alternate_intr_handler->handler)(irq, arg, regs); + return; + } + /* * srlz.d done before arriving here * @@ -2951,23 +3051,10 @@ /* sanity check */ if (!ctx) { - printk("perfmon: Spurious overflow interrupt: process %d has no PFM context\n", - task->pid); + printk(KERN_DEBUG "perfmon: Spurious overflow interrupt: process %d has " + "no PFM context\n", task->pid); return; } -#ifdef CONFIG_SMP - /* - * Because an IPI has higher priority than the PMU overflow interrupt, it is - * possible that the handler be interrupted by a request from another CPU to fetch - * the PMU state of the currently active context. The task may have just been - * migrated to another CPU which is trying to restore the context. If there was - * a pending overflow interrupt when the task left this CPU, it is possible for - * the handler to get interrupt by the IPI. In which case, we fetch request - * MUST be postponed until the interrupt handler is done. The ctx_is_busy - * flag indicates such a condition. The other CPU must busy wait until it's cleared. - */ - atomic_set(&ctx->ctx_is_busy, 1); -#endif /* * assume PMC[0].fr = 1 at this point @@ -2981,12 +3068,6 @@ ia64_set_pmc(0, pmc0); ia64_srlz_d(); -#ifdef CONFIG_SMP - /* - * announce that we are doing with the context - */ - atomic_set(&ctx->ctx_is_busy, 0); -#endif } else { pfm_stats[smp_processor_id()].pfm_spurious_ovfl_intr_count++; } @@ -2994,14 +3075,13 @@ /* for debug only */ static int -perfmon_proc_info(char *page) +pfm_proc_info(char *page) { char *p = page; int i; - p += sprintf(p, "enabled : %s\n", pmu_conf.pfm_is_disabled ? "No": "Yes"); p += sprintf(p, "fastctxsw : %s\n", pfm_sysctl.fastctxsw > 0 ? "Yes": "No"); - p += sprintf(p, "ovfl_mask : 0x%lx\n", pmu_conf.perf_ovfl_val); + p += sprintf(p, "ovfl_mask : 0x%lx\n", pmu_conf.ovfl_val); for(i=0; i < NR_CPUS; i++) { if (cpu_is_online(i) == 0) continue; @@ -3009,16 +3089,18 @@ p += sprintf(p, "CPU%-2d spurious intrs : %lu\n", i, pfm_stats[i].pfm_spurious_ovfl_intr_count); p += sprintf(p, "CPU%-2d recorded samples : %lu\n", i, pfm_stats[i].pfm_recorded_samples_count); p += sprintf(p, "CPU%-2d smpl buffer full : %lu\n", i, pfm_stats[i].pfm_full_smpl_buffer_count); + p += sprintf(p, "CPU%-2d syst_wide : %d\n", i, per_cpu(pfm_syst_info, i) & PFM_CPUINFO_SYST_WIDE ? 1 : 0); + p += sprintf(p, "CPU%-2d dcr_pp : %d\n", i, per_cpu(pfm_syst_info, i) & PFM_CPUINFO_DCR_PP ? 1 : 0); + p += sprintf(p, "CPU%-2d exclude idle : %d\n", i, per_cpu(pfm_syst_info, i) & PFM_CPUINFO_EXCL_IDLE ? 1 : 0); p += sprintf(p, "CPU%-2d owner : %d\n", i, pmu_owners[i].owner ? pmu_owners[i].owner->pid: -1); - p += sprintf(p, "CPU%-2d syst_wide : %d\n", i, per_cpu(pfm_syst_wide, i)); - p += sprintf(p, "CPU%-2d dcr_pp : %d\n", i, per_cpu(pfm_dcr_pp, i)); } LOCK_PFS(); - p += sprintf(p, "proc_sessions : %lu\n" - "sys_sessions : %lu\n" - "sys_use_dbregs : %lu\n" - "ptrace_use_dbregs : %lu\n", + + p += sprintf(p, "proc_sessions : %u\n" + "sys_sessions : %u\n" + "sys_use_dbregs : %u\n" + "ptrace_use_dbregs : %u\n", pfm_sessions.pfs_task_sessions, pfm_sessions.pfs_sys_sessions, pfm_sessions.pfs_sys_use_dbregs, @@ -3033,7 +3115,7 @@ static int perfmon_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len = perfmon_proc_info(page); + int len = pfm_proc_info(page); if (len <= off+count) *eof = 1; @@ -3046,24 +3128,66 @@ return len; } +/* + * we come here as soon as PFM_CPUINFO_SYST_WIDE is set. This happens + * during pfm_enable() hence before pfm_start(). We cannot assume monitoring + * is active or inactive based on mode. We must rely on the value in + * cpu_data(i)->pfm_syst_info + */ void -pfm_syst_wide_update_task(struct task_struct *task, int mode) +pfm_syst_wide_update_task(struct task_struct *task, unsigned long info, int is_ctxswin) { - struct pt_regs *regs = (struct pt_regs *)((unsigned long) task + IA64_STK_OFFSET); + struct pt_regs *regs; + unsigned long dcr; + unsigned long dcr_pp; - regs--; + dcr_pp = info & PFM_CPUINFO_DCR_PP ? 1 : 0; /* - * propagate the value of the dcr_pp bit to the psr + * pid 0 is guaranteed to be the idle task. There is one such task with pid 0 + * on every CPU, so we can rely on the pid to identify the idle task. + */ + if ((info & PFM_CPUINFO_EXCL_IDLE) == 0 || task->pid) { + regs = (struct pt_regs *)((unsigned long) task + IA64_STK_OFFSET); + regs--; + ia64_psr(regs)->pp = is_ctxswin ? dcr_pp : 0; + return; + } + /* + * if monitoring has started */ - ia64_psr(regs)->pp = mode ? __get_cpu_var(pfm_dcr_pp) : 0; + if (dcr_pp) { + dcr = ia64_get_dcr(); + /* + * context switching in? + */ + if (is_ctxswin) { + /* mask monitoring for the idle task */ + ia64_set_dcr(dcr & ~IA64_DCR_PP); + pfm_clear_psr_pp(); + ia64_srlz_i(); + return; + } + /* + * context switching out + * restore monitoring for next task + * + * Due to inlining this odd if-then-else construction generates + * better code. + */ + ia64_set_dcr(dcr |IA64_DCR_PP); + pfm_set_psr_pp(); + ia64_srlz_i(); + } } void pfm_save_regs (struct task_struct *task) { pfm_context_t *ctx; + unsigned long mask; u64 psr; + int i; ctx = task->thread.pfm_context; @@ -3071,7 +3195,7 @@ /* * save current PSR: needed because we modify it */ - __asm__ __volatile__ ("mov %0=psr;;": "=r"(psr) :: "memory"); + psr = pfm_get_psr(); /* * stop monitoring: @@ -3080,129 +3204,61 @@ * We do not need to set psr.sp because, it is irrelevant in kernel. * It will be restored from ipsr when going back to user level */ - __asm__ __volatile__ ("rum psr.up;;"::: "memory"); + pfm_clear_psr_up(); ia64_srlz_i(); ctx->ctx_saved_psr = psr; - //ctx->ctx_last_cpu = smp_processor_id(); - -} - -static void -pfm_lazy_save_regs (struct task_struct *task) -{ - pfm_context_t *ctx; - struct thread_struct *t; - unsigned long mask; - int i; - - DBprintk(("on [%d] by [%d]\n", task->pid, current->pid)); - - t = &task->thread; - ctx = task->thread.pfm_context; - #ifdef CONFIG_SMP - /* - * announce we are saving this PMU state - * This will cause other CPU, to wait until we're done - * before using the context.h + /* + * We do not use a lazy scheme in SMP because + * of the new scheduler which masks interrupts + * during low-level context switch. So we save + * all the PMD register we use and restore on + * ctxsw in. * - * must be an atomic operation + * release ownership of this PMU. + * must be done before we save the registers. */ - atomic_set(&ctx->ctx_saving_in_progress, 1); - - /* - * if owner is NULL, it means that the other CPU won the race - * and the IPI has caused the context to be saved in pfm_handle_fectch_regs() - * instead of here. We have nothing to do - * - * note that this is safe, because the other CPU NEVER modifies saving_in_progress. - */ - if (PMU_OWNER() == NULL) goto do_nothing; -#endif + SET_PMU_OWNER(NULL); /* - * do not own the PMU + * save PMDs */ - SET_PMU_OWNER(NULL); - ia64_srlz_d(); - /* - * XXX needs further optimization. - * Also must take holes into account - */ mask = ctx->ctx_used_pmds[0]; for (i=0; mask; i++, mask>>=1) { - if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i); + if (mask & 0x1) task->thread.pmd[i] =ia64_get_pmd(i); } - /* save pmc0 */ - t->pmc[0] = ia64_get_pmc(0); + /* + * save pmc0 + */ + task->thread.pmc[0] = ia64_get_pmc(0); - /* not owned by this CPU */ + /* + * force a full reload + */ atomic_set(&ctx->ctx_last_cpu, -1); - -#ifdef CONFIG_SMP -do_nothing: #endif - /* - * declare we are done saving this context - * - * must be an atomic operation - */ - atomic_set(&ctx->ctx_saving_in_progress,0); - } -#ifdef CONFIG_SMP -/* - * Handles request coming from other CPUs - */ -static void -pfm_handle_fetch_regs(void *info) +static void +pfm_lazy_save_regs (struct task_struct *task) { - pfm_smp_ipi_arg_t *arg = info; - struct thread_struct *t; pfm_context_t *ctx; + struct thread_struct *t; unsigned long mask; int i; - ctx = arg->task->thread.pfm_context; - t = &arg->task->thread; - - DBprintk(("task=%d owner=%d saving=%d\n", - arg->task->pid, - PMU_OWNER() ? PMU_OWNER()->pid: -1, - atomic_read(&ctx->ctx_saving_in_progress))); - - /* must wait until not busy before retrying whole request */ - if (atomic_read(&ctx->ctx_is_busy)) { - arg->retval = 2; - return; - } - - /* must wait if saving was interrupted */ - if (atomic_read(&ctx->ctx_saving_in_progress)) { - arg->retval = 1; - return; - } - - /* can proceed, done with context */ - if (PMU_OWNER() != arg->task) { - arg->retval = 0; - return; - } + DBprintk(("on [%d] by [%d]\n", task->pid, current->pid)); - DBprintk(("saving state for [%d] used_pmcs=0x%lx reload_pmcs=0x%lx used_pmds=0x%lx\n", - arg->task->pid, - ctx->ctx_used_pmcs[0], - ctx->ctx_reload_pmcs[0], - ctx->ctx_used_pmds[0])); + t = &task->thread; + ctx = task->thread.pfm_context; /* - * XXX: will be replaced with pure assembly call + * do not own the PMU */ SET_PMU_OWNER(NULL); @@ -3210,10 +3266,11 @@ /* * XXX needs further optimization. + * Also must take holes into account */ mask = ctx->ctx_used_pmds[0]; for (i=0; mask; i++, mask>>=1) { - if (mask & 0x1) t->pmd[i] = ia64_get_pmd(i); + if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i); } /* save pmc0 */ @@ -3221,66 +3278,7 @@ /* not owned by this CPU */ atomic_set(&ctx->ctx_last_cpu, -1); - - /* can proceed */ - arg->retval = 0; -} - -/* - * Function call to fetch PMU state from another CPU identified by 'cpu'. - * If the context is being saved on the remote CPU, then we busy wait until - * the saving is done and then we return. In this case, non IPI is sent. - * Otherwise, we send an IPI to the remote CPU, potentially interrupting - * pfm_lazy_save_regs() over there. - * - * If the retval==1, then it means that we interrupted remote save and that we must - * wait until the saving is over before proceeding. - * Otherwise, we did the saving on the remote CPU, and it was done by the time we got there. - * in either case, we can proceed. - */ -static void -pfm_fetch_regs(int cpu, struct task_struct *task, pfm_context_t *ctx) -{ - pfm_smp_ipi_arg_t arg; - int ret; - - arg.task = task; - arg.retval = -1; - - if (atomic_read(&ctx->ctx_is_busy)) { -must_wait_busy: - while (atomic_read(&ctx->ctx_is_busy)); - } - - if (atomic_read(&ctx->ctx_saving_in_progress)) { - DBprintk(("no IPI, must wait for [%d] to be saved on [%d]\n", task->pid, cpu)); -must_wait_saving: - /* busy wait */ - while (atomic_read(&ctx->ctx_saving_in_progress)); - DBprintk(("done saving for [%d] on [%d]\n", task->pid, cpu)); - return; - } - DBprintk(("calling CPU %d from CPU %d\n", cpu, smp_processor_id())); - - if (cpu == -1) { - printk("refusing to use -1 for [%d]\n", task->pid); - return; - } - - /* will send IPI to other CPU and wait for completion of remote call */ - if ((ret=smp_call_function_single(cpu, pfm_handle_fetch_regs, &arg, 0, 1))) { - printk("perfmon: remote CPU call from %d to %d error %d\n", smp_processor_id(), cpu, ret); - return; - } - /* - * we must wait until saving is over on the other CPU - * This is the case, where we interrupted the saving which started just at the time we sent the - * IPI. - */ - if (arg.retval == 1) goto must_wait_saving; - if (arg.retval == 2) goto must_wait_busy; } -#endif /* CONFIG_SMP */ void pfm_load_regs (struct task_struct *task) @@ -3291,14 +3289,16 @@ unsigned long mask; u64 psr; int i; -#ifdef CONFIG_SMP - int cpu; -#endif owner = PMU_OWNER(); ctx = task->thread.pfm_context; t = &task->thread; + if (ctx == NULL) { + printk("perfmon: pfm_load_regs: null ctx for [%d]\n", task->pid); + return; + } + /* * we restore ALL the debug registers to avoid picking up * stale state. @@ -3324,6 +3324,7 @@ /* * if we were the last user, then nothing to do except restore psr + * this path cannot be used in SMP */ if (owner == task) { if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id()) @@ -3331,32 +3332,19 @@ atomic_read(&ctx->ctx_last_cpu), task->pid)); psr = ctx->ctx_saved_psr; - __asm__ __volatile__ ("mov psr.l=%0;; srlz.i;;"::"r"(psr): "memory"); + pfm_set_psr_l(psr); return; } - DBprintk(("load_regs: must reload for [%d] owner=%d\n", - task->pid, owner ? owner->pid : -1 )); + /* * someone else is still using the PMU, first push it out and * then we'll be able to install our stuff ! + * + * not possible in SMP */ if (owner) pfm_lazy_save_regs(owner); -#ifdef CONFIG_SMP - /* - * check if context on another CPU (-1 means saved) - * We MUST use the variable, as last_cpu may change behind our - * back. If it changes to -1 (not on a CPU anymore), then in cpu - * we have the last CPU the context was on. We may be sending the - * IPI for nothing, but we have no way of verifying this. - */ - cpu = atomic_read(&ctx->ctx_last_cpu); - if (cpu != -1) { - pfm_fetch_regs(cpu, task, ctx); - } -#endif - /* * To avoid leaking information to the user level when psr.sp=0, * we must reload ALL implemented pmds (even the ones we don't use). @@ -3369,7 +3357,7 @@ */ mask = pfm_sysctl.fastctxsw || ctx->ctx_fl_protected ? ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0]; for (i=0; mask; i++, mask>>=1) { - if (mask & 0x1) ia64_set_pmd(i, t->pmd[i] & pmu_conf.perf_ovfl_val); + if (mask & 0x1) ia64_set_pmd(i, t->pmd[i] & pmu_conf.ovfl_val); } /* @@ -3393,8 +3381,7 @@ * fl_frozen==1 when we are in blocking mode waiting for restart */ if (ctx->ctx_fl_frozen == 0) { - ia64_set_pmc(0, 0); - ia64_srlz_d(); + pfm_unfreeze_pmu(); } atomic_set(&ctx->ctx_last_cpu, smp_processor_id()); @@ -3404,8 +3391,7 @@ * restore the psr we changed in pfm_save_regs() */ psr = ctx->ctx_saved_psr; - __asm__ __volatile__ ("mov psr.l=%0;; srlz.i;;"::"r"(psr): "memory"); - + pfm_set_psr_l(psr); } /* @@ -3419,15 +3405,16 @@ int i; if (task != current) { - printk("perfmon: invalid task in ia64_reset_pmu()\n"); + printk("perfmon: invalid task in pfm_reset_pmu()\n"); return; } /* Let's make sure the PMU is frozen */ - ia64_set_pmc(0,1); + pfm_freeze_pmu(); /* * install reset values for PMC. We skip PMC0 (done above) + * XX: good up to 64 PMCS */ for (i=1; (pmu_conf.pmc_desc[i].type & PFM_REG_END) == 0; i++) { if ((pmu_conf.pmc_desc[i].type & PFM_REG_IMPL) == 0) continue; @@ -3444,7 +3431,7 @@ /* * clear reset values for PMD. - * XXX: good up to 64 PMDS. Suppose that zero is a valid value. + * XXX: good up to 64 PMDS. */ for (i=0; (pmu_conf.pmd_desc[i].type & PFM_REG_END) == 0; i++) { if ((pmu_conf.pmd_desc[i].type & PFM_REG_IMPL) == 0) continue; @@ -3477,13 +3464,13 @@ * * We never directly restore PMC0 so we do not include it in the mask. */ - ctx->ctx_reload_pmcs[0] = pmu_conf.impl_regs[0] & ~0x1; + ctx->ctx_reload_pmcs[0] = pmu_conf.impl_pmcs[0] & ~0x1; /* * We must include all the PMD in this mask to avoid picking * up stale value and leak information, especially directly * at the user level when psr.sp=0 */ - ctx->ctx_reload_pmds[0] = pmu_conf.impl_regs[4]; + ctx->ctx_reload_pmds[0] = pmu_conf.impl_pmds[0]; /* * Keep track of the pmds we want to sample @@ -3493,7 +3480,7 @@ * * We ignore the unimplemented pmds specified by the user */ - ctx->ctx_used_pmds[0] = ctx->ctx_smpl_regs[0] & pmu_conf.impl_regs[4]; + ctx->ctx_used_pmds[0] = ctx->ctx_smpl_regs[0]; ctx->ctx_used_pmcs[0] = 1; /* always save/restore PMC[0] */ /* @@ -3547,16 +3534,17 @@ ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP); /* stop monitoring */ - __asm__ __volatile__ ("rsm psr.pp;;"::: "memory"); + pfm_clear_psr_pp(); ia64_srlz_i(); - __get_cpu_var(pfm_syst_wide) = 0; - __get_cpu_var(pfm_dcr_pp) = 0; + PFM_CPUINFO_CLEAR(PFM_CPUINFO_SYST_WIDE); + PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP); + PFM_CPUINFO_CLEAR(PFM_CPUINFO_EXCL_IDLE); } else { /* stop monitoring */ - __asm__ __volatile__ ("rum psr.up;;"::: "memory"); + pfm_clear_psr_up(); ia64_srlz_i(); @@ -3589,8 +3577,7 @@ * This destroys the overflow information. This is required to make sure * next process does not start with monitoring on if not requested */ - ia64_set_pmc(0, 1); - ia64_srlz_d(); + pfm_freeze_pmu(); /* * We don't need to restore psr, because we are on our way out @@ -3606,8 +3593,9 @@ * */ - if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id()) - printk("perfmon: [%d] last_cpu=%d\n", task->pid, atomic_read(&ctx->ctx_last_cpu)); + if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id()) + printk(KERN_DEBUG "perfmon: [%d] last_cpu=%d\n", + task->pid, atomic_read(&ctx->ctx_last_cpu)); /* * we save all the used pmds @@ -3622,10 +3610,14 @@ val = ia64_get_pmd(i); if (PMD_IS_COUNTING(i)) { - DBprintk(("[%d] pmd[%d] soft_pmd=0x%lx hw_pmd=0x%lx\n", task->pid, i, ctx->ctx_soft_pmds[i].val, val & pmu_conf.perf_ovfl_val)); + DBprintk(("[%d] pmd[%d] soft_pmd=0x%lx hw_pmd=0x%lx\n", + task->pid, + i, + ctx->ctx_soft_pmds[i].val, + val & pmu_conf.ovfl_val)); /* collect latest results */ - ctx->ctx_soft_pmds[i].val += val & pmu_conf.perf_ovfl_val; + ctx->ctx_soft_pmds[i].val += val & pmu_conf.ovfl_val; /* * now everything is in ctx_soft_pmds[] and we need @@ -3638,7 +3630,7 @@ * take care of overflow inline */ if (pmc0 & (1UL << i)) { - ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.perf_ovfl_val; + ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.ovfl_val; DBprintk(("[%d] pmd[%d] overflowed soft_pmd=0x%lx\n", task->pid, i, ctx->ctx_soft_pmds[i].val)); } @@ -3771,8 +3763,8 @@ m = nctx->ctx_used_pmds[0] >> PMU_FIRST_COUNTER; for(i = PMU_FIRST_COUNTER ; m ; m>>=1, i++) { if ((m & 0x1) && pmu_conf.pmd_desc[i].type == PFM_REG_COUNTING) { - nctx->ctx_soft_pmds[i].val = nctx->ctx_soft_pmds[i].lval & ~pmu_conf.perf_ovfl_val; - thread->pmd[i] = nctx->ctx_soft_pmds[i].lval & pmu_conf.perf_ovfl_val; + nctx->ctx_soft_pmds[i].val = nctx->ctx_soft_pmds[i].lval & ~pmu_conf.ovfl_val; + thread->pmd[i] = nctx->ctx_soft_pmds[i].lval & pmu_conf.ovfl_val; } else { thread->pmd[i] = 0UL; /* reset to initial state */ } @@ -3811,6 +3803,16 @@ sema_init(&nctx->ctx_restart_sem, 0); /* reset this semaphore to locked */ + /* + * propagate kernel psr in new context (used for first ctxsw in + */ + nctx->ctx_saved_psr = pfm_get_psr(); + + /* + * propagate kernel psr in new context (used for first ctxsw in + */ + nctx->ctx_saved_psr = pfm_get_psr(); + /* link with new task */ thread->pfm_context = nctx; @@ -3939,30 +3941,14 @@ UNLOCK_CTX(ctx); - LOCK_PFS(); + pfm_unreserve_session(task, ctx->ctx_fl_system, 1UL << ctx->ctx_cpu); if (ctx->ctx_fl_system) { - - pfm_sessions.pfs_sys_session[ctx->ctx_cpu] = NULL; - pfm_sessions.pfs_sys_sessions--; - DBprintk(("freeing syswide session on CPU%ld\n", ctx->ctx_cpu)); - - /* update perfmon debug register usage counter */ - if (ctx->ctx_fl_using_dbreg) { - if (pfm_sessions.pfs_sys_use_dbregs == 0) { - printk("perfmon: invalid release for [%d] sys_use_dbregs=0\n", task->pid); - } else - pfm_sessions.pfs_sys_use_dbregs--; - } - /* * remove any CPU pinning */ set_cpus_allowed(task, ctx->ctx_saved_cpus_allowed); - } else { - pfm_sessions.pfs_task_sessions--; - } - UNLOCK_PFS(); + } pfm_context_free(ctx); /* @@ -3983,15 +3969,14 @@ pfm_smpl_buffer_desc_t *tmp, *psb = task->thread.pfm_smpl_buf_list; if (psb == NULL) { - printk("perfmon: psb is null in [%d]\n", current->pid); + printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid); return -1; } /* * Walk through the list and free the sampling buffer and psb */ while (psb) { - DBprintk(("[%d] freeing smpl @%p size %ld\n", - current->pid, psb->psb_hdr, psb->psb_size)); + DBprintk(("[%d] freeing smpl @%p size %ld\n", current->pid, psb->psb_hdr, psb->psb_size)); pfm_rvfree(psb->psb_hdr, psb->psb_size); tmp = psb->psb_next; @@ -4095,16 +4080,16 @@ if (ctx && ctx->ctx_notify_task == task) { DBprintk(("trying for notifier [%d] in [%d]\n", task->pid, p->pid)); /* - * the spinlock is required to take care of a race condition with - * the send_sig_info() call. We must make sure that either the - * send_sig_info() completes using a valid task, or the - * notify_task is cleared before the send_sig_info() can pick up a - * stale value. Note that by the time this function is executed - * the 'task' is already detached from the tasklist. The problem - * is that the notifiers have a direct pointer to it. It is okay - * to send a signal to a task in this stage, it simply will have - * no effect. But it is better than sending to a completely - * destroyed task or worse to a new task using the same + * the spinlock is required to take care of a race condition + * with the send_sig_info() call. We must make sure that + * either the send_sig_info() completes using a valid task, + * or the notify_task is cleared before the send_sig_info() + * can pick up a stale value. Note that by the time this + * function is executed the 'task' is already detached from the + * tasklist. The problem is that the notifiers have a direct + * pointer to it. It is okay to send a signal to a task in this + * stage, it simply will have no effect. But it is better than sending + * to a completely destroyed task or worse to a new task using the same * task_struct address. */ LOCK_CTX(ctx); @@ -4123,87 +4108,130 @@ } static struct irqaction perfmon_irqaction = { - .handler = perfmon_interrupt, - .flags = SA_INTERRUPT, - .name = "perfmon" + .handler = pfm_interrupt_handler, + .flags = SA_INTERRUPT, + .name = "perfmon" }; +int +pfm_install_alternate_syswide_subsystem(pfm_intr_handler_desc_t *hdl) +{ + int ret; + + /* some sanity checks */ + if (hdl == NULL || hdl->handler == NULL) return -EINVAL; + + /* do the easy test first */ + if (pfm_alternate_intr_handler) return -EBUSY; + + /* reserve our session */ + ret = pfm_reserve_session(NULL, 1, cpu_online_map); + if (ret) return ret; + + if (pfm_alternate_intr_handler) { + printk(KERN_DEBUG "perfmon: install_alternate, intr_handler not NULL " + "after reserve\n"); + return -EINVAL; + } + + pfm_alternate_intr_handler = hdl; + + return 0; +} + +int +pfm_remove_alternate_syswide_subsystem(pfm_intr_handler_desc_t *hdl) +{ + if (hdl == NULL) return -EINVAL; + + /* cannot remove someone else's handler! */ + if (pfm_alternate_intr_handler != hdl) return -EINVAL; + + pfm_alternate_intr_handler = NULL; + + /* + * XXX: assume cpu_online_map has not changed since reservation + */ + pfm_unreserve_session(NULL, 1, cpu_online_map); + + return 0; +} /* * perfmon initialization routine, called from the initcall() table */ int __init -perfmon_init (void) +pfm_init(void) { - pal_perf_mon_info_u_t pm_info; - s64 status; + unsigned int n, n_counters, i; - pmu_conf.pfm_is_disabled = 1; + pmu_conf.disabled = 1; - printk("perfmon: version %u.%u (sampling format v%u.%u) IRQ %u\n", - PFM_VERSION_MAJ, - PFM_VERSION_MIN, - PFM_SMPL_VERSION_MAJ, - PFM_SMPL_VERSION_MIN, - IA64_PERFMON_VECTOR); + printk(KERN_INFO "perfmon: version %u.%u IRQ %u\n", PFM_VERSION_MAJ, PFM_VERSION_MIN, + IA64_PERFMON_VECTOR); - if ((status=ia64_pal_perf_mon_info(pmu_conf.impl_regs, &pm_info)) != 0) { - printk("perfmon: PAL call failed (%ld), perfmon disabled\n", status); - return -1; - } - - pmu_conf.perf_ovfl_val = (1UL << pm_info.pal_perf_mon_info_s.width) - 1; /* - * XXX: use the pfm_*_desc tables instead and simply verify with PAL + * compute the number of implemented PMD/PMC from the + * description tables */ - pmu_conf.max_counters = pm_info.pal_perf_mon_info_s.generic; - pmu_conf.num_pmcs = find_num_pm_regs(pmu_conf.impl_regs); - pmu_conf.num_pmds = find_num_pm_regs(&pmu_conf.impl_regs[4]); + n = 0; + for (i=0; PMC_IS_LAST(i) == 0; i++) { + if (PMC_IS_IMPL(i) == 0) continue; + pmu_conf.impl_pmcs[i>>6] |= 1UL << (i&63); + n++; + } + pmu_conf.num_pmcs = n; - printk("perfmon: %u bits counters\n", pm_info.pal_perf_mon_info_s.width); + n = 0; n_counters = 0; + for (i=0; PMD_IS_LAST(i) == 0; i++) { + if (PMD_IS_IMPL(i) == 0) continue; + pmu_conf.impl_pmds[i>>6] |= 1UL << (i&63); + n++; + if (PMD_IS_COUNTING(i)) n_counters++; + } + pmu_conf.num_pmds = n; + pmu_conf.num_counters = n_counters; - printk("perfmon: %lu PMC/PMD pairs, %lu PMCs, %lu PMDs\n", - pmu_conf.max_counters, pmu_conf.num_pmcs, pmu_conf.num_pmds); + printk(KERN_INFO "perfmon: %u PMCs, %u PMDs, %u counters (%lu bits)\n", + pmu_conf.num_pmcs, + pmu_conf.num_pmds, + pmu_conf.num_counters, + ffz(pmu_conf.ovfl_val)); /* sanity check */ if (pmu_conf.num_pmds >= IA64_NUM_PMD_REGS || pmu_conf.num_pmcs >= IA64_NUM_PMC_REGS) { - printk(KERN_ERR "perfmon: not enough pmc/pmd, perfmon is DISABLED\n"); - return -1; /* no need to continue anyway */ - } - - if (ia64_pal_debug_info(&pmu_conf.num_ibrs, &pmu_conf.num_dbrs)) { - printk(KERN_WARNING "perfmon: unable to get number of debug registers\n"); - pmu_conf.num_ibrs = pmu_conf.num_dbrs = 0; + printk(KERN_ERR "perfmon: not enough pmc/pmd, perfmon disabled\n"); + return -1; } - /* PAL reports the number of pairs */ - pmu_conf.num_ibrs <<=1; - pmu_conf.num_dbrs <<=1; - - /* - * setup the register configuration descriptions for the CPU - */ - pmu_conf.pmc_desc = pfm_pmc_desc; - pmu_conf.pmd_desc = pfm_pmd_desc; - - /* we are all set */ - pmu_conf.pfm_is_disabled = 0; /* * for now here for debug purposes */ perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL); + if (perfmon_dir == NULL) { + printk(KERN_ERR "perfmon: cannot create /proc entry, perfmon disabled\n"); + return -1; + } + /* + * create /proc/perfmon + */ pfm_sysctl_header = register_sysctl_table(pfm_sysctl_root, 0); + /* + * initialize all our spinlocks + */ spin_lock_init(&pfm_sessions.pfs_lock); + /* we are all set */ + pmu_conf.disabled = 0; + return 0; } - -__initcall(perfmon_init); +__initcall(pfm_init); void -perfmon_init_percpu (void) +pfm_init_percpu(void) { int i; @@ -4222,22 +4250,21 @@ * * On McKinley, this code is ineffective until PMC4 is initialized. */ - for (i=1; (pfm_pmc_desc[i].type & PFM_REG_END) == 0; i++) { - if ((pfm_pmc_desc[i].type & PFM_REG_IMPL) == 0) continue; - ia64_set_pmc(i, pfm_pmc_desc[i].default_value); + for (i=1; PMC_IS_LAST(i) == 0; i++) { + if (PMC_IS_IMPL(i) == 0) continue; + ia64_set_pmc(i, PMC_DFL_VAL(i)); } - for (i=0; (pfm_pmd_desc[i].type & PFM_REG_END) == 0; i++) { - if ((pfm_pmd_desc[i].type & PFM_REG_IMPL) == 0) continue; + + for (i=0; PMD_IS_LAST(i); i++) { + if (PMD_IS_IMPL(i) == 0) continue; ia64_set_pmd(i, 0UL); } - ia64_set_pmc(0,1UL); - ia64_srlz_d(); - + pfm_freeze_pmu(); } #else /* !CONFIG_PERFMON */ -asmlinkage int +asmlinkage long sys_perfmonctl (int pid, int cmd, void *req, int count, long arg5, long arg6, long arg7, long arg8, long stack) { diff -Nru a/arch/ia64/kernel/perfmon_generic.h b/arch/ia64/kernel/perfmon_generic.h --- a/arch/ia64/kernel/perfmon_generic.h Sun Feb 9 21:13:31 2003 +++ b/arch/ia64/kernel/perfmon_generic.h Sun Feb 9 21:13:31 2003 @@ -1,10 +1,17 @@ +/* + * This file contains the architected PMU register description tables + * and pmc checker used by perfmon.c. + * + * Copyright (C) 2002 Hewlett Packard Co + * Stephane Eranian + */ #define RDEP(x) (1UL<<(x)) -#if defined(CONFIG_ITANIUM) || defined(CONFIG_MCKINLEY) -#error "This file should only be used when CONFIG_ITANIUM and CONFIG_MCKINLEY are not defined" +#if defined(CONFIG_ITANIUM) || defined (CONFIG_MCKINLEY) +#error "This file should not be used when CONFIG_ITANIUM or CONFIG_MCKINLEY is defined" #endif -static pfm_reg_desc_t pmc_desc[PMU_MAX_PMCS]={ +static pfm_reg_desc_t pmc_gen_desc[PMU_MAX_PMCS]={ /* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, @@ -13,10 +20,10 @@ /* pmc5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ + { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ }; -static pfm_reg_desc_t pmd_desc[PMU_MAX_PMDS]={ +static pfm_reg_desc_t pmd_gen_desc[PMU_MAX_PMDS]={ /* pmd0 */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* pmd1 */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* pmd2 */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, @@ -25,5 +32,17 @@ /* pmd5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}}, /* pmd6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}}, /* pmd7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}}, - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ + { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ +}; + +/* + * impl_pmcs, impl_pmds are computed at runtime to minimize errors! + */ +static pmu_config_t pmu_conf={ + .disabled = 1, + .ovfl_val = (1UL << 32) - 1, + .num_ibrs = 8, + .num_dbrs = 8, + .pmd_desc = pfm_gen_pmd_desc, + .pmc_desc = pfm_gen_pmc_desc }; diff -Nru a/arch/ia64/kernel/perfmon_itanium.h b/arch/ia64/kernel/perfmon_itanium.h --- a/arch/ia64/kernel/perfmon_itanium.h Sun Feb 9 21:13:37 2003 +++ b/arch/ia64/kernel/perfmon_itanium.h Sun Feb 9 21:13:37 2003 @@ -15,7 +15,7 @@ static int pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs); static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs); -static pfm_reg_desc_t pfm_pmc_desc[PMU_MAX_PMCS]={ +static pfm_reg_desc_t pfm_ita_pmc_desc[PMU_MAX_PMCS]={ /* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, @@ -33,7 +33,7 @@ { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ }; -static pfm_reg_desc_t pfm_pmd_desc[PMU_MAX_PMDS]={ +static pfm_reg_desc_t pfm_ita_pmd_desc[PMU_MAX_PMDS]={ /* pmd0 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}}, /* pmd1 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}}, /* pmd2 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}}, @@ -54,6 +54,19 @@ /* pmd17 */ { PFM_REG_BUFFER , 0, 0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}}, { PFM_REG_END , 0, 0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ }; + +/* + * impl_pmcs, impl_pmds are computed at runtime to minimize errors! + */ +static pmu_config_t pmu_conf={ + .disabled = 1, + .ovfl_val = (1UL << 32) - 1, + .num_ibrs = 8, + .num_dbrs = 8, + .pmd_desc = pfm_ita_pmd_desc, + .pmc_desc = pfm_ita_pmc_desc +}; + static int pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs) diff -Nru a/arch/ia64/kernel/perfmon_mckinley.h b/arch/ia64/kernel/perfmon_mckinley.h --- a/arch/ia64/kernel/perfmon_mckinley.h Sun Feb 9 21:13:34 2003 +++ b/arch/ia64/kernel/perfmon_mckinley.h Sun Feb 9 21:13:34 2003 @@ -16,7 +16,7 @@ static int pfm_mck_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs); static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs); -static pfm_reg_desc_t pfm_pmc_desc[PMU_MAX_PMCS]={ +static pfm_reg_desc_t pfm_mck_pmc_desc[PMU_MAX_PMCS]={ /* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, /* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, @@ -36,7 +36,7 @@ { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ }; -static pfm_reg_desc_t pfm_pmd_desc[PMU_MAX_PMDS]={ +static pfm_reg_desc_t pfm_mck_pmd_desc[PMU_MAX_PMDS]={ /* pmd0 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}}, /* pmd1 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}}, /* pmd2 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}}, @@ -59,6 +59,19 @@ }; /* + * impl_pmcs, impl_pmds are computed at runtime to minimize errors! + */ +static pmu_config_t pmu_conf={ + .disabled = 1, + .ovfl_val = (1UL << 47) - 1, + .num_ibrs = 8, + .num_dbrs = 8, + .pmd_desc = pfm_mck_pmd_desc, + .pmc_desc = pfm_mck_pmc_desc +}; + + +/* * PMC reserved fields must have their power-up values preserved */ static int @@ -150,12 +163,12 @@ * i-side events in L1D and L2 caches */ if (check_case1) { - ret = ((val13 >> 45) & 0xf) == 0 + ret = ((val13 >> 45) & 0xf) == 0 && ((val8 & 0x1) == 0) && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0) ||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0)); - if (ret) printk("perfmon: failure check_case1\n"); + if (ret) printk(KERN_DEBUG "perfmon: failure check_case1\n"); } return ret ? -EINVAL : 0; diff -Nru a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c --- a/arch/ia64/kernel/process.c Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/kernel/process.c Sun Feb 9 21:13:32 2003 @@ -1,7 +1,7 @@ /* * Architecture-specific setup. * - * Copyright (C) 1998-2002 Hewlett-Packard Co + * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang */ #define __KERNEL_SYSCALLS__ /* see */ @@ -96,7 +96,7 @@ { unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; - printk("\nPid: %d, comm: %20s\n", current->pid, current->comm); + printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm); printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n", regs->cr_ipsr, regs->cr_ifs, ip, print_tainted()); print_symbol("ip is at %s\n", ip); @@ -144,6 +144,15 @@ void do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall) { +#ifdef CONFIG_FSYS + if (fsys_mode(current, &scr->pt)) { + /* defer signal-handling etc. until we return to privilege-level 0. */ + if (!ia64_psr(&scr->pt)->lp) + ia64_psr(&scr->pt)->lp = 1; + return; + } +#endif + #ifdef CONFIG_PERFMON if (current->thread.pfm_ovfl_block_reset) pfm_ovfl_block_reset(); @@ -198,6 +207,10 @@ void ia64_save_extra (struct task_struct *task) { +#ifdef CONFIG_PERFMON + unsigned long info; +#endif + if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) ia64_save_debug_regs(&task->thread.dbr[0]); @@ -205,8 +218,9 @@ if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) pfm_save_regs(task); - if (__get_cpu_var(pfm_syst_wide)) - pfm_syst_wide_update_task(task, 0); + info = __get_cpu_var(pfm_syst_info); + if (info & PFM_CPUINFO_SYST_WIDE) + pfm_syst_wide_update_task(task, info, 0); #endif #ifdef CONFIG_IA32_SUPPORT @@ -218,6 +232,10 @@ void ia64_load_extra (struct task_struct *task) { +#ifdef CONFIG_PERFMON + unsigned long info; +#endif + if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) ia64_load_debug_regs(&task->thread.dbr[0]); @@ -225,8 +243,9 @@ if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) pfm_load_regs(task); - if (__get_cpu_var(pfm_syst_wide)) - pfm_syst_wide_update_task(task, 1); + info = __get_cpu_var(pfm_syst_info); + if (info & PFM_CPUINFO_SYST_WIDE) + pfm_syst_wide_update_task(task, info, 1); #endif #ifdef CONFIG_IA32_SUPPORT diff -Nru a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c --- a/arch/ia64/kernel/ptrace.c Sun Feb 9 21:13:37 2003 +++ b/arch/ia64/kernel/ptrace.c Sun Feb 9 21:13:37 2003 @@ -833,21 +833,19 @@ return -1; } #ifdef CONFIG_PERFMON - /* - * Check if debug registers are used - * by perfmon. This test must be done once we know that we can - * do the operation, i.e. the arguments are all valid, but before - * we start modifying the state. + /* + * Check if debug registers are used by perfmon. This test must be done + * once we know that we can do the operation, i.e. the arguments are all + * valid, but before we start modifying the state. * - * Perfmon needs to keep a count of how many processes are - * trying to modify the debug registers for system wide monitoring - * sessions. + * Perfmon needs to keep a count of how many processes are trying to + * modify the debug registers for system wide monitoring sessions. * - * We also include read access here, because they may cause - * the PMU-installed debug register state (dbr[], ibr[]) to - * be reset. The two arrays are also used by perfmon, but - * we do not use IA64_THREAD_DBG_VALID. The registers are restored - * by the PMU context switch code. + * We also include read access here, because they may cause the + * PMU-installed debug register state (dbr[], ibr[]) to be reset. The two + * arrays are also used by perfmon, but we do not use + * IA64_THREAD_DBG_VALID. The registers are restored by the PMU context + * switch code. */ if (pfm_use_debug_registers(child)) return -1; #endif diff -Nru a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c --- a/arch/ia64/kernel/sal.c Sun Feb 9 21:13:36 2003 +++ b/arch/ia64/kernel/sal.c Sun Feb 9 21:13:36 2003 @@ -1,7 +1,7 @@ /* * System Abstraction Layer (SAL) interface routines. * - * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co + * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co * David Mosberger-Tang * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999 Walt Drummond @@ -96,17 +96,17 @@ int i; if (!systab) { - printk("Hmm, no SAL System Table.\n"); + printk(KERN_WARNING "Hmm, no SAL System Table.\n"); return; } if (strncmp(systab->signature, "SST_", 4) != 0) - printk("bad signature in system table!"); + printk(KERN_ERR "bad signature in system table!"); /* * revisions are coded in BCD, so %x does the job for us */ - printk("SAL v%x.%02x: oem=%.32s, product=%.32s\n", + printk(KERN_INFO "SAL v%x.%02x: oem=%.32s, product=%.32s\n", systab->sal_rev_major, systab->sal_rev_minor, systab->oem_id, systab->product_id); @@ -121,7 +121,7 @@ switch (*p) { case SAL_DESC_ENTRY_POINT: ep = (struct ia64_sal_desc_entry_point *) p; - printk("SAL: entry: pal_proc=0x%lx, sal_proc=0x%lx\n", + printk(KERN_INFO "SAL: entry: pal_proc=0x%lx, sal_proc=0x%lx\n", ep->pal_proc, ep->sal_proc); ia64_pal_handler_init(__va(ep->pal_proc)); ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp)); @@ -139,12 +139,12 @@ switch (ap->mechanism) { case IA64_SAL_AP_EXTERNAL_INT: ap_wakeup_vector = ap->vector; - printk("SAL: AP wakeup using external interrupt " + printk(KERN_INFO "SAL: AP wakeup using external interrupt " "vector 0x%lx\n", ap_wakeup_vector); break; default: - printk("SAL: AP wakeup mechanism unsupported!\n"); + printk(KERN_ERR "SAL: AP wakeup mechanism unsupported!\n"); break; } break; @@ -154,7 +154,7 @@ { struct ia64_sal_desc_platform_feature *pf = (void *) p; sal_platform_features = pf->feature_mask; - printk("SAL: Platform features "); + printk(KERN_INFO "SAL: Platform features "); if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_BUS_LOCK) printk("BusLock "); diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c --- a/arch/ia64/kernel/setup.c Sun Feb 9 21:13:29 2003 +++ b/arch/ia64/kernel/setup.c Sun Feb 9 21:13:29 2003 @@ -1,7 +1,7 @@ /* * Architecture-specific setup. * - * Copyright (C) 1998-2001 Hewlett-Packard Co + * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co * David Mosberger-Tang * Stephane Eranian * Copyright (C) 2000, Rohit Seth @@ -171,7 +171,7 @@ #if IGNORE_PFN0 if (start == PAGE_OFFSET) { - printk("warning: skipping physical page 0\n"); + printk(KERN_WARNING "warning: skipping physical page 0\n"); start += PAGE_SIZE; if (start >= end) return 0; } @@ -341,7 +341,7 @@ initrd_start = (unsigned long)__va(ia64_boot_param->initrd_start); initrd_end = initrd_start+ia64_boot_param->initrd_size; - printk("Initial ramdisk at: 0x%lx (%lu bytes)\n", + printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n", initrd_start, ia64_boot_param->initrd_size); } #endif @@ -409,8 +409,9 @@ ia64_set_kr(IA64_KR_IO_BASE, phys_iobase); else { phys_iobase = ia64_get_kr(IA64_KR_IO_BASE); - printk("No I/O port range found in EFI memory map, falling back to AR.KR0\n"); - printk("I/O port base = 0x%lx\n", phys_iobase); + printk(KERN_INFO "No I/O port range found in EFI memory map, falling back " + "to AR.KR0\n"); + printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase); } ia64_iobase = (unsigned long) ioremap(phys_iobase, 0); @@ -615,7 +616,7 @@ impl_va_msb = vm2.pal_vm_info_2_s.impl_va_msb; phys_addr_size = vm1.pal_vm_info_1_s.phys_add_size; } - printk("CPU %d: %lu virtual and %lu physical address bits\n", + printk(KERN_INFO "CPU %d: %lu virtual and %lu physical address bits\n", smp_processor_id(), impl_va_msb + 1, phys_addr_size); c->unimpl_va_mask = ~((7L<<61) | ((1L << (impl_va_msb + 1)) - 1)); c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1)); @@ -738,7 +739,7 @@ if (ia64_pal_vm_summary(NULL, &vmi) == 0) max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1; else { - printk("cpu_init: PAL VM summary failed, assuming 18 RID bits\n"); + printk(KERN_WARNING "cpu_init: PAL VM summary failed, assuming 18 RID bits\n"); max_ctx = (1U << 15) - 1; /* use architected minimum */ } while (max_ctx < ia64_ctx.max_ctx) { @@ -748,10 +749,39 @@ } if (ia64_pal_rse_info(&num_phys_stacked, 0) != 0) { - printk ("cpu_init: PAL RSE info failed, assuming 96 physical stacked regs\n"); + printk(KERN_WARNING "cpu_init: PAL RSE info failed; assuming 96 physical " + "stacked regs\n"); num_phys_stacked = 96; } /* size of physical stacked register partition plus 8 bytes: */ __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8; platform_cpu_init(); +} + +void +check_bugs (void) +{ + extern int __start___mckinley_e9_bundles[]; + extern int __end___mckinley_e9_bundles[]; + u64 *bundle; + int *wp; + + if (local_cpu_data->family == 0x1f && local_cpu_data->model == 0) + printk(KERN_INFO "check_bugs: leaving McKinley Errata 9 workaround enabled\n"); + else { + printk(KERN_INFO "check_bugs: McKinley Errata 9 workaround not needed; " + "disabling it\n"); + for (wp = __start___mckinley_e9_bundles; wp < __end___mckinley_e9_bundles; ++wp) { + bundle = (u64 *) ((char *) wp + *wp); + /* install a bundle of NOPs: */ + bundle[0] = 0x0000000100000000; + bundle[1] = 0x0004000000000200; + ia64_fc(bundle); + } + ia64_insn_group_barrier(); + ia64_sync_i(); + ia64_insn_group_barrier(); + ia64_srlz_i(); + ia64_insn_group_barrier(); + } } diff -Nru a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c --- a/arch/ia64/kernel/signal.c Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/kernel/signal.c Sun Feb 9 21:13:32 2003 @@ -68,13 +68,13 @@ sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); { oldset = current->blocked; current->blocked = set; recalc_sigpending(); } - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); /* * The return below usually returns to the signal handler. We need to @@ -274,12 +274,12 @@ sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); { current->blocked = set; recalc_sigpending(); } - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(sc, scr)) goto give_sigsegv; @@ -465,13 +465,13 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); { sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); sigaddset(¤t->blocked, sig); recalc_sigpending(); } - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } return 1; } diff -Nru a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c --- a/arch/ia64/kernel/smpboot.c Sun Feb 9 21:13:29 2003 +++ b/arch/ia64/kernel/smpboot.c Sun Feb 9 21:13:29 2003 @@ -1,7 +1,7 @@ /* * SMP boot-related support * - * Copyright (C) 1998-2002 Hewlett-Packard Co + * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang * * 01/05/16 Rohit Seth Moved SMP booting functions from smp.c to here. @@ -204,7 +204,7 @@ go[MASTER] = 1; if (smp_call_function_single(master, sync_master, NULL, 1, 0) < 0) { - printk("sync_itc: failed to get attention of CPU %u!\n", master); + printk(KERN_ERR "sync_itc: failed to get attention of CPU %u!\n", master); return; } @@ -244,8 +244,8 @@ t[i].rt, t[i].master, t[i].diff, t[i].lat); #endif - printk("CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, maxerr %lu cycles)\n", - smp_processor_id(), master, delta, rt); + printk(KERN_INFO "CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, " + "maxerr %lu cycles)\n", smp_processor_id(), master, delta, rt); } /* @@ -265,14 +265,15 @@ extern void ia64_init_itm(void); #ifdef CONFIG_PERFMON - extern void perfmon_init_percpu(void); + extern void pfm_init_percpu(void); #endif cpuid = smp_processor_id(); phys_id = hard_smp_processor_id(); if (test_and_set_bit(cpuid, &cpu_online_map)) { - printk("huh, phys CPU#0x%x, CPU#0x%x already present??\n", phys_id, cpuid); + printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n", + phys_id, cpuid); BUG(); } @@ -300,7 +301,7 @@ #endif #ifdef CONFIG_PERFMON - perfmon_init_percpu(); + pfm_init_percpu(); #endif local_irq_enable(); @@ -380,9 +381,7 @@ if (test_bit(cpu, &cpu_callin_map)) { /* number CPUs logically, starting from 1 (BSP is 0) */ - printk("CPU%d: ", cpu); - /*print_cpu_info(&cpu_data[cpu]); */ - printk("CPU has booted.\n"); + printk(KERN_INFO "CPU%d: CPU has booted.\n", cpu); } else { printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid); ia64_cpu_to_sapicid[cpu] = -1; @@ -399,7 +398,7 @@ { cache_decay_ticks = 10; /* XXX base this on PAL info and cache-bandwidth estimate */ - printk("task migration cache decay timeout: %ld msecs.\n", + printk(KERN_INFO "task migration cache decay timeout: %ld msecs.\n", (cache_decay_ticks + 1) * 1000 / HZ); } @@ -491,7 +490,7 @@ local_cpu_data->loops_per_jiffy = loops_per_jiffy; ia64_cpu_to_sapicid[0] = boot_cpu_id; - printk("Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id); + printk(KERN_INFO "Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id); current_thread_info()->cpu = 0; smp_tune_scheduling(); @@ -526,7 +525,7 @@ if (cpu_online(cpu)) bogosum += cpu_data(cpu)->loops_per_jiffy; - printk(KERN_INFO"Total of %d processors activated (%lu.%02lu BogoMIPS).\n", + printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100); } @@ -552,7 +551,7 @@ } /* - * Assume that CPU's have been discovered by some platform-dependant interface. For + * Assume that CPU's have been discovered by some platform-dependent interface. For * SoftSDV/Lion, that would be ACPI. * * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP(). @@ -571,5 +570,6 @@ sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ, __pa(ap_startup->fp), __pa(ap_startup->gp), 0, 0, 0, 0); if (sal_ret < 0) - printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n", ia64_sal_strerror(sal_ret)); + printk(KERN_ERR "SMP: Can't set SAL AP Boot Rendezvous: %s\n", + ia64_sal_strerror(sal_ret)); } diff -Nru a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c --- a/arch/ia64/kernel/sys_ia64.c Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/kernel/sys_ia64.c Sun Feb 9 21:13:32 2003 @@ -16,11 +16,11 @@ #include #include #include +#include #include #include - unsigned long arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) @@ -31,6 +31,20 @@ if (len > RGN_MAP_LIMIT) return -ENOMEM; + +#ifdef CONFIG_HUGETLB_PAGE +#define COLOR_HALIGN(addr) ((addr + HPAGE_SIZE - 1) & ~(HPAGE_SIZE - 1)) +#define TASK_HPAGE_BASE ((REGION_HPAGE << REGION_SHIFT) | HPAGE_SIZE) + if (filp && is_file_hugepages(filp)) { + if ((REGION_NUMBER(addr) != REGION_HPAGE) || (addr & (HPAGE_SIZE -1))) + addr = TASK_HPAGE_BASE; + addr = COLOR_HALIGN(addr); + } + else { + if (REGION_NUMBER(addr) == REGION_HPAGE) + addr = 0; + } +#endif if (!addr) addr = TASK_UNMAPPED_BASE; diff -Nru a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c --- a/arch/ia64/kernel/time.c Sun Feb 9 21:13:29 2003 +++ b/arch/ia64/kernel/time.c Sun Feb 9 21:13:29 2003 @@ -1,7 +1,7 @@ /* * linux/arch/ia64/kernel/time.c * - * Copyright (C) 1998-2002 Hewlett-Packard Co + * Copyright (C) 1998-2003 Hewlett-Packard Co * Stephane Eranian * David Mosberger * Copyright (C) 1999 Don Dugger @@ -24,7 +24,6 @@ #include #include -extern rwlock_t xtime_lock; extern unsigned long wall_jiffies; extern unsigned long last_time_offset; @@ -76,10 +75,8 @@ now = ia64_get_itc(); if ((long) (now - last_tick) < 0) { -# if 1 - printk("CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n", + printk(KERN_ERR "CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n", smp_processor_id(), now, last_tick); -# endif return last_time_offset; } elapsed_cycles = now - last_tick; @@ -89,7 +86,7 @@ void do_settimeofday (struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); { /* * This is revolting. We need to set "xtime" correctly. However, the value @@ -112,21 +109,21 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; } - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } void do_gettimeofday (struct timeval *tv) { - unsigned long flags, usec, sec, old; + unsigned long seq, usec, sec, old; - read_lock_irqsave(&xtime_lock, flags); - { + do { + seq = read_seqbegin(&xtime_lock); usec = gettimeoffset(); /* - * Ensure time never goes backwards, even when ITC on different CPUs are - * not perfectly synchronized. + * Ensure time never goes backwards, even when ITC on + * different CPUs are not perfectly synchronized. */ do { old = last_time_offset; @@ -138,8 +135,8 @@ sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; - } - read_unlock_irqrestore(&xtime_lock, flags); + } while (read_seqend(&xtime_lock, seq)); + while (usec >= 1000000) { usec -= 1000000; @@ -158,7 +155,7 @@ new_itm = local_cpu_data->itm_next; if (!time_after(ia64_get_itc(), new_itm)) - printk("Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", + printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n", ia64_get_itc(), new_itm); while (1) { @@ -182,10 +179,10 @@ * another CPU. We need to avoid to SMP race by acquiring the * xtime_lock. */ - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); do_timer(regs); local_cpu_data->itm_next = new_itm; - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } else local_cpu_data->itm_next = new_itm; @@ -247,21 +244,22 @@ */ status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, &platform_base_freq, &drift); if (status != 0) { - printk("SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status)); + printk(KERN_ERR "SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status)); } else { status = ia64_pal_freq_ratios(&proc_ratio, 0, &itc_ratio); if (status != 0) - printk("PAL_FREQ_RATIOS failed with status=%ld\n", status); + printk(KERN_ERR "PAL_FREQ_RATIOS failed with status=%ld\n", status); } if (status != 0) { /* invent "random" values */ - printk("SAL/PAL failed to obtain frequency info---inventing reasonably values\n"); + printk(KERN_ERR + "SAL/PAL failed to obtain frequency info---inventing reasonably values\n"); platform_base_freq = 100000000; itc_ratio.num = 3; itc_ratio.den = 1; } if (platform_base_freq < 40000000) { - printk("Platform base frequency %lu bogus---resetting to 75MHz!\n", + printk(KERN_ERR "Platform base frequency %lu bogus---resetting to 75MHz!\n", platform_base_freq); platform_base_freq = 75000000; } @@ -272,8 +270,8 @@ itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den; local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ; - printk("CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, ITC freq=%lu.%03luMHz\n", - smp_processor_id(), + printk(KERN_INFO "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, " + "ITC freq=%lu.%03luMHz\n", smp_processor_id(), platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000, itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000); diff -Nru a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c --- a/arch/ia64/kernel/traps.c Sun Feb 9 21:13:36 2003 +++ b/arch/ia64/kernel/traps.c Sun Feb 9 21:13:36 2003 @@ -1,7 +1,7 @@ /* * Architecture-specific trap handling. * - * Copyright (C) 1998-2002 Hewlett-Packard Co + * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang * * 05/12/00 grao : added isr in siginfo for SIGFPE @@ -57,7 +57,8 @@ major = fpswa_interface->revision >> 16; minor = fpswa_interface->revision & 0xffff; } - printk("fpswa interface at %lx (rev %d.%d)\n", ia64_boot_param->fpswa, major, minor); + printk(KERN_INFO "fpswa interface at %lx (rev %d.%d)\n", + ia64_boot_param->fpswa, major, minor); } /* @@ -142,7 +143,7 @@ switch (break_num) { case 0: /* unknown error (used by GCC for __builtin_abort()) */ - die_if_kernel("bad break", regs, break_num); + die_if_kernel("bugcheck!", regs, break_num); sig = SIGILL; code = ILL_ILLOPC; break; @@ -222,7 +223,7 @@ { struct pt_regs *regs = (struct pt_regs *) &stack; - printk("%s(%d): \n", current->comm, current->pid, + printk(KERN_DEBUG "%s(%d): \n", current->comm, current->pid, regs->r15, arg0, arg1, arg2, arg3); return -ENOSYS; } @@ -346,7 +347,7 @@ /* emulation was successful */ ia64_increment_ip(regs); } else if (exception == -1) { - printk("handle_fpu_swa: fp_emulate() returned -1\n"); + printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n"); return -1; } else { /* is next instruction a trap? */ @@ -369,7 +370,7 @@ } } else { if (exception == -1) { - printk("handle_fpu_swa: fp_emulate() returned -1\n"); + printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n"); return -1; } else if (exception != 0) { /* raise exception */ @@ -467,7 +468,9 @@ ? " (RSE access)" : " (data access)") : ""); if (code == 8) { # ifdef CONFIG_IA64_PRINT_HAZARDS - printk("%016lx:possible hazard, pr = %016lx\n", regs->cr_iip, regs->pr); + printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n", + current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, + regs->pr); # endif return; } @@ -524,6 +527,25 @@ case 29: /* Debug */ case 35: /* Taken Branch Trap */ case 36: /* Single Step Trap */ +#ifdef CONFIG_FSYS + if (fsys_mode(current, regs)) { + extern char syscall_via_break[], __start_gate_section[]; + /* + * Got a trap in fsys-mode: Taken Branch Trap and Single Step trap + * need special handling; Debug trap is not supposed to happen. + */ + if (unlikely(vector == 29)) { + die("Got debug trap in fsys-mode---not supposed to happen!", + regs, 0); + return; + } + /* re-do the system call via break 0x100000: */ + regs->cr_iip = GATE_ADDR + (syscall_via_break - __start_gate_section); + ia64_psr(regs)->ri = 0; + ia64_psr(regs)->cpl = 3; + return; + } +#endif switch (vector) { case 29: siginfo.si_code = TRAP_HWBKPT; @@ -563,19 +585,31 @@ } return; - case 34: /* Unimplemented Instruction Address Trap */ - if (user_mode(regs)) { - siginfo.si_signo = SIGILL; - siginfo.si_code = ILL_BADIADDR; - siginfo.si_errno = 0; - siginfo.si_flags = 0; - siginfo.si_isr = 0; - siginfo.si_imm = 0; - siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri); - force_sig_info(SIGILL, &siginfo, current); + case 34: + if (isr & 0x2) { + /* Lower-Privilege Transfer Trap */ + /* + * Just clear PSR.lp and then return immediately: all the + * interesting work (e.g., signal delivery is done in the kernel + * exit path). + */ + ia64_psr(regs)->lp = 0; return; + } else { + /* Unimplemented Instr. Address Trap */ + if (user_mode(regs)) { + siginfo.si_signo = SIGILL; + siginfo.si_code = ILL_BADIADDR; + siginfo.si_errno = 0; + siginfo.si_flags = 0; + siginfo.si_isr = 0; + siginfo.si_imm = 0; + siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri); + force_sig_info(SIGILL, &siginfo, current); + return; + } + sprintf(buf, "Unimplemented Instruction Address fault"); } - sprintf(buf, "Unimplemented Instruction Address fault"); break; case 45: @@ -583,8 +617,9 @@ if (ia32_exception(regs, isr) == 0) return; #endif - printk("Unexpected IA-32 exception (Trap 45)\n"); - printk(" iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", regs->cr_iip, ifa, isr); + printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n"); + printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", + regs->cr_iip, ifa, isr); force_sig(SIGSEGV, current); break; @@ -593,8 +628,8 @@ if (ia32_intercept(regs, isr) == 0) return; #endif - printk("Unexpected IA-32 intercept trap (Trap 46)\n"); - printk(" iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n", + printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n"); + printk(KERN_ERR " iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n", regs->cr_iip, ifa, isr, iim); force_sig(SIGSEGV, current); return; diff -Nru a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c --- a/arch/ia64/kernel/unaligned.c Sun Feb 9 21:13:36 2003 +++ b/arch/ia64/kernel/unaligned.c Sun Feb 9 21:13:36 2003 @@ -331,12 +331,8 @@ return; } - /* - * Avoid using user_mode() here: with "epc", we cannot use the privilege level to - * infer whether the interrupt task was running on the kernel backing store. - */ - if (regs->r12 >= TASK_SIZE) { - DPRINT("ignoring kernel write to r%lu; register isn't on the RBS!", r1); + if (!user_stack(current, regs)) { + DPRINT("ignoring kernel write to r%lu; register isn't on the kernel RBS!", r1); return; } @@ -406,11 +402,7 @@ return; } - /* - * Avoid using user_mode() here: with "epc", we cannot use the privilege level to - * infer whether the interrupt task was running on the kernel backing store. - */ - if (regs->r12 >= TASK_SIZE) { + if (!user_stack(current, regs)) { DPRINT("ignoring kernel read of r%lu; register isn't on the RBS!", r1); goto fail; } @@ -1302,12 +1294,12 @@ void ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) { - struct exception_fixup fix = { 0 }; struct ia64_psr *ipsr = ia64_psr(regs); mm_segment_t old_fs = get_fs(); unsigned long bundle[2]; unsigned long opcode; struct siginfo si; + const struct exception_table_entry *eh = NULL; union { unsigned long l; load_store_t insn; @@ -1325,10 +1317,9 @@ * user-level unaligned accesses. Otherwise, a clever program could trick this * handler into reading an arbitrary kernel addresses... */ - if (!user_mode(regs)) { - fix = SEARCH_EXCEPTION_TABLE(regs); - } - if (user_mode(regs) || fix.cont) { + if (!user_mode(regs)) + eh = SEARCH_EXCEPTION_TABLE(regs); + if (user_mode(regs) || eh) { if ((current->thread.flags & IA64_THREAD_UAC_SIGBUS) != 0) goto force_sigbus; @@ -1494,8 +1485,8 @@ failure: /* something went wrong... */ if (!user_mode(regs)) { - if (fix.cont) { - handle_exception(regs, fix); + if (eh) { + handle_exception(regs, eh); goto done; } die_if_kernel("error during unaligned kernel access\n", regs, ret); diff -Nru a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c --- a/arch/ia64/kernel/unwind.c Sun Feb 9 21:13:37 2003 +++ b/arch/ia64/kernel/unwind.c Sun Feb 9 21:13:37 2003 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1999-2002 Hewlett-Packard Co + * Copyright (C) 1999-2003 Hewlett-Packard Co * David Mosberger-Tang */ /* @@ -532,7 +532,7 @@ rs = alloc_reg_state(); if (!rs) { - printk("unwind: cannot stack reg state!\n"); + printk(KERN_ERR "unwind: cannot stack reg state!\n"); return; } memcpy(rs, &sr->curr, sizeof(*rs)); @@ -545,7 +545,7 @@ struct unw_reg_state *rs = sr->curr.next; if (!rs) { - printk("unwind: stack underflow!\n"); + printk(KERN_ERR "unwind: stack underflow!\n"); return; } memcpy(&sr->curr, rs, sizeof(*rs)); @@ -561,7 +561,7 @@ while (rs) { copy = alloc_reg_state(); if (!copy) { - printk ("unwind.dup_state_stack: out of memory\n"); + printk(KERN_ERR "unwind.dup_state_stack: out of memory\n"); return NULL; } memcpy(copy, rs, sizeof(*copy)); @@ -951,7 +951,7 @@ return; } } - printk("unwind: failed to find state labeled 0x%lx\n", label); + printk(KERN_ERR "unwind: failed to find state labeled 0x%lx\n", label); } static inline void @@ -961,7 +961,7 @@ ls = alloc_labeled_state(); if (!ls) { - printk("unwind.desc_label_state(): out of memory\n"); + printk(KERN_ERR "unwind.desc_label_state(): out of memory\n"); return; } ls->label = label; @@ -1055,7 +1055,8 @@ r->val = 4*spoff; } -#define UNW_DEC_BAD_CODE(code) printk("unwind: unknown code 0x%02x\n", code); +#define UNW_DEC_BAD_CODE(code) printk(KERN_ERR "unwind: unknown code 0x%02x\n", \ + code); /* * region headers: @@ -1997,23 +1998,25 @@ { extern char __start_gate_section[], __stop_gate_section[]; unsigned long *lp, start, end, segbase = unw.kernel_table.segment_base; - const struct unw_table_entry *entry, *first; + const struct unw_table_entry *entry, *first, *unw_table_end; + extern int ia64_unw_end; size_t info_size, size; char *info; start = (unsigned long) __start_gate_section - segbase; end = (unsigned long) __stop_gate_section - segbase; + unw_table_end = (struct unw_table_entry *) &ia64_unw_end; size = 0; first = lookup(&unw.kernel_table, start); - for (entry = first; entry->start_offset < end; ++entry) + for (entry = first; entry < unw_table_end && entry->start_offset < end; ++entry) size += 3*8 + 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset)); size += 8; /* reserve space for "end of table" marker */ unw.gate_table = alloc_bootmem(size); if (!unw.gate_table) { unw.gate_table_size = 0; - printk("unwind: unable to create unwind data for gate page!\n"); + printk(KERN_ERR "unwind: unable to create unwind data for gate page!\n"); return; } unw.gate_table_size = size; @@ -2021,7 +2024,7 @@ lp = unw.gate_table; info = (char *) unw.gate_table + size; - for (entry = first; entry->start_offset < end; ++entry, lp += 3) { + for (entry = first; entry < unw_table_end && entry->start_offset < end; ++entry, lp += 3) { info_size = 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset)); info -= info_size; memcpy(info, (char *) segbase + entry->info_offset, info_size); diff -Nru a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile --- a/arch/ia64/lib/Makefile Sun Feb 9 21:13:36 2003 +++ b/arch/ia64/lib/Makefile Sun Feb 9 21:13:36 2003 @@ -4,8 +4,6 @@ L_TARGET = lib.a -export-objs := swiotlb.o - obj-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \ checksum.o clear_page.o csum_partial_copy.o copy_page.o \ diff -Nru a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S --- a/arch/ia64/lib/memcpy_mck.S Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/lib/memcpy_mck.S Sun Feb 9 21:13:32 2003 @@ -159,7 +159,7 @@ mov ar.ec=2 (p10) br.dpnt.few .aligned_src_tail ;; - .align 32 +// .align 32 1: EX(.ex_handler, (p16) ld8 r34=[src0],16) EK(.ex_handler, (p16) ld8 r38=[src1],16) @@ -316,7 +316,7 @@ (p7) mov ar.lc = r21 (p8) mov ar.lc = r0 ;; - .align 32 +// .align 32 1: lfetch.fault [src_pre_mem], 128 lfetch.fault.excl [dst_pre_mem], 128 br.cloop.dptk.few 1b @@ -522,7 +522,7 @@ shrp r21=r22,r38,shift; /* speculative work */ \ br.sptk.few .unaligned_src_tail /* branch out of jump table */ \ ;; - .align 32 +// .align 32 .jump_table: COPYU(8) // unaligned cases .jmp1: diff -Nru a/arch/ia64/lib/memset.S b/arch/ia64/lib/memset.S --- a/arch/ia64/lib/memset.S Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/lib/memset.S Sun Feb 9 21:13:32 2003 @@ -125,7 +125,7 @@ (p_zr) br.cond.dptk.many .l1b // Jump to use stf.spill ;; } - .align 32 // -------------------------- // L1A: store ahead into cache lines; fill later +// .align 32 // -------------------------- // L1A: store ahead into cache lines; fill later { .mmi and tmp = -(LINE_SIZE), cnt // compute end of range mov ptr9 = ptr1 // used for prefetching @@ -194,7 +194,7 @@ br.cond.dpnt.many .move_bytes_from_alignment // Branch no. 3 ;; } - .align 32 +// .align 32 .l1b: // ------------------------------------ // L1B: store ahead into cache lines; fill later { .mmi and tmp = -(LINE_SIZE), cnt // compute end of range @@ -261,7 +261,7 @@ and cnt = 0x1f, cnt // compute the remaining cnt mov.i ar.lc = loopcnt ;; } - .align 32 +// .align 32 .l2: // ------------------------------------ // L2A: store 32B in 2 cycles { .mmb stf8 [ptr1] = fvalue, 8 diff -Nru a/arch/ia64/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c --- a/arch/ia64/lib/swiotlb.c Sun Feb 9 21:13:34 2003 +++ b/arch/ia64/lib/swiotlb.c Sun Feb 9 21:13:34 2003 @@ -113,7 +113,7 @@ io_tlb_index = 0; io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *)); - printk("Placing software IO TLB between 0x%p - 0x%p\n", + printk(KERN_INFO "Placing software IO TLB between 0x%p - 0x%p\n", (void *) io_tlb_start, (void *) io_tlb_end); } diff -Nru a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c --- a/arch/ia64/mm/discontig.c Sun Feb 9 21:13:35 2003 +++ b/arch/ia64/mm/discontig.c Sun Feb 9 21:13:35 2003 @@ -215,7 +215,7 @@ int node; if (numnodes == 0) { - printk("node info missing!\n"); + printk(KERN_ERR "node info missing!\n"); numnodes = 1; } diff -Nru a/arch/ia64/mm/extable.c b/arch/ia64/mm/extable.c --- a/arch/ia64/mm/extable.c Sun Feb 9 21:13:30 2003 +++ b/arch/ia64/mm/extable.c Sun Feb 9 21:13:30 2003 @@ -10,20 +10,19 @@ #include #include -extern const struct exception_table_entry __start___ex_table[]; -extern const struct exception_table_entry __stop___ex_table[]; - -static inline const struct exception_table_entry * -search_one_table (const struct exception_table_entry *first, - const struct exception_table_entry *last, - unsigned long ip, unsigned long gp) +const struct exception_table_entry * +search_extable (const struct exception_table_entry *first, + const struct exception_table_entry *last, + unsigned long ip) { - while (first <= last) { - const struct exception_table_entry *mid; - long diff; + const struct exception_table_entry *mid; + unsigned long mid_ip; + long diff; + while (first <= last) { mid = &first[(last - first)/2]; - diff = (mid->addr + gp) - ip; + mid_ip = (u64) &mid->addr + mid->addr; + diff = mid_ip - ip; if (diff == 0) return mid; else if (diff < 0) @@ -34,50 +33,14 @@ return 0; } -#ifndef CONFIG_MODULES -register unsigned long main_gp __asm__("gp"); -#endif - -struct exception_fixup -search_exception_table (unsigned long addr) -{ - const struct exception_table_entry *entry; - struct exception_fixup fix = { 0 }; - -#ifndef CONFIG_MODULES - /* There is only the kernel to search. */ - entry = search_one_table(__start___ex_table, __stop___ex_table - 1, addr, main_gp); - if (entry) - fix.cont = entry->cont + main_gp; - return fix; -#else - struct archdata *archdata; - struct module *mp; - - /* The kernel is the last "module" -- no need to treat it special. */ - for (mp = module_list; mp; mp = mp->next) { - if (!mp->ex_table_start) - continue; - archdata = (struct archdata *) mp->archdata_start; - if (!archdata) - continue; - entry = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, - addr, (unsigned long) archdata->gp); - if (entry) { - fix.cont = entry->cont + (unsigned long) archdata->gp; - return fix; - } - } -#endif - return fix; -} - void -handle_exception (struct pt_regs *regs, struct exception_fixup fix) +handle_exception (struct pt_regs *regs, const struct exception_table_entry *e) { + long fix = (u64) &e->cont + e->cont; + regs->r8 = -EFAULT; - if (fix.cont & 4) + if (fix & 4) regs->r9 = 0; - regs->cr_iip = (long) fix.cont & ~0xf; - ia64_psr(regs)->ri = fix.cont & 0x3; /* set continuation slot number */ + regs->cr_iip = fix & ~0xf; + ia64_psr(regs)->ri = fix & 0x3; /* set continuation slot number */ } diff -Nru a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c --- a/arch/ia64/mm/fault.c Sun Feb 9 21:13:36 2003 +++ b/arch/ia64/mm/fault.c Sun Feb 9 21:13:36 2003 @@ -196,7 +196,7 @@ yield(); goto survive; } - printk("VM: killing process %s\n", current->comm); + printk(KERN_CRIT "VM: killing process %s\n", current->comm); if (user_mode(regs)) do_exit(SIGKILL); goto no_context; diff -Nru a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c --- a/arch/ia64/mm/hugetlbpage.c Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/mm/hugetlbpage.c Sun Feb 9 21:13:32 2003 @@ -12,71 +12,41 @@ #include #include #include - #include #include #include #include -static struct vm_operations_struct hugetlb_vm_ops; -struct list_head htlbpage_freelist; -spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED; -extern long htlbpagemem; +#include + +static long htlbpagemem; +int htlbpage_max; +static long htlbzone_pages; -static void zap_hugetlb_resources (struct vm_area_struct *); +static LIST_HEAD(htlbpage_freelist); +static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED; -static struct page * -alloc_hugetlb_page (void) +static struct page *alloc_hugetlb_page(void) { - struct list_head *curr, *head; + int i; struct page *page; spin_lock(&htlbpage_lock); - - head = &htlbpage_freelist; - curr = head->next; - - if (curr == head) { + if (list_empty(&htlbpage_freelist)) { spin_unlock(&htlbpage_lock); return NULL; } - page = list_entry(curr, struct page, list); - list_del(curr); + + page = list_entry(htlbpage_freelist.next, struct page, list); + list_del(&page->list); htlbpagemem--; spin_unlock(&htlbpage_lock); set_page_count(page, 1); - memset(page_address(page), 0, HPAGE_SIZE); + for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i) + clear_highpage(&page[i]); return page; } -static void -free_hugetlb_page (struct page *page) -{ - spin_lock(&htlbpage_lock); - if ((page->mapping != NULL) && (page_count(page) == 2)) { - struct inode *inode = page->mapping->host; - int i; - - ClearPageDirty(page); - remove_from_page_cache(page); - set_page_count(page, 1); - if ((inode->i_size -= HPAGE_SIZE) == 0) { - for (i = 0; i < MAX_ID; i++) - if (htlbpagek[i].key == inode->i_ino) { - htlbpagek[i].key = 0; - htlbpagek[i].in = NULL; - break; - } - kfree(inode); - } - } - if (put_page_testzero(page)) { - list_add(&page->list, &htlbpage_freelist); - htlbpagemem++; - } - spin_unlock(&htlbpage_lock); -} - static pte_t * huge_pte_alloc (struct mm_struct *mm, unsigned long addr) { @@ -126,63 +96,8 @@ return; } -static int -anon_get_hugetlb_page (struct mm_struct *mm, struct vm_area_struct *vma, - int write_access, pte_t * page_table) -{ - struct page *page; - - page = alloc_hugetlb_page(); - if (page == NULL) - return -1; - set_huge_pte(mm, vma, page, page_table, write_access); - return 1; -} - -static int -make_hugetlb_pages_present (unsigned long addr, unsigned long end, int flags) -{ - int write; - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; - pte_t *pte; - - vma = find_vma(mm, addr); - if (!vma) - goto out_error1; - - write = (vma->vm_flags & VM_WRITE) != 0; - if ((vma->vm_end - vma->vm_start) & (HPAGE_SIZE - 1)) - goto out_error1; - spin_lock(&mm->page_table_lock); - do { - pte = huge_pte_alloc(mm, addr); - if ((pte) && (pte_none(*pte))) { - if (anon_get_hugetlb_page(mm, vma, write ? VM_WRITE : VM_READ, pte) == -1) - goto out_error; - } else - goto out_error; - addr += HPAGE_SIZE; - } while (addr < end); - spin_unlock(&mm->page_table_lock); - vma->vm_flags |= (VM_HUGETLB | VM_RESERVED); - if (flags & MAP_PRIVATE) - vma->vm_flags |= VM_DONTCOPY; - vma->vm_ops = &hugetlb_vm_ops; - return 0; -out_error: - if (addr > vma->vm_start) { - vma->vm_end = addr; - zap_hugetlb_resources(vma); - vma->vm_end = end; - } - spin_unlock(&mm->page_table_lock); -out_error1: - return -1; -} - -int -copy_hugetlb_page_range (struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma) +int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, + struct vm_area_struct *vma) { pte_t *src_pte, *dst_pte, entry; struct page *ptepage; @@ -202,15 +117,14 @@ addr += HPAGE_SIZE; } return 0; - - nomem: +nomem: return -ENOMEM; } int -follow_hugetlb_page (struct mm_struct *mm, struct vm_area_struct *vma, - struct page **pages, struct vm_area_struct **vmas, - unsigned long *st, int *length, int i) +follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, + struct page **pages, struct vm_area_struct **vmas, + unsigned long *st, int *length, int i) { pte_t *ptep, pte; unsigned long start = *st; @@ -227,6 +141,7 @@ page = pte_page(pte); if (pages) { page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT); + get_page(page); pages[i] = page; } if (vmas) @@ -234,8 +149,8 @@ i++; len--; start += PAGE_SIZE; - if (((start & HPAGE_MASK) == pstart) && len - && (start < vma->vm_end)) + if (((start & HPAGE_MASK) == pstart) && len && + (start < vma->vm_end)) goto back1; } while (len && start < vma->vm_end); *length = len; @@ -243,51 +158,149 @@ return i; } -static void -zap_hugetlb_resources (struct vm_area_struct *mpnt) +void free_huge_page(struct page *page) { - struct mm_struct *mm = mpnt->vm_mm; - unsigned long len, addr, end; - pte_t *ptep; + BUG_ON(page_count(page)); + BUG_ON(page->mapping); + + INIT_LIST_HEAD(&page->list); + + spin_lock(&htlbpage_lock); + list_add(&page->list, &htlbpage_freelist); + htlbpagemem++; + spin_unlock(&htlbpage_lock); +} + +void huge_page_release(struct page *page) +{ + if (!put_page_testzero(page)) + return; + + free_huge_page(page); +} + +void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned long address; + pte_t *pte; struct page *page; - addr = mpnt->vm_start; - end = mpnt->vm_end; - len = end - addr; - do { - ptep = huge_pte_offset(mm, addr); - page = pte_page(*ptep); - pte_clear(ptep); - free_hugetlb_page(page); - addr += HPAGE_SIZE; - } while (addr < end); - mm->rss -= (len >> PAGE_SHIFT); - mpnt->vm_ops = NULL; - flush_tlb_range(mpnt, end - len, end); + 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); + if (pte_none(*pte)) + continue; + page = pte_page(*pte); + huge_page_release(page); + pte_clear(pte); + } + mm->rss -= (end - start) >> PAGE_SHIFT; + flush_tlb_range(vma, start, end); } -static void -unlink_vma (struct vm_area_struct *mpnt) +void zap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long length) +{ + struct mm_struct *mm = vma->vm_mm; + spin_lock(&mm->page_table_lock); + unmap_hugepage_range(vma, start, start + length); + spin_unlock(&mm->page_table_lock); +} + +int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) { struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; + unsigned long addr; + int ret = 0; + + BUG_ON(vma->vm_start & ~HPAGE_MASK); + BUG_ON(vma->vm_end & ~HPAGE_MASK); + + spin_lock(&mm->page_table_lock); + for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) { + unsigned long idx; + pte_t *pte = huge_pte_alloc(mm, addr); + struct page *page; + + if (!pte) { + ret = -ENOMEM; + goto out; + } + if (!pte_none(*pte)) + continue; - vma = mm->mmap; - if (vma == mpnt) { - mm->mmap = vma->vm_next; - } else { - while (vma->vm_next != mpnt) { - vma = vma->vm_next; + idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) + + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); + page = find_get_page(mapping, idx); + if (!page) { + page = alloc_hugetlb_page(); + if (!page) { + ret = -ENOMEM; + goto out; + } + add_to_page_cache(page, mapping, idx, GFP_ATOMIC); + unlock_page(page); } - vma->vm_next = mpnt->vm_next; + set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE); } - rb_erase(&mpnt->vm_rb, &mm->mm_rb); - mm->mmap_cache = NULL; - mm->map_count--; +out: + spin_unlock(&mm->page_table_lock); + return ret; } -int -set_hugetlb_mem_size (int count) +void update_and_free_page(struct page *page) +{ + int j; + struct page *map; + + map = page; + htlbzone_pages--; + for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) { + map->flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced | + 1 << PG_dirty | 1 << PG_active | 1 << PG_reserved | + 1 << PG_private | 1<< PG_writeback); + set_page_count(map, 0); + map++; + } + set_page_count(page, 1); + __free_pages(page, HUGETLB_PAGE_ORDER); +} + +int try_to_free_low(int count) +{ + struct list_head *p; + struct page *page, *map; + + map = NULL; + spin_lock(&htlbpage_lock); + list_for_each(p, &htlbpage_freelist) { + if (map) { + list_del(&map->list); + update_and_free_page(map); + htlbpagemem--; + map = NULL; + if (++count == 0) + break; + } + page = list_entry(p, struct page, list); + if ((page_zone(page))->name[0] != 'H') // Look for non-Highmem + map = page; + } + if (map) { + list_del(&map->list); + update_and_free_page(map); + htlbpagemem--; + count++; + } + spin_unlock(&htlbpage_lock); + return count; +} + +int set_hugetlb_mem_size(int count) { int j, lcount; struct page *page, *map; @@ -298,16 +311,14 @@ lcount = count; else lcount = count - htlbzone_pages; - if (lcount > 0) { /*Increase the mem size. */ + + if (lcount == 0) + return (int)htlbzone_pages; + if (lcount > 0) { /* Increase the mem size. */ while (lcount--) { page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER); if (page == NULL) break; - map = page; - for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) { - SetPageReserved(map); - map++; - } spin_lock(&htlbpage_lock); list_add(&page->list, &htlbpage_freelist); htlbpagemem++; @@ -316,27 +327,80 @@ } return (int) htlbzone_pages; } - /*Shrink the memory size. */ + /* Shrink the memory size. */ + lcount = try_to_free_low(lcount); while (lcount++) { page = alloc_hugetlb_page(); if (page == NULL) break; spin_lock(&htlbpage_lock); - htlbzone_pages--; + update_and_free_page(page); spin_unlock(&htlbpage_lock); - map = page; - for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) { - map->flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced | - 1 << PG_dirty | 1 << PG_active | 1 << PG_reserved | - 1 << PG_private | 1<< PG_writeback); - map++; - } - set_page_count(page, 1); - __free_pages(page, HUGETLB_PAGE_ORDER); } return (int) htlbzone_pages; } -static struct vm_operations_struct hugetlb_vm_ops = { - .close = zap_hugetlb_resources +int hugetlb_sysctl_handler(ctl_table *table, int write, struct file *file, void *buffer, size_t *length) +{ + proc_dointvec(table, write, file, buffer, length); + htlbpage_max = set_hugetlb_mem_size(htlbpage_max); + return 0; +} + +static int __init hugetlb_setup(char *s) +{ + if (sscanf(s, "%d", &htlbpage_max) <= 0) + htlbpage_max = 0; + return 1; +} +__setup("hugepages=", hugetlb_setup); + +static int __init hugetlb_init(void) +{ + int i, j; + struct page *page; + + for (i = 0; i < htlbpage_max; ++i) { + page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER); + if (!page) + break; + for (j = 0; j < HPAGE_SIZE/PAGE_SIZE; ++j) + SetPageReserved(&page[j]); + spin_lock(&htlbpage_lock); + list_add(&page->list, &htlbpage_freelist); + spin_unlock(&htlbpage_lock); + } + htlbpage_max = htlbpagemem = htlbzone_pages = i; + printk("Total HugeTLB memory allocated, %ld\n", htlbpagemem); + return 0; +} +module_init(hugetlb_init); + +int hugetlb_report_meminfo(char *buf) +{ + return sprintf(buf, + "HugePages_Total: %5lu\n" + "HugePages_Free: %5lu\n" + "Hugepagesize: %5lu kB\n", + htlbzone_pages, + htlbpagemem, + HPAGE_SIZE/1024); +} + +int is_hugepage_mem_enough(size_t size) +{ + if (size > (htlbpagemem << HPAGE_SHIFT)) + return 0; + return 1; +} + +static struct page *hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int unused) +{ + BUG(); + return NULL; +} + +struct vm_operations_struct hugetlb_vm_ops = { + .nopage = hugetlb_nopage, + .close = zap_hugetlb_resources, }; diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c --- a/arch/ia64/mm/init.c Sun Feb 9 21:13:31 2003 +++ b/arch/ia64/mm/init.c Sun Feb 9 21:13:31 2003 @@ -234,7 +234,7 @@ pte_t *pte; if (!PageReserved(page)) - printk("put_gate_page: gate page at 0x%p not in reserved memory\n", + printk(KERN_ERR "put_gate_page: gate page at 0x%p not in reserved memory\n", page_address(page)); pgd = pgd_offset_k(address); /* note: this is NOT pgd_offset()! */ @@ -342,13 +342,6 @@ * Set up the page tables. */ -#ifdef CONFIG_HUGETLB_PAGE -long htlbpagemem; -int htlbpage_max; -extern long htlbzone_pages; -extern struct list_head htlbpage_freelist; -#endif - #ifdef CONFIG_DISCONTIGMEM void paging_init (void) @@ -438,10 +431,10 @@ datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; - printk("Memory: %luk/%luk available (%luk code, %luk reserved, %luk data, %luk init)\n", - (unsigned long) nr_free_pages() << (PAGE_SHIFT - 10), - num_physpages << (PAGE_SHIFT - 10), codesize >> 10, reserved_pages << (PAGE_SHIFT - 10), - datasize >> 10, initsize >> 10); + printk(KERN_INFO "Memory: %luk/%luk available (%luk code, %luk reserved, " + "%luk data, %luk init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT - 10), + num_physpages << (PAGE_SHIFT - 10), codesize >> 10, + reserved_pages << (PAGE_SHIFT - 10), datasize >> 10, initsize >> 10); /* * Allow for enough (cached) page table pages so that we can map the entire memory @@ -461,30 +454,5 @@ #ifdef CONFIG_IA32_SUPPORT ia32_gdt_init(); -#endif -#ifdef CONFIG_HUGETLB_PAGE - { - long i; - int j; - struct page *page, *map; - - if ((htlbzone_pages << (HPAGE_SHIFT - PAGE_SHIFT)) >= max_low_pfn) - htlbzone_pages = (max_low_pfn >> ((HPAGE_SHIFT - PAGE_SHIFT) + 1)); - INIT_LIST_HEAD(&htlbpage_freelist); - for (i = 0; i < htlbzone_pages; i++) { - page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER); - if (!page) - break; - map = page; - for (j = 0; j < (HPAGE_SIZE/PAGE_SIZE); j++) { - SetPageReserved(map); - map++; - } - list_add(&page->list, &htlbpage_freelist); - } - printk("Total Huge_TLB_Page memory pages allocated %ld \n", i); - htlbzone_pages = htlbpagemem = i; - htlbpage_max = (int)i; - } #endif } diff -Nru a/arch/ia64/scripts/check-gas b/arch/ia64/scripts/check-gas --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ia64/scripts/check-gas Sun Feb 9 21:13:38 2003 @@ -0,0 +1,11 @@ +#!/bin/sh +dir=$(dirname $0) +CC=$1 +$CC -c $dir/check-gas-asm.S +res=$(objdump -r --section .data check-gas-asm.o | fgrep 00004 | tr -s ' ' |cut -f3 -d' ') +if [ $res != ".text" ]; then + echo buggy +else + echo good +fi +exit 0 diff -Nru a/arch/ia64/scripts/check-gas-asm.S b/arch/ia64/scripts/check-gas-asm.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ia64/scripts/check-gas-asm.S Sun Feb 9 21:13:38 2003 @@ -0,0 +1,2 @@ +[1:] nop 0 + .xdata4 ".data", 0, 1b-. diff -Nru a/arch/ia64/scripts/unwcheck.sh b/arch/ia64/scripts/unwcheck.sh --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ia64/scripts/unwcheck.sh Sun Feb 9 21:13:38 2003 @@ -0,0 +1,109 @@ +#!/bin/sh +# Usage: unwcheck.sh +# Pre-requisite: readelf [from Gnu binutils package] +# Purpose: Check the following invariant +# For each code range in the input binary: +# Sum[ lengths of unwind regions] = Number of slots in code range. +# Author : Harish Patil +# First version: January 2002 +# Modified : 2/13/2002 +# Modified : 3/15/2002: duplicate detection +readelf -u $1 | gawk '\ + function todec(hexstr){ + dec = 0; + l = length(hexstr); + for (i = 1; i <= l; i++) + { + c = substr(hexstr, i, 1); + if (c == "A") + dec = dec*16 + 10; + else if (c == "B") + dec = dec*16 + 11; + else if (c == "C") + dec = dec*16 + 12; + else if (c == "D") + dec = dec*16 + 13; + else if (c == "E") + dec = dec*16 + 14; + else if (c == "F") + dec = dec*16 + 15; + else + dec = dec*16 + c; + } + return dec; + } + BEGIN { first = 1; sum_rlen = 0; no_slots = 0; errors=0; no_code_ranges=0; } + { + if (NF==5 && $3=="info") + { + no_code_ranges += 1; + if (first == 0) + { + if (sum_rlen != no_slots) + { + print full_code_range; + print " ", "lo = ", lo, " hi =", hi; + print " ", "sum_rlen = ", sum_rlen, "no_slots = " no_slots; + print " "," ", "*******ERROR ***********"; + print " "," ", "sum_rlen:", sum_rlen, " != no_slots:" no_slots; + errors += 1; + } + sum_rlen = 0; + } + full_code_range = $0; + code_range = $2; + gsub("..$", "", code_range); + gsub("^.", "", code_range); + split(code_range, addr, "-"); + lo = toupper(addr[1]); + + code_range_lo[no_code_ranges] = addr[1]; + occurs[addr[1]] += 1; + full_range[addr[1]] = $0; + + gsub("0X.[0]*", "", lo); + hi = toupper(addr[2]); + gsub("0X.[0]*", "", hi); + no_slots = (todec(hi) - todec(lo))/ 16*3 + first = 0; + } + if (index($0,"rlen") > 0 ) + { + rlen_str = substr($0, index($0,"rlen")); + rlen = rlen_str; + gsub("rlen=", "", rlen); + gsub(")", "", rlen); + sum_rlen = sum_rlen + rlen; + } + } + END { + if (first == 0) + { + if (sum_rlen != no_slots) + { + print "code_range=", code_range; + print " ", "lo = ", lo, " hi =", hi; + print " ", "sum_rlen = ", sum_rlen, "no_slots = " no_slots; + print " "," ", "*******ERROR ***********"; + print " "," ", "sum_rlen:", sum_rlen, " != no_slots:" no_slots; + errors += 1; + } + } + no_duplicates = 0; + for (i=1; i<=no_code_ranges; i++) + { + cr = code_range_lo[i]; + if (reported_cr[cr]==1) continue; + if ( occurs[cr] > 1) + { + reported_cr[cr] = 1; + print "Code range low ", code_range_lo[i], ":", full_range[cr], " occurs: ", occurs[cr], " times."; + print " "; + no_duplicates++; + } + } + print "======================================" + print "Total errors:", errors, "/", no_code_ranges, " duplicates:", no_duplicates; + print "======================================" + } + ' diff -Nru a/arch/ia64/sn/io/Makefile b/arch/ia64/sn/io/Makefile --- a/arch/ia64/sn/io/Makefile Sun Feb 9 21:13:30 2003 +++ b/arch/ia64/sn/io/Makefile Sun Feb 9 21:13:30 2003 @@ -13,8 +13,6 @@ EXTRA_CFLAGS += -DSHUB_SWAP_WAR endif -export-objs := hcl.o pci_dma.o - obj-$(CONFIG_IA64_SGI_SN) += stubs.o sgi_if.o xswitch.o klgraph_hack.o \ hcl.o labelcl.o invent.o sgi_io_sim.o \ klgraph_hack.o hcl_util.o cdl.o hubdev.o hubspc.o \ diff -Nru a/arch/ia64/sn/io/sn1/pcibr.c b/arch/ia64/sn/io/sn1/pcibr.c --- a/arch/ia64/sn/io/sn1/pcibr.c Sun Feb 9 21:13:33 2003 +++ b/arch/ia64/sn/io/sn1/pcibr.c Sun Feb 9 21:13:33 2003 @@ -4811,7 +4811,7 @@ /* Device is capable of A64 operations, * and the attributes of the DMA are - * consistant with any previous DMA + * consistent with any previous DMA * mappings using shared resources. */ @@ -4853,7 +4853,7 @@ if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) { /* User desires DIRECT A32 operations, * and the attributes of the DMA are - * consistant with any previous DMA + * consistent with any previous DMA * mappings using shared resources. * Mapping calls may fail if target * is outside the direct32 range. diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c --- a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c Sun Feb 9 21:13:37 2003 +++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c Sun Feb 9 21:13:37 2003 @@ -3216,7 +3216,7 @@ /* Device is capable of A64 operations, * and the attributes of the DMA are - * consistant with any previous DMA + * consistent with any previous DMA * mappings using shared resources. */ @@ -3266,7 +3266,7 @@ if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) { /* User desires DIRECT A32 operations, * and the attributes of the DMA are - * consistant with any previous DMA + * consistent with any previous DMA * mappings using shared resources. * Mapping calls may fail if target * is outside the direct32 range. diff -Nru a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile --- a/arch/ia64/sn/kernel/Makefile Sun Feb 9 21:13:29 2003 +++ b/arch/ia64/sn/kernel/Makefile Sun Feb 9 21:13:29 2003 @@ -38,8 +38,6 @@ .S.o: $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $< -export-objs = sn_ksyms.o iomv.o - obj-y = probe.o setup.o sn_asm.o sv.o bte.o iomv.o obj-$(CONFIG_IA64_SGI_SN1) += irq.o mca.o obj-$(CONFIG_IA64_SGI_SN2) += irq.o mca.o diff -Nru a/arch/ia64/tools/Makefile b/arch/ia64/tools/Makefile --- a/arch/ia64/tools/Makefile Sun Feb 9 21:13:32 2003 +++ b/arch/ia64/tools/Makefile Sun Feb 9 21:13:32 2003 @@ -4,14 +4,7 @@ src = $(obj) -all: - -fastdep: - -mrproper: clean - -clean: - rm -f $(obj)/print_offsets.s $(obj)/print_offsets $(obj)/offsets.h +clean-files := print_offsets.s print_offsets offsets.h $(TARGET): $(obj)/offsets.h @if ! cmp -s $(obj)/offsets.h ${TARGET}; then \ diff -Nru a/arch/ia64/tools/print_offsets.c b/arch/ia64/tools/print_offsets.c --- a/arch/ia64/tools/print_offsets.c Sun Feb 9 21:13:36 2003 +++ b/arch/ia64/tools/print_offsets.c Sun Feb 9 21:13:36 2003 @@ -1,7 +1,7 @@ /* * Utility to generate asm-ia64/offsets.h. * - * Copyright (C) 1999-2002 Hewlett-Packard Co + * Copyright (C) 1999-2003 Hewlett-Packard Co * David Mosberger-Tang * * Note that this file has dual use: when building the kernel @@ -52,8 +52,13 @@ { "SIGFRAME_SIZE", sizeof (struct sigframe) }, { "UNW_FRAME_INFO_SIZE", sizeof (struct unw_frame_info) }, { "", 0 }, /* spacer */ - { "IA64_TASK_THREAD_KSP_OFFSET", offsetof (struct task_struct, thread.ksp) }, + { "IA64_TASK_CLEAR_CHILD_TID_OFFSET",offsetof (struct task_struct, clear_child_tid) }, + { "IA64_TASK_GROUP_LEADER_OFFSET", offsetof (struct task_struct, group_leader) }, { "IA64_TASK_PID_OFFSET", offsetof (struct task_struct, pid) }, + { "IA64_TASK_REAL_PARENT_OFFSET", offsetof (struct task_struct, real_parent) }, + { "IA64_TASK_TGID_OFFSET", offsetof (struct task_struct, tgid) }, + { "IA64_TASK_THREAD_KSP_OFFSET", offsetof (struct task_struct, thread.ksp) }, + { "IA64_TASK_THREAD_ON_USTACK_OFFSET", offsetof (struct task_struct, thread.on_ustack) }, { "IA64_PT_REGS_CR_IPSR_OFFSET", offsetof (struct pt_regs, cr_ipsr) }, { "IA64_PT_REGS_CR_IIP_OFFSET", offsetof (struct pt_regs, cr_iip) }, { "IA64_PT_REGS_CR_IFS_OFFSET", offsetof (struct pt_regs, cr_ifs) }, diff -Nru a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S --- a/arch/ia64/vmlinux.lds.S Sun Feb 9 21:13:35 2003 +++ b/arch/ia64/vmlinux.lds.S Sun Feb 9 21:13:35 2003 @@ -6,7 +6,7 @@ #define LOAD_OFFSET PAGE_OFFSET #include - + OUTPUT_FORMAT("elf64-ia64-little") OUTPUT_ARCH(ia64) ENTRY(phys_start) @@ -29,6 +29,7 @@ _text = .; _stext = .; + .text : AT(ADDR(.text) - PAGE_OFFSET) { *(.text.ivt) @@ -44,33 +45,46 @@ /* Read-only data */ - /* Global data */ - _data = .; - /* Exception table */ . = ALIGN(16); - __start___ex_table = .; __ex_table : AT(ADDR(__ex_table) - PAGE_OFFSET) - { *(__ex_table) } - __stop___ex_table = .; + { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } + + __mckinley_e9_bundles : AT(ADDR(__mckinley_e9_bundles) - PAGE_OFFSET) + { + __start___mckinley_e9_bundles = .; + *(__mckinley_e9_bundles) + __end___mckinley_e9_bundles = .; + } + + /* Global data */ + _data = .; #if defined(CONFIG_IA64_GENERIC) /* Machine Vector */ . = ALIGN(16); - machvec_start = .; .machvec : AT(ADDR(.machvec) - PAGE_OFFSET) - { *(.machvec) } - machvec_end = .; + { + machvec_start = .; + *(.machvec) + machvec_end = .; + } #endif /* Unwind info & table: */ . = ALIGN(8); .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - PAGE_OFFSET) { *(.IA_64.unwind_info*) } - ia64_unw_start = .; .IA_64.unwind : AT(ADDR(.IA_64.unwind) - PAGE_OFFSET) - { *(.IA_64.unwind*) } - ia64_unw_end = .; + { + ia64_unw_start = .; + *(.IA_64.unwind*) + ia64_unw_end = .; + } RODATA @@ -87,32 +101,38 @@ .init.data : AT(ADDR(.init.data) - PAGE_OFFSET) { *(.init.data) } - __initramfs_start = .; .init.ramfs : AT(ADDR(.init.ramfs) - PAGE_OFFSET) - { *(.init.ramfs) } - __initramfs_end = .; + { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + } . = ALIGN(16); - __setup_start = .; .init.setup : AT(ADDR(.init.setup) - PAGE_OFFSET) - { *(.init.setup) } - __setup_end = .; - __start___param = .; + { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } __param : AT(ADDR(__param) - PAGE_OFFSET) - { *(__param) } - __stop___param = .; - __initcall_start = .; + { + __start___param = .; + *(__param) + __stop___param = .; + } .initcall.init : AT(ADDR(.initcall.init) - PAGE_OFFSET) { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + __initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + __initcall_end = .; } - __initcall_end = .; . = ALIGN(PAGE_SIZE); __init_end = .; @@ -130,10 +150,6 @@ . = ALIGN(SMP_CACHE_BYTES); .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - PAGE_OFFSET) { *(.data.cacheline_aligned) } - - /* Kernel symbol names for modules: */ - .kstrtab : AT(ADDR(.kstrtab) - PAGE_OFFSET) - { *(.kstrtab) } /* Per-cpu data: */ . = ALIGN(PERCPU_PAGE_SIZE); diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig --- a/arch/m68k/Kconfig Sun Feb 9 21:13:33 2003 +++ b/arch/m68k/Kconfig Sun Feb 9 21:13:33 2003 @@ -73,8 +73,8 @@ This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - When compiled this way, there will be modules called pcmcia_core.o - and ds.o. If you want to compile it as a module, say M here and + When compiled this way, there will be modules called pcmcia_core + and ds. If you want to compile it as a module, say M here and read . config AMIGA @@ -398,7 +398,7 @@ QMAGIC support" then you'll have to say Y here. You may answer M to compile a.out support as a module and later load the module when you want to use a program or library in a.out format. The module will be - called binfmt_aout.o. Saying M or N here is dangerous though, + called binfmt_aout. Saying M or N here is dangerous though, because some crucial programs on your system might still be in A.OUT format. @@ -428,7 +428,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config BINFMT_MISC @@ -453,7 +453,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. config ZORRO @@ -541,7 +541,7 @@ ( = 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 - parport.o. If you have more than one parallel port and want to + parport. If you have more than one parallel port and want to specify which port and IRQ to be used by this driver at module load time, take a look at . @@ -553,7 +553,7 @@ help Say Y here if you need support for the parallel port hardware on Amiga machines. This code is also available as a module (say M), - called parport_amiga.o. If in doubt, saying N is the safe plan. + called parport_amiga. If in doubt, saying N is the safe plan. config PARPORT_MFC3 tristate "Multiface III parallel port" @@ -561,7 +561,7 @@ help Say Y here if you need parallel port support for the MFC3 card. This code is also available as a module (say M), called - parport_mfc3.o. If in doubt, saying N is the safe plan. + parport_mfc3. If in doubt, saying N is the safe plan. config PARPORT_PC bool @@ -576,7 +576,7 @@ 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 - parport_pc.o. + parport_pc. If unsure, say Y. @@ -586,7 +586,7 @@ help Say Y here if you need support for the parallel port hardware on Atari machines. This code is also available as a module (say M), - called parport_atari.o. If in doubt, saying N is the safe plan. + called parport_atari. If in doubt, saying N is the safe plan. config PRINTER tristate "Parallel printer support" @@ -604,7 +604,7 @@ driver as a module however ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read and - . The module will be called lp.o. + . The module will be called lp. If you have several parallel ports, you can specify which ports to use with the "lp" kernel command line option. (Try "man bootparam" @@ -702,7 +702,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -729,7 +729,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -750,7 +750,7 @@ 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 will be called sd_mod.o. If you want to compile it as a + The module will be called sd_mod. If you want to compile it as a module, say M here and read and . Do not compile this driver as a module if your root file system (the one containing the directory /) @@ -786,7 +786,7 @@ 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 will be called st.o. If you want to compile it as a + The module will be called st. If you want to compile it as a module, say M here and read and . @@ -818,7 +818,7 @@ 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 will be called sr_mod.o. If you want to compile it as a + The module will be called sr_mod. If you want to compile it as a module, say M here and read and . @@ -871,7 +871,7 @@ 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 and - . The module will be called sg.o. + . The module will be called sg. If unsure, say N. comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs" @@ -934,7 +934,7 @@ built-in SCSI controller, say Y. Otherwise, say N. 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 wd33c93.o. If you want to compile it as a module, say M here + called wd33c93. If you want to compile it as a module, say M here and read . config A4000T_SCSI @@ -950,7 +950,7 @@ If you have a Commodore A2091 SCSI controller, say Y. Otherwise, say N. 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 wd33c93.o. If you want to compile it as + want). The module is called wd33c93. If you want to compile it as a module, say M here and read . config GVP11_SCSI @@ -965,7 +965,7 @@ 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 will be called gvp11.o. If you want to compile it + want). The module will be called gvp11. If you want to compile it as a module, say M here and read . config CYBERSTORM_SCSI @@ -1050,7 +1050,7 @@ a compatible SCSI controller (e.g. for Medusa). 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 - atari_scsi.o. If you want to compile it as a module, say M here and + atari_scsi. If you want to compile it as a module, say M here and read . This driver supports both styles of NCR integration into the system: the TT style (separate DMA), and the Falcon style (via ST-DMA, replacing ACSI). It does @@ -1101,7 +1101,7 @@ 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 will be called mac_esp.o. If you want to compile it as + The module will be called mac_esp. If you want to compile it as a module, say M here and read . # dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI @@ -1169,7 +1169,7 @@ If you want to compile this driver as a module, say M here and read . The module will be called - serial.o. + serial. [WARNING: Do not compile this driver as a module if you are using non-standard serial ports, since the configuration information will be lost when the driver is unloaded. This limitation may be lifted @@ -1315,7 +1315,7 @@ 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 will be called nvram.o. If you want to compile it as a + The module will be called nvram. If you want to compile it as a module, say M here and read . config ATARI_MFPSER @@ -1426,9 +1426,9 @@ for which 8 pin to DB25 adapters were supplied. The card also had jumpers internally to toggle various pinning configurations. - This driver can be built as a module; but then "generic_serial.o" + This driver can be built as a module; but then "generic_serial" will also be built as a module. This has to be loaded before - "ser_a2232.o". If you want to do this, answer M here and read + "ser_a2232". If you want to do this, answer M here and read "". config GVPIOEXT @@ -1686,7 +1686,7 @@ inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . The module will be called - softdog.o. + softdog. config RTC bool "Enhanced Real Time Clock Support" @@ -1713,7 +1713,7 @@ 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 rtc.o. If you want to compile it as a module, + The module is called rtc. If you want to compile it as a module, say M here and read . config GEN_RTC @@ -1734,7 +1734,7 @@ 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 genrtc.o. If you want to compile it as a module, + The module is called genrtc. If you want to compile it as a module, say M here and read . To load the module automatically add 'alias char-major-10-135 genrtc' to your /etc/modules.conf diff -Nru a/arch/m68k/Makefile b/arch/m68k/Makefile --- a/arch/m68k/Makefile Sun Feb 9 21:13:36 2003 +++ b/arch/m68k/Makefile Sun Feb 9 21:13:36 2003 @@ -54,9 +54,9 @@ endif ifndef CONFIG_SUN3 -HEAD := arch/m68k/kernel/head.o +head-y := arch/m68k/kernel/head.o else -HEAD := arch/m68k/kernel/sun3-head.o +head-y := arch/m68k/kernel/sun3-head.o endif core-y += arch/m68k/kernel/ arch/m68k/mm/ @@ -113,5 +113,3 @@ archclean: rm -f vmlinux.gz vmlinux.bz2 rm -f arch/m68k/kernel/m68k_defs.h arch/m68k/kernel/m68k_defs.d - -archmrproper: diff -Nru a/arch/m68k/amiga/Makefile b/arch/m68k/amiga/Makefile --- a/arch/m68k/amiga/Makefile Sun Feb 9 21:13:37 2003 +++ b/arch/m68k/amiga/Makefile Sun Feb 9 21:13:37 2003 @@ -2,8 +2,6 @@ # Makefile for Linux arch/m68k/amiga source directory # -export-objs := amiga_ksyms.o - obj-y := config.o amiints.o cia.o chipram.o amisound.o amiga_ksyms.o obj-$(CONFIG_AMIGA_PCMCIA) += pcmcia.o diff -Nru a/arch/m68k/atari/Makefile b/arch/m68k/atari/Makefile --- a/arch/m68k/atari/Makefile Sun Feb 9 21:13:34 2003 +++ b/arch/m68k/atari/Makefile Sun Feb 9 21:13:34 2003 @@ -2,8 +2,6 @@ # Makefile for Linux arch/m68k/atari source directory # -export-objs := atari_ksyms.o - obj-y := config.o time.o debug.o ataints.o stdma.o \ atasound.o stram.o atari_ksyms.o diff -Nru a/arch/m68k/atari/hades-pci.c b/arch/m68k/atari/hades-pci.c --- a/arch/m68k/atari/hades-pci.c Sun Feb 9 21:13:32 2003 +++ b/arch/m68k/atari/hades-pci.c Sun Feb 9 21:13:32 2003 @@ -375,7 +375,7 @@ memset(bus, 0, sizeof(struct pci_bus_info)); /* - * Claim resources. The m68k has no seperate I/O space, both + * Claim resources. The m68k has no separate I/O space, both * PCI memory space and PCI I/O space are in memory space. Therefore * the I/O resources are requested in memory space as well. */ diff -Nru a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile --- a/arch/m68k/kernel/Makefile Sun Feb 9 21:13:34 2003 +++ b/arch/m68k/kernel/Makefile Sun Feb 9 21:13:34 2003 @@ -8,8 +8,6 @@ EXTRA_TARGETS := sun3-head.o endif -export-objs := setup.o m68k_ksyms.o - obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o \ sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o diff -Nru a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c --- a/arch/m68k/kernel/time.c Sun Feb 9 21:13:30 2003 +++ b/arch/m68k/kernel/time.c Sun Feb 9 21:13:30 2003 @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -129,25 +130,27 @@ mach_sched_init(timer_interrupt); } -extern rwlock_t xtime_lock; - /* * This version of gettimeofday has near microsecond resolution. */ void do_gettimeofday(struct timeval *tv) { - extern unsigned long wall_jiffies; unsigned long flags; + extern unsigned long wall_jiffies; + unsigned long seq; unsigned long usec, sec, lost; - read_lock_irqsave(&xtime_lock, flags); - usec = mach_gettimeoffset(); - lost = jiffies - wall_jiffies; - if (lost) - usec += lost * (1000000/HZ); - sec = xtime.tv_sec; - usec += xtime.tv_nsec/1000; - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + + usec = mach_gettimeoffset(); + lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000/HZ); + sec = xtime.tv_sec; + usec += xtime.tv_nsec/1000; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + while (usec >= 1000000) { usec -= 1000000; @@ -162,7 +165,7 @@ { extern unsigned long wall_jiffies; - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* This is revolting. We need to set the xtime.tv_nsec * correctly. However, the value in this location is * is value at the last tick. @@ -183,5 +186,5 @@ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } diff -Nru a/arch/m68k/mac/Makefile b/arch/m68k/mac/Makefile --- a/arch/m68k/mac/Makefile Sun Feb 9 21:13:37 2003 +++ b/arch/m68k/mac/Makefile Sun Feb 9 21:13:37 2003 @@ -2,7 +2,5 @@ # Makefile for Linux arch/m68k/mac source directory # -export-objs := mac_ksyms.o - obj-y := config.o bootparse.o macints.o iop.o via.o oss.o psc.o \ baboon.o macboing.o debug.o misc.o mac_ksyms.o diff -Nru a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c --- a/arch/m68k/mac/macints.c Sun Feb 9 21:13:35 2003 +++ b/arch/m68k/mac/macints.c Sun Feb 9 21:13:35 2003 @@ -749,7 +749,7 @@ /* */ /* Note that we're ignoring scc_mask for now. */ /* If we actually mask the ints then we tend to */ - /* get hammered by very persistant SCC irqs, */ + /* get hammered by very persistent SCC irqs, */ /* and since they're autovector interrupts they */ /* pretty much kill the system. */ diff -Nru a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c --- a/arch/m68k/mac/via.c Sun Feb 9 21:13:31 2003 +++ b/arch/m68k/mac/via.c Sun Feb 9 21:13:31 2003 @@ -48,7 +48,7 @@ * just hit the combined register (ie, vIER|rIER) but that seems to * break on AV Macs...probably because they actually decode more than * eight address bits. Why can't Apple engineers at least be - * _consistantly_ lazy? - 1999-05-21 (jmt) + * _consistently_ lazy? - 1999-05-21 (jmt) */ static int gIER,gIFR,gBufA,gBufB; diff -Nru a/arch/m68k/math-emu/fp_decode.h b/arch/m68k/math-emu/fp_decode.h --- a/arch/m68k/math-emu/fp_decode.h Sun Feb 9 21:13:28 2003 +++ b/arch/m68k/math-emu/fp_decode.h Sun Feb 9 21:13:28 2003 @@ -68,7 +68,7 @@ do_fscc=0 | first decoding of the instr type -| this seperates the conditional instr +| this separates the conditional instr .macro fp_decode_cond_instr_type bfextu %d2{#8,#2},%d0 jmp ([0f:w,%pc,%d0*4]) @@ -80,7 +80,7 @@ .endm | second decoding of the instr type -| this seperates most move instr +| this separates most move instr .macro fp_decode_move_instr_type bfextu %d2{#16,#3},%d0 jmp ([0f:w,%pc,%d0*4]) diff -Nru a/arch/m68k/math-emu/fp_scan.S b/arch/m68k/math-emu/fp_scan.S --- a/arch/m68k/math-emu/fp_scan.S Sun Feb 9 21:13:32 2003 +++ b/arch/m68k/math-emu/fp_scan.S Sun Feb 9 21:13:32 2003 @@ -74,13 +74,13 @@ | first two instruction words are kept in %d2 getuser.l (%a0)+,%d2,fp_err_ua1,%a0 fp_put_pc %a0 -fp_decode_cond: | seperate conditional instr +fp_decode_cond: | separate conditional instr fp_decode_cond_instr_type .long fp_decode_move, fp_fscc .long fp_fbccw, fp_fbccl -fp_decode_move: | seperate move instr +fp_decode_move: | separate move instr fp_decode_move_instr_type .long fp_fgen_fp, fp_ill diff -Nru a/arch/m68k/mvme16x/Makefile b/arch/m68k/mvme16x/Makefile --- a/arch/m68k/mvme16x/Makefile Sun Feb 9 21:13:34 2003 +++ b/arch/m68k/mvme16x/Makefile Sun Feb 9 21:13:34 2003 @@ -2,6 +2,4 @@ # Makefile for Linux arch/m68k/mvme16x source directory # -export-objs := mvme16x_ksyms.o - obj-y := config.o 16xints.o rtc.o mvme16x_ksyms.o diff -Nru a/arch/m68k/sun3/Makefile b/arch/m68k/sun3/Makefile --- a/arch/m68k/sun3/Makefile Sun Feb 9 21:13:28 2003 +++ b/arch/m68k/sun3/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for Linux arch/m68k/sun3 source directory # -export-objs := sun3_ksyms.o - obj-y := sun3_ksyms.o sun3ints.o sun3dvma.o sbus.o idprom.o obj-$(CONFIG_SUN3) += config.o mmu_emu.o leds.o dvma.o \ diff -Nru a/arch/m68k/sun3x/Makefile b/arch/m68k/sun3x/Makefile --- a/arch/m68k/sun3x/Makefile Sun Feb 9 21:13:31 2003 +++ b/arch/m68k/sun3x/Makefile Sun Feb 9 21:13:31 2003 @@ -2,6 +2,4 @@ # Makefile for Linux arch/m68k/sun3x source directory # -export-objs := sun3x_ksyms.o - obj-y := config.o time.o dvma.o prom.o diff -Nru a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig --- a/arch/m68knommu/Kconfig Sun Feb 9 21:13:34 2003 +++ b/arch/m68knommu/Kconfig Sun Feb 9 21:13:34 2003 @@ -658,7 +658,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile --- a/arch/m68knommu/Makefile Sun Feb 9 21:13:34 2003 +++ b/arch/m68knommu/Makefile Sun Feb 9 21:13:34 2003 @@ -84,7 +84,7 @@ LDFLAGS_BLOB := --format binary --oformat elf32-m68k -HEAD := arch/m68knommu/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o +head-y := arch/m68knommu/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o CLEAN_FILES := include/asm-$(ARCH)/asm-offsets.h.tmp \ include/asm-$(ARCH)/asm-offsets.h \ @@ -97,8 +97,6 @@ libs-y += arch/m68knommu/lib/ prepare: include/asm-$(ARCH)/asm-offsets.h - -archmrproper: archclean: $(call descend arch/$(ARCH)/boot, subdirclean) diff -Nru a/arch/m68knommu/kernel/Makefile b/arch/m68knommu/kernel/Makefile --- a/arch/m68knommu/kernel/Makefile Sun Feb 9 21:13:30 2003 +++ b/arch/m68knommu/kernel/Makefile Sun Feb 9 21:13:30 2003 @@ -2,8 +2,6 @@ # Makefile for arch/m68knommu/kernel. # -export-objs := m68k_ksyms.o - obj-y += entry.o init_task.o ints.o m68k_ksyms.o process.o ptrace.o \ semaphore.o setup.o signal.o syscalltable.o sys_m68k.o time.o \ traps.o diff -Nru a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c --- a/arch/m68knommu/kernel/signal.c Sun Feb 9 21:13:33 2003 +++ b/arch/m68knommu/kernel/signal.c Sun Feb 9 21:13:33 2003 @@ -63,11 +63,11 @@ sigset_t saveset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->d0 = -EINTR; while (1) { @@ -93,11 +93,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->d0 = -EINTR; while (1) { @@ -370,10 +370,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0)) goto badframe; @@ -399,10 +399,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (rt_restore_ucontext(regs, sw, &frame->uc, &d0)) goto badframe; @@ -738,11 +738,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c --- a/arch/m68knommu/kernel/time.c Sun Feb 9 21:13:33 2003 +++ b/arch/m68knommu/kernel/time.c Sun Feb 9 21:13:33 2003 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -126,21 +127,23 @@ mach_sched_init(timer_interrupt); } -extern rwlock_t xtime_lock; - /* * This version of gettimeofday has near microsecond resolution. */ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; unsigned long usec, sec; - read_lock_irqsave(&xtime_lock, flags); - usec = mach_gettimeoffset ? mach_gettimeoffset() : 0; - sec = xtime.tv_sec; - usec += (xtime.tv_nsec / 1000); - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + + usec = mach_gettimeoffset ? mach_gettimeoffset() : 0; + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + while (usec >= 1000000) { usec -= 1000000; @@ -153,7 +156,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is * is value at the last tick. @@ -174,5 +177,5 @@ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } diff -Nru a/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S b/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S --- a/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S Sun Feb 9 21:13:37 2003 +++ b/arch/m68knommu/platform/68360/uCquicc/crt0_ram.S Sun Feb 9 21:13:37 2003 @@ -358,7 +358,7 @@ .long 0 /* (Unassigned, Reserved) - 62. */ .long 0 /* (Unassigned, Reserved) - 63. */ /* The assignment of these vectors to the CPM is */ - /* dependant on the configuration of the CPM vba */ + /* dependent on the configuration of the CPM vba */ /* fields. */ .long 0 /* (User-Defined Vectors 1) CPM Error - 64. */ .long 0 /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */ diff -Nru a/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S b/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S --- a/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S Sun Feb 9 21:13:36 2003 +++ b/arch/m68knommu/platform/68360/uCquicc/crt0_rom.S Sun Feb 9 21:13:36 2003 @@ -367,7 +367,7 @@ .long 0 /* (Unassigned, Reserved) - 62. */ .long 0 /* (Unassigned, Reserved) - 63. */ /* The assignment of these vectors to the CPM is */ - /* dependant on the configuration of the CPM vba */ + /* dependent on the configuration of the CPM vba */ /* fields. */ .long 0 /* (User-Defined Vectors 1) CPM Error - 64. */ .long 0 /* (User-Defined Vectors 2) CPM Parallel IO PC11- 65. */ diff -Nru a/arch/mips/Kconfig b/arch/mips/Kconfig --- a/arch/mips/Kconfig Sun Feb 9 21:13:32 2003 +++ b/arch/mips/Kconfig Sun Feb 9 21:13:32 2003 @@ -724,7 +724,7 @@ QMAGIC support" then you'll have to say Y here. You may answer M to compile a.out support as a module and later load the module when you want to use a program or library in a.out format. The module will be - called binfmt_aout.o. Saying M or N here is dangerous though, + called binfmt_aout. Saying M or N here is dangerous though, because some crucial programs on your system might still be in A.OUT format. @@ -755,7 +755,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config BINFMT_MISC @@ -780,7 +780,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. source "drivers/pci/Kconfig" @@ -875,7 +875,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -902,7 +902,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -994,7 +994,7 @@ If you want to compile this driver as a module, say M here and read . The module will be called - serial.o. + serial. [WARNING: Do not compile this driver as a module if you are using non-standard serial ports, since the configuration information will be lost when the driver is unloaded. This limitation may be lifted @@ -1157,7 +1157,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/mips/Makefile b/arch/mips/Makefile --- a/arch/mips/Makefile Sun Feb 9 21:13:28 2003 +++ b/arch/mips/Makefile Sun Feb 9 21:13:28 2003 @@ -256,7 +256,7 @@ AFLAGS_vmlinux.lds.o := -DLOADADDR=$(LOADADDR) -HEAD := arch/mips/kernel/head.o arch/mips/kernel/init_task.o +head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o SUBDIRS := arch/mips/tools diff -Nru a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile --- a/arch/mips/au1000/common/Makefile Sun Feb 9 21:13:36 2003 +++ b/arch/mips/au1000/common/Makefile Sun Feb 9 21:13:36 2003 @@ -6,8 +6,6 @@ # Makefile for the Alchemy Au1000 CPU, generic files. # -export-objs := serial.o - obj-y := prom.o dbg_io.o int-handler.o irq.o puts.o time.o reset.o obj-$(CONFIG_AU1000_UART) += serial.o diff -Nru a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c --- a/arch/mips/au1000/common/time.c Sun Feb 9 21:13:30 2003 +++ b/arch/mips/au1000/common/time.c Sun Feb 9 21:13:30 2003 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -44,7 +45,6 @@ static unsigned long r4k_offset; /* Amount to increment compare reg each time */ static unsigned long r4k_cur; /* What counter should be at next timer irq */ -extern rwlock_t xtime_lock; #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) @@ -150,10 +150,10 @@ set_cp0_status(ALLINTS); /* Read time from the RTC chipset. */ - write_lock_irqsave (&xtime_lock, flags); + write_seqlock_irqsave (&xtime_lock, flags); xtime.tv_sec = get_mips_time(); xtime.tv_usec = 0; - write_unlock_irqrestore(&xtime_lock, flags); + write_sequnlock_irqrestore(&xtime_lock, flags); } /* This is for machines which generate the exact clock. */ @@ -229,20 +229,24 @@ void do_gettimeofday(struct timeval *tv) { - unsigned int flags; + unsigned long flags; + unsigned long seq; - read_lock_irqsave (&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_fast_gettimeoffset(); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; + *tv = xtime; + tv->tv_usec += do_fast_gettimeoffset(); + + /* + * xtime is atomically updated in timer_bh. jiffies - wall_jiffies + * is nonzero if the timer bottom half hasnt executed yet. + */ + if (jiffies - wall_jiffies) + tv->tv_usec += USECS_PER_JIFFY; + + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - read_unlock_irqrestore (&xtime_lock, flags); if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; @@ -252,7 +256,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq (&xtime_lock); + write_seqlock_irq (&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec correctly. * However, the value in this location is is value at the last tick. @@ -272,7 +276,7 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq (&xtime_lock); + write_sequnlock_irq (&xtime_lock); } /* diff -Nru a/arch/mips/baget/Makefile b/arch/mips/baget/Makefile --- a/arch/mips/baget/Makefile Sun Feb 9 21:13:37 2003 +++ b/arch/mips/baget/Makefile Sun Feb 9 21:13:37 2003 @@ -3,7 +3,6 @@ # under Linux. # -export-objs := vacserial.o obj-y := baget.o print.o setup.o time.o irq.o bagetIRQ.o \ reset.o wbflush.o obj-$(CONFIG_SERIAL) += vacserial.o diff -Nru a/arch/mips/baget/time.c b/arch/mips/baget/time.c --- a/arch/mips/baget/time.c Sun Feb 9 21:13:28 2003 +++ b/arch/mips/baget/time.c Sun Feb 9 21:13:28 2003 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -23,8 +24,6 @@ #include -extern rwlock_t xtime_lock; - /* * To have precision clock, we need to fix available clock frequency */ @@ -79,20 +78,21 @@ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; + unsigned long seq; - read_lock_irqsave (&xtime_lock, flags); - *tv = xtime; - read_unlock_irqrestore (&xtime_lock, flags); + do { + seq = read_seqbegin(&xtime_lock); + *tv = xtime; + } while (read_seqretry(&xtime_lock, seq)); } void do_settimeofday(struct timeval *tv) { - write_lock_irq (&xtime_lock); + write_seqlock_irq (&xtime_lock); xtime = *tv; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq (&xtime_lock); + write_sequnlock_irq (&xtime_lock); } diff -Nru a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile --- a/arch/mips/dec/Makefile Sun Feb 9 21:13:30 2003 +++ b/arch/mips/dec/Makefile Sun Feb 9 21:13:30 2003 @@ -2,8 +2,6 @@ # Makefile for the DECstation family specific parts of the kernel # -export-objs := wbflush.o - obj-y := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o wbflush.o obj-$(CONFIG_PROM_CONSOLE) += promcon.o diff -Nru a/arch/mips/dec/time.c b/arch/mips/dec/time.c --- a/arch/mips/dec/time.c Sun Feb 9 21:13:35 2003 +++ b/arch/mips/dec/time.c Sun Feb 9 21:13:35 2003 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,6 @@ extern void (*board_time_init)(struct irqaction *irq); extern volatile unsigned long wall_jiffies; -extern rwlock_t xtime_lock; /* * Change this if you have some constant time drift @@ -211,19 +211,22 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; - read_lock_irqsave(&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_gettimeoffset(); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + *tv = xtime; + tv->tv_usec += do_gettimeoffset(); - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; + /* + * xtime is atomically updated in timer_bh. jiffies - wall_jiffies + * is nonzero if the timer bottom half hasnt executed yet. + */ + if (jiffies - wall_jiffies) + tv->tv_usec += USECS_PER_JIFFY; + + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - read_unlock_irqrestore(&xtime_lock, flags); if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; @@ -233,7 +236,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is @@ -254,7 +257,7 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } /* @@ -330,6 +333,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { volatile unsigned char dummy; + unsigned long seq; dummy = CMOS_READ(RTC_REG_C); /* ACK RTC Interrupt */ @@ -357,23 +361,27 @@ * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ - read_lock(&xtime_lock); - if ((time_status & STA_UNSYNC) == 0 - && xtime.tv_sec > last_rtc_update + 660 - && xtime.tv_usec >= 500000 - tick / 2 - && xtime.tv_usec <= 500000 + tick / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* do it again in 60 s */ - last_rtc_update = xtime.tv_sec - 600; - } + do { + seq = read_seqbegin(&xtime_lock); + + if ((time_status & STA_UNSYNC) == 0 + && xtime.tv_sec > last_rtc_update + 660 + && xtime.tv_usec >= 500000 - tick / 2 + && xtime.tv_usec <= 500000 + tick / 2) { + if (set_rtc_mmss(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + /* do it again in 60 s */ + last_rtc_update = xtime.tv_sec - 600; + } + } while (read_seqretry(&xtime_lock, seq)); + /* As we return to user mode fire off the other CPU schedulers.. this is basically because we don't yet share IRQ's around. This message is rigged to be safe on the 386 - basically it's a hack, so don't look closely for now.. */ /*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */ - read_unlock(&xtime_lock); + } static void r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -470,10 +478,10 @@ real_year = CMOS_READ(RTC_DEC_YEAR); year += real_year - 72 + 2000; - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_usec = 0; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); if (mips_cpu.options & MIPS_CPU_COUNTER) { write_32bit_cp0_register(CP0_COUNT, 0); diff -Nru a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c --- a/arch/mips/ite-boards/generic/time.c Sun Feb 9 21:13:31 2003 +++ b/arch/mips/ite-boards/generic/time.c Sun Feb 9 21:13:31 2003 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,6 @@ extern void enable_cpu_timer(void); extern volatile unsigned long wall_jiffies; -extern rwlock_t xtime_lock; unsigned long missed_heart_beats = 0; static long last_rtc_update = 0; @@ -119,6 +119,8 @@ */ void mips_timer_interrupt(struct pt_regs *regs) { + unsigned long seq; + if (r4k_offset == 0) goto null; @@ -133,18 +135,22 @@ * within 500ms before the * next second starts, * thus the following code. */ - read_lock(&xtime_lock); - if ((time_status & STA_UNSYNC) == 0 - && xtime.tv_sec > last_rtc_update + 660 - && xtime.tv_usec >= 500000 - (tick >> 1) - && xtime.tv_usec <= 500000 + (tick >> 1)) - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else { - /* do it again in 60 s */ - last_rtc_update = xtime.tv_sec - 600; - } - read_unlock(&xtime_lock); + do { + seq = read_seqbegin(&xtime_lock); + + + if ((time_status & STA_UNSYNC) == 0 + && xtime.tv_sec > last_rtc_update + 660 + && xtime.tv_usec >= 500000 - (tick >> 1) + && xtime.tv_usec <= 500000 + (tick >> 1)) + if (set_rtc_mmss(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else { + /* do it again in 60 s */ + last_rtc_update = xtime.tv_sec - 600; + } + + } while (read_seqretry(&xtime_lock, seq)); r4k_cur += r4k_offset; ack_r4ktimer(r4k_cur); @@ -247,10 +253,10 @@ enable_cpu_timer(); /* Read time from the RTC chipset. */ - write_lock_irqsave (&xtime_lock, flags); + write_seqlock_irqsave (&xtime_lock, flags); xtime.tv_sec = get_mips_time(); xtime.tv_usec = 0; - write_unlock_irqrestore(&xtime_lock, flags); + write_sequnlock_irqrestore(&xtime_lock, flags); } /* This is for machines which generate the exact clock. */ @@ -332,20 +338,24 @@ void do_gettimeofday(struct timeval *tv) { - unsigned int flags; + unsigned long flags; + unsigned int seq; - read_lock_irqsave (&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_fast_gettimeoffset(); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; + *tv = xtime; + tv->tv_usec += do_fast_gettimeoffset(); + + /* + * xtime is atomically updated in timer_bh. + * jiffies - wall_jiffies + * is nonzero if the timer bottom half hasnt executed yet. + */ + if (jiffies - wall_jiffies) + tv->tv_usec += USECS_PER_JIFFY; - read_unlock_irqrestore (&xtime_lock, flags); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; @@ -355,7 +365,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq (&xtime_lock); + write_seqlock_irq (&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec correctly. * However, the value in this location is is value at the last tick. @@ -375,5 +385,5 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq (&xtime_lock); + write_sequnlock_irq (&xtime_lock); } diff -Nru a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile --- a/arch/mips/kernel/Makefile Sun Feb 9 21:13:31 2003 +++ b/arch/mips/kernel/Makefile Sun Feb 9 21:13:31 2003 @@ -5,8 +5,6 @@ # EXTRA_AFLAGS = -mips3 -mcpu=r4000 # not used? EXTRA_TARGETS := head.o init_task.o -export-objs := mips_ksyms.o - obj-y += branch.o process.o signal.o entry.o \ traps.o ptrace.o vm86.o ioport.o reset.o \ semaphore.o setup.o syscall.o sysmips.o \ diff -Nru a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c --- a/arch/mips/kernel/sysirix.c Sun Feb 9 21:13:36 2003 +++ b/arch/mips/kernel/sysirix.c Sun Feb 9 21:13:36 2003 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -615,19 +616,17 @@ return current->gid; } -extern rwlock_t xtime_lock; - asmlinkage int irix_stime(int value) { if (!capable(CAP_SYS_TIME)) return -EPERM; - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); xtime.tv_sec = value; xtime.tv_usec = 0; time_maxerror = MAXPHASE; time_esterror = MAXPHASE; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); return 0; } diff -Nru a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c --- a/arch/mips/kernel/time.c Sun Feb 9 21:13:31 2003 +++ b/arch/mips/kernel/time.c Sun Feb 9 21:13:31 2003 @@ -37,7 +37,6 @@ /* * forward reference */ -extern rwlock_t xtime_lock; extern volatile unsigned long wall_jiffies; /* @@ -63,19 +62,23 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; - read_lock_irqsave (&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_gettimeoffset(); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; + *tv = xtime; + tv->tv_usec += do_gettimeoffset(); + + /* + * xtime is atomically updated in timer_bh. + * jiffies - wall_jiffies + * is nonzero if the timer bottom half hasnt executed yet. + */ + if (jiffies - wall_jiffies) + tv->tv_usec += USECS_PER_JIFFY; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - read_unlock_irqrestore (&xtime_lock, flags); if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; @@ -85,7 +88,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq (&xtime_lock); + write_seqlock_irq (&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is @@ -105,7 +108,7 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq (&xtime_lock); + write_sequnlock_irq (&xtime_lock); } @@ -291,6 +294,8 @@ */ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + unsigned long seq; + if (mips_cpu.options & MIPS_CPU_COUNTER) { unsigned int count; @@ -340,19 +345,21 @@ * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be * called as close as possible to 500 ms before the new second starts. */ - read_lock (&xtime_lock); - if ((time_status & STA_UNSYNC) == 0 && - xtime.tv_sec > last_rtc_update + 660 && - xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && - xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { - if (rtc_set_time(xtime.tv_sec) == 0) { - last_rtc_update = xtime.tv_sec; - } else { - last_rtc_update = xtime.tv_sec - 600; - /* do it again in 60 s */ + do { + seq = read_seqbegin(&xtime_lock); + + if ((time_status & STA_UNSYNC) == 0 && + xtime.tv_sec > last_rtc_update + 660 && + xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && + xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { + if (rtc_set_time(xtime.tv_sec) == 0) { + last_rtc_update = xtime.tv_sec; + } else { + last_rtc_update = xtime.tv_sec - 600; + /* do it again in 60 s */ + } } - } - read_unlock (&xtime_lock); + } while (read_seqretry(&xtime_lock, seq)); /* * If jiffies has overflowed in this timer_interrupt we must diff -Nru a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c --- a/arch/mips/mips-boards/generic/time.c Sun Feb 9 21:13:33 2003 +++ b/arch/mips/mips-boards/generic/time.c Sun Feb 9 21:13:33 2003 @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -45,7 +46,6 @@ static unsigned long r4k_offset; /* Amount to increment compare reg each time */ static unsigned long r4k_cur; /* What counter should be at next timer irq */ -extern rwlock_t xtime_lock; #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) @@ -133,7 +133,9 @@ */ void mips_timer_interrupt(struct pt_regs *regs) { + unsigned long flags; int irq = 7; + unsigned long seq; if (r4k_offset == 0) goto null; @@ -149,18 +151,21 @@ * within 500ms before the * next second starts, * thus the following code. */ - read_lock(&xtime_lock); - if ((time_status & STA_UNSYNC) == 0 - && xtime.tv_sec > last_rtc_update + 660 - && xtime.tv_usec >= 500000 - (tick >> 1) - && xtime.tv_usec <= 500000 + (tick >> 1)) - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* do it again in 60 s */ - last_rtc_update = xtime.tv_sec - 600; - read_unlock(&xtime_lock); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + + if ((time_status & STA_UNSYNC) == 0 + && xtime.tv_sec > last_rtc_update + 660 + && xtime.tv_usec >= 500000 - (tick >> 1) + && xtime.tv_usec <= 500000 + (tick >> 1)) + if (set_rtc_mmss(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + /* do it again in 60 s */ + last_rtc_update = xtime.tv_sec - 600; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + if ((timer_tick_count++ % HZ) == 0) { mips_display_message(&display_string[display_count++]); if (display_count == MAX_DISPLAY_COUNT) @@ -267,10 +272,10 @@ change_cp0_status(ST0_IM, ALLINTS); /* Read time from the RTC chipset. */ - write_lock_irqsave (&xtime_lock, flags); + write_seqlock_irqsave (&xtime_lock, flags); xtime.tv_sec = get_mips_time(); xtime.tv_usec = 0; - write_unlock_irqrestore(&xtime_lock, flags); + write_sequnlock_irqrestore(&xtime_lock, flags); } /* This is for machines which generate the exact clock. */ @@ -363,20 +368,24 @@ void do_gettimeofday(struct timeval *tv) { - unsigned int flags; + unsigned long flags; + unsigned long seq; + + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); - read_lock_irqsave (&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_fast_gettimeoffset(); + *tv = xtime; + tv->tv_usec += do_fast_gettimeoffset(); - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; + /* + * xtime is atomically updated in timer_bh. + * jiffies - wall_jiffies + * is nonzero if the timer bottom half hasnt executed yet. + */ + if (jiffies - wall_jiffies) + tv->tv_usec += USECS_PER_JIFFY; - read_unlock_irqrestore (&xtime_lock, flags); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; @@ -386,7 +395,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq (&xtime_lock); + write_seqlock_irq (&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec correctly. * However, the value in this location is is value at the last tick. @@ -406,5 +415,5 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq (&xtime_lock); + write_sequnlock_irq (&xtime_lock); } diff -Nru a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile --- a/arch/mips/mm/Makefile Sun Feb 9 21:13:33 2003 +++ b/arch/mips/mm/Makefile Sun Feb 9 21:13:33 2003 @@ -2,7 +2,6 @@ # Makefile for the Linux/MIPS-specific parts of the memory manager. # -export-objs += ioremap.o umap.o obj-y += extable.o init.o ioremap.o fault.o loadmmu.o obj-$(CONFIG_CPU_R3000) += r2300.o diff -Nru a/arch/mips/philips/nino/time.c b/arch/mips/philips/nino/time.c --- a/arch/mips/philips/nino/time.c Sun Feb 9 21:13:28 2003 +++ b/arch/mips/philips/nino/time.c Sun Feb 9 21:13:28 2003 @@ -19,12 +19,12 @@ #include #include #include +#include #include #include #include extern volatile unsigned long wall_jiffies; -extern rwlock_t xtime_lock; static struct timeval xbase; @@ -62,29 +62,31 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; unsigned long high, low; - read_lock_irqsave(&xtime_lock, flags); - // 40 bit RTC, driven by 32khz source: - // +-----------+-----------------------------------------+ - // | HHHH.HHHH | LLLL.LLLL.LLLL.LLLL.LMMM.MMMM.MMMM.MMMM | - // +-----------+-----------------------------------------+ - readRTC(&high,&low); - tv->tv_sec = (high << 17) | (low >> 15); - tv->tv_usec = (low % 32768) * 1953 / 64; - tv->tv_sec += xbase.tv_sec; - tv->tv_usec += xbase.tv_usec; + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); - tv->tv_usec += do_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. lost_ticks is - * nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; - - read_unlock_irqrestore(&xtime_lock, flags); + // 40 bit RTC, driven by 32khz source: + // +-----------+-----------------------------------------+ + // | HHHH.HHHH | LLLL.LLLL.LLLL.LLLL.LMMM.MMMM.MMMM.MMMM | + // +-----------+-----------------------------------------+ + readRTC(&high,&low); + tv->tv_sec = (high << 17) | (low >> 15); + tv->tv_usec = (low % 32768) * 1953 / 64; + tv->tv_sec += xbase.tv_sec; + tv->tv_usec += xbase.tv_usec; + + tv->tv_usec += do_gettimeoffset(); + + /* + * xtime is atomically updated in timer_bh. lost_ticks is + * nonzero if the timer bottom half hasnt executed yet. + */ + if (jiffies - wall_jiffies) + tv->tv_usec += USECS_PER_JIFFY; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; @@ -94,7 +96,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is * is value at the last tick. @@ -118,7 +120,7 @@ time_state = TIME_BAD; time_maxerror = MAXPHASE; time_esterror = MAXPHASE; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } static int set_rtc_mmss(unsigned long nowtime) diff -Nru a/arch/mips64/Kconfig b/arch/mips64/Kconfig --- a/arch/mips64/Kconfig Sun Feb 9 21:13:30 2003 +++ b/arch/mips64/Kconfig Sun Feb 9 21:13:30 2003 @@ -361,7 +361,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config MIPS32_COMPAT @@ -406,7 +406,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. endmenu @@ -464,7 +464,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -491,7 +491,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -608,7 +608,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/mips64/Makefile b/arch/mips64/Makefile --- a/arch/mips64/Makefile Sun Feb 9 21:13:30 2003 +++ b/arch/mips64/Makefile Sun Feb 9 21:13:30 2003 @@ -128,7 +128,7 @@ LDFLAGS_vmlinux += -Ttext $(LOADADDR) -HEAD := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o +head-y := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o SUBDIRS := arch/mips64/tools $(SUBDIRS) core-y += arch/mips64/kernel/ arch/mips64/mm/ diff -Nru a/arch/mips64/kernel/Makefile b/arch/mips64/kernel/Makefile --- a/arch/mips64/kernel/Makefile Sun Feb 9 21:13:31 2003 +++ b/arch/mips64/kernel/Makefile Sun Feb 9 21:13:31 2003 @@ -4,8 +4,6 @@ EXTRA_TARGETS := head.o init_task.o -export-objs := mips64_ksyms.o - obj-y := branch.o entry.o proc.o process.o ptrace.o r4k_cache.o r4k_fpu.o \ r4k_genex.o r4k_switch.o r4k_tlb.o r4k_tlb_debug.o r4k_tlb_glue.o \ scall_64.o semaphore.o setup.o signal.o softfp.o syscall.o \ diff -Nru a/arch/mips64/mips-boards/generic/time.c b/arch/mips64/mips-boards/generic/time.c --- a/arch/mips64/mips-boards/generic/time.c Sun Feb 9 21:13:29 2003 +++ b/arch/mips64/mips-boards/generic/time.c Sun Feb 9 21:13:29 2003 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -44,7 +45,6 @@ static unsigned long r4k_offset; /* Amount to increment compare reg each time */ static unsigned long r4k_cur; /* What counter should be at next timer irq */ -extern rwlock_t xtime_lock; #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) @@ -132,6 +132,8 @@ */ void mips_timer_interrupt(struct pt_regs *regs) { + unsigned long flags; + unsigned long seq; int irq = 7; if (r4k_offset == 0) @@ -148,17 +150,20 @@ * within 500ms before the * next second starts, * thus the following code. */ - read_lock(&xtime_lock); - if ((time_status & STA_UNSYNC) == 0 - && xtime.tv_sec > last_rtc_update + 660 - && xtime.tv_usec >= 500000 - (tick >> 1) - && xtime.tv_usec <= 500000 + (tick >> 1)) - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* do it again in 60 s */ - last_rtc_update = xtime.tv_sec - 600; - read_unlock(&xtime_lock); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + + if ((time_status & STA_UNSYNC) == 0 + && xtime.tv_sec > last_rtc_update + 660 + && xtime.tv_usec >= 500000 - (tick >> 1) + && xtime.tv_usec <= 500000 + (tick >> 1)) + if (set_rtc_mmss(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + /* do it again in 60 s */ + last_rtc_update = xtime.tv_sec - 600; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + if ((timer_tick_count++ % HZ) == 0) { mips_display_message(&display_string[display_count++]); @@ -266,10 +271,10 @@ set_cp0_status(ST0_IM, ALLINTS); /* Read time from the RTC chipset. */ - write_lock_irqsave (&xtime_lock, flags); + write_seqlock_irqsave (&xtime_lock, flags); xtime.tv_sec = get_mips_time(); xtime.tv_usec = 0; - write_unlock_irqrestore(&xtime_lock, flags); + write_sequnlock_irqrestore(&xtime_lock, flags); } /* This is for machines which generate the exact clock. */ @@ -352,20 +357,25 @@ void do_gettimeofday(struct timeval *tv) { - unsigned int flags; + unsigned long flags; + unsigned long seq; - read_lock_irqsave (&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_fast_gettimeoffset(); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; + *tv = xtime; + tv->tv_usec += do_fast_gettimeoffset(); + + /* + * xtime is atomically updated in timer_bh. + * jiffies - wall_jiffies + * is nonzero if the timer bottom half hasnt executed yet. + */ + if (jiffies - wall_jiffies) + tv->tv_usec += USECS_PER_JIFFY; + + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - read_unlock_irqrestore (&xtime_lock, flags); if (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; @@ -375,7 +385,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq (&xtime_lock); + write_seqlock_irq (&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec correctly. * However, the value in this location is is value at the last tick. @@ -395,5 +405,5 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq (&xtime_lock); + write_sequnlock_irq (&xtime_lock); } diff -Nru a/arch/mips64/mm/Makefile b/arch/mips64/mm/Makefile --- a/arch/mips64/mm/Makefile Sun Feb 9 21:13:28 2003 +++ b/arch/mips64/mm/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux/MIPS-specific parts of the memory manager. # -export-objs += umap.o - obj-y := extable.o init.o fault.o loadmmu.o obj-$(CONFIG_CPU_R4300) += r4xx0.o diff -Nru a/arch/mips64/sgi-ip22/ip22-timer.c b/arch/mips64/sgi-ip22/ip22-timer.c --- a/arch/mips64/sgi-ip22/ip22-timer.c Sun Feb 9 21:13:32 2003 +++ b/arch/mips64/sgi-ip22/ip22-timer.c Sun Feb 9 21:13:32 2003 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -32,8 +33,6 @@ static unsigned long r4k_offset; /* Amount to increment compare reg each time */ static unsigned long r4k_cur; /* What counter should be at next timer irq */ -extern rwlock_t xtime_lock; - static inline void ack_r4ktimer(unsigned long newval) { write_32bit_cp0_register(CP0_COMPARE, newval); @@ -86,7 +85,7 @@ unsigned long count; int irq = 7; - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); /* Ack timer and compute new compare. */ count = read_32bit_cp0_register(CP0_COUNT); /* This has races. */ @@ -116,7 +115,7 @@ /* do it again in 60s */ last_rtc_update = xtime.tv_sec - 600; } - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } static unsigned long dosample(volatile unsigned char *tcwp, @@ -224,10 +223,10 @@ set_cp0_status(ST0_IM, ALLINTS); sti(); - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); xtime.tv_sec = get_indy_time(); /* Read time from RTC. */ xtime.tv_usec = 0; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } void indy_8254timer_irq(void) @@ -243,20 +242,21 @@ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; + unsigned long seq; - read_lock_irqsave(&xtime_lock, flags); - *tv = xtime; - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin(&xtime_lock); + *tv = xtime; + } while (read_seqretry(&xtime_lock, seq)); } void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); xtime = *tv; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } diff -Nru a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c --- a/arch/mips64/sgi-ip27/ip27-timer.c Sun Feb 9 21:13:31 2003 +++ b/arch/mips64/sgi-ip27/ip27-timer.c Sun Feb 9 21:13:31 2003 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,6 @@ static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */ static long last_rtc_update; /* Last time the rtc clock got updated */ -extern rwlock_t xtime_lock; extern volatile unsigned long wall_jiffies; @@ -94,7 +94,7 @@ int cpuA = ((cputoslice(cpu)) == 0); int irq = 7; /* XXX Assign number */ - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); again: LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */ @@ -145,7 +145,7 @@ } } - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); if (softirq_pending(cpu)) do_softirq(); @@ -162,17 +162,20 @@ { unsigned long flags; unsigned long usec, sec; + unsigned long seq; - read_lock_irqsave(&xtime_lock, flags); - usec = do_gettimeoffset(); - { - unsigned long lost = jiffies - wall_jiffies; - if (lost) - usec += lost * (1000000 / HZ); - } - sec = xtime.tv_sec; - usec += xtime.tv_usec; - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + + usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += xtime.tv_usec; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; @@ -185,7 +188,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); tv->tv_usec -= do_gettimeoffset(); tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ); @@ -199,7 +202,7 @@ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } /* Includes for ioc3_init(). */ diff -Nru a/arch/parisc/Kconfig b/arch/parisc/Kconfig --- a/arch/parisc/Kconfig Sun Feb 9 21:13:33 2003 +++ b/arch/parisc/Kconfig Sun Feb 9 21:13:33 2003 @@ -199,7 +199,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config BINFMT_MISC @@ -224,7 +224,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. endmenu @@ -260,7 +260,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -327,7 +327,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/parisc/Makefile b/arch/parisc/Makefile --- a/arch/parisc/Makefile Sun Feb 9 21:13:36 2003 +++ b/arch/parisc/Makefile Sun Feb 9 21:13:36 2003 @@ -33,10 +33,10 @@ OBJCOPY_FLAGS =-O binary -R .note -R .comment -S -cflags-y := -D__linux__ -pipe -fno-strength-reduce +cflags-y := -pipe -# These should be on for older toolchains or SOM toolchains that don't -# enable them by default. +# These flags should be implied by an hppa-linux configuration, but they +# are not in gcc 3.2. cflags-y += -mno-space-regs -mfast-indirect-calls # No fixed-point multiply @@ -56,7 +56,6 @@ head-$(CONFIG_PARISC64) := arch/parisc/kernel/head64.o CFLAGS += $(cflags-y) -HEAD := $(head-y) core-y += $(addprefix arch/parisc/, kernel/pdc_cons.o kernel/process.o \ mm/ kernel/ hpux/ math-emu/ kernel/init_task.o ) @@ -95,9 +94,6 @@ @echo -n ' Generating $@' @$(generate-asm-offsets.h) < $< > $@.tmp @$(update-if-changed) - -archclean: -archmrproper: CLEAN_FILES += palo.conf lifimage include/asm-parisc/offsets.h \ include/asm-parisc/offsets.h.tmp diff -Nru a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile --- a/arch/parisc/kernel/Makefile Sun Feb 9 21:13:30 2003 +++ b/arch/parisc/kernel/Makefile Sun Feb 9 21:13:30 2003 @@ -9,8 +9,6 @@ AFLAGS_entry.o := -traditional AFLAGS_pacache.o := -traditional -export-objs := parisc_ksyms.o - obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \ pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \ ptrace.o hardware.o inventory.o drivers.o semaphore.o \ diff -Nru a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S --- a/arch/parisc/kernel/entry.S Sun Feb 9 21:13:29 2003 +++ b/arch/parisc/kernel/entry.S Sun Feb 9 21:13:29 2003 @@ -689,7 +689,7 @@ * (we don't store them in the sigcontext), so set them * to "proper" values now (otherwise we'll wind up restoring * whatever was last stored in the task structure, which might - * be inconsistant if an interrupt occured while on the gateway + * be inconsistent if an interrupt occured while on the gateway * page) Note that we may be "trashing" values the user put in * them, but we don't support the the user changing them. */ diff -Nru a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c --- a/arch/parisc/kernel/irq.c Sun Feb 9 21:13:31 2003 +++ b/arch/parisc/kernel/irq.c Sun Feb 9 21:13:31 2003 @@ -243,7 +243,7 @@ for (i = 0; i <= MAX_CPU_IRQ; i++) { struct irqaction *action = ®ion->action[i]; unsigned int irq_no = IRQ_FROM_REGION(regnr) + i; - int j=0; + int j = 0; if (!action->handler) continue; @@ -251,7 +251,7 @@ #ifdef CONFIG_SMP for (; j < NR_CPUS; j++) #endif - seq_printf(p, "%10u ", kstat_cpu(j).irqs[regnr][irq_no]); + seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq_no]); seq_printf(p, " %14s", region->data.name ? region->data.name : "N/A"); @@ -373,7 +373,7 @@ /* XXX FIXME : bits_wide indicates how wide the transaction ** data is allowed to be...we may need a different virt_irq ** if this one won't work. Another reason to index virtual - ** irq's into a table which can manage CPU/IRQ bit seperately. + ** irq's into a table which can manage CPU/IRQ bit separately. */ if (IRQ_OFFSET(virt_irq) > (1 << (bits_wide -1))) { @@ -388,7 +388,7 @@ int cpu = smp_processor_id(); irq_enter(); - ++kstat_cpu(cpu).irqs[IRQ_REGION(irq)][IRQ_OFFSET(irq)]; + ++kstat_cpu(cpu).irqs[irq]; DBG_IRQ(irq, ("do_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq))); diff -Nru a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c --- a/arch/parisc/kernel/module.c Sun Feb 9 21:13:37 2003 +++ b/arch/parisc/kernel/module.c Sun Feb 9 21:13:37 2003 @@ -13,6 +13,12 @@ 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 + + (c) 2003 Randolph Chung + + The best reference for this stuff is probably the Processor- + Specific ELF Supplement for PA-RISC: + http://ftp.parisc-linux.org/docs/elf-pa-hp.pdf */ #include #include @@ -21,19 +27,92 @@ #include #include -#if 0 +#if 1 #define DEBUGP printk #else #define DEBUGP(fmt...) #endif -enum parisc_fsel { - e_fsel, - e_lsel, - e_rsel, - e_lrsel, - e_rrsel + +#ifndef __LP64__ +struct got_entry { + Elf32_Addr addr; +}; + +struct fdesc_entry { + Elf32_Addr gp; + Elf32_Addr addr; +}; + +struct stub_entry { + Elf32_Word insns[2]; /* each stub entry has two insns */ +}; +#else +struct got_entry { + Elf64_Addr addr; +}; + +struct fdesc_entry { + Elf64_Addr dummy[2]; + Elf64_Addr gp; + Elf64_Addr addr; +}; + +struct stub_entry { + Elf64_Word insns[4]; /* each stub entry has four insns */ }; +#endif + +/* Field selection types defined by hppa */ +#define rnd(x) (((x)+0x1000)&~0x1fff) +/* fsel: full 32 bits */ +#define fsel(v,a) ((v)+(a)) +/* lsel: select left 21 bits */ +#define lsel(v,a) (((v)+(a))>>11) +/* rsel: select right 11 bits */ +#define rsel(v,a) (((v)+(a))&0x7ff) +/* lrsel with rounding of addend to nearest 8k */ +#define lrsel(v,a) (((v)+rnd(a))>>11) +/* rrsel with rounding of addend to nearest 8k */ +#define rrsel(v,a) ((((v)+rnd(a))&0x7ff)+((a)-rnd(a))) + +#define mask(x,sz) ((x) & ~((1<<(sz))-1)) + + +/* The reassemble_* functions prepare an immediate value for + insertion into an opcode. pa-risc uses all sorts of weird bitfields + in the instruction to hold the value. */ +static inline int reassemble_14(int as14) +{ + return (((as14 & 0x1fff) << 1) | + ((as14 & 0x2000) >> 13)); +} + +static inline int reassemble_17(int as17) +{ + return (((as17 & 0x10000) >> 16) | + ((as17 & 0x0f800) << 5) | + ((as17 & 0x00400) >> 8) | + ((as17 & 0x003ff) << 3)); +} + +static inline int reassemble_21(int as21) +{ + return (((as21 & 0x100000) >> 20) | + ((as21 & 0x0ffe00) >> 8) | + ((as21 & 0x000180) << 7) | + ((as21 & 0x00007c) << 14) | + ((as21 & 0x000003) << 12)); +} + +static inline int reassemble_22(int as22) +{ + return (((as22 & 0x200000) >> 21) | + ((as22 & 0x1f0000) << 5) | + ((as22 & 0x00f800) << 5) | + ((as22 & 0x000400) >> 8) | + ((as22 & 0x0003ff) << 3)); +} void *module_alloc(unsigned long size) { @@ -42,6 +121,81 @@ return vmalloc(size); } +#ifndef __LP64__ +static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n) +{ + return 0; +} + +static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n) +{ + return 0; +} + +static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n) +{ + unsigned long cnt = 0; + + for (; n > 0; n--, rela++) + { + switch (ELF32_R_TYPE(rela->r_info)) { + case R_PARISC_PCREL17F: + case R_PARISC_PCREL22F: + cnt++; + } + } + + return cnt; +} +#else +static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n) +{ + unsigned long cnt = 0; + + for (; n > 0; n--, rela++) + { + switch (ELF64_R_TYPE(rela->r_info)) { + case R_PARISC_LTOFF21L: + case R_PARISC_LTOFF14R: + case R_PARISC_PCREL22F: + cnt++; + } + } + + return cnt; +} + +static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n) +{ + unsigned long cnt = 3; /* 3 for finalize */ + + for (; n > 0; n--, rela++) + { + switch (ELF64_R_TYPE(rela->r_info)) { + case R_PARISC_FPTR64: + cnt++; + } + } + + return cnt; +} + +static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n) +{ + unsigned long cnt = 0; + + for (; n > 0; n--, rela++) + { + switch (ELF64_R_TYPE(rela->r_info)) { + case R_PARISC_PCREL22F: + cnt++; + } + } + + return cnt; +} +#endif + /* Free memory returned from module_alloc */ void module_free(struct module *mod, void *module_region) @@ -51,35 +205,145 @@ table entries. */ } -/* We don't need anything special. */ -long module_core_size(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - const char *secstrings, - struct module *module) +#define CONST +int module_frob_arch_sections(CONST Elf_Ehdr *hdr, + CONST Elf_Shdr *sechdrs, + CONST char *secstrings, + struct module *me) { - return module->core_size; + unsigned long gots = 0, fdescs = 0, stubs = 0; + unsigned int i; + + for (i = 1; i < hdr->e_shnum; i++) { + const Elf_Rela *rels = (void *)hdr + sechdrs[i].sh_offset; + unsigned long nrels = sechdrs[i].sh_size / sizeof(*rels); + + if (sechdrs[i].sh_type != SHT_RELA) + continue; + + /* some of these are not relevant for 32-bit/64-bit + * we leave them here to make the code common. the + * compiler will do its thing and optimize out the + * stuff we don't need + */ + gots += count_gots(rels, nrels); + fdescs += count_fdescs(rels, nrels); + stubs += count_stubs(rels, nrels); + } + + /* align things a bit */ + me->core_size = ALIGN(me->core_size, 16); + me->arch.got_offset = me->core_size; + me->core_size += gots * sizeof(struct got_entry); + + me->core_size = ALIGN(me->core_size, 16); + me->arch.fdesc_offset = me->core_size; + me->core_size += stubs * sizeof(struct fdesc_entry); + + me->core_size = ALIGN(me->core_size, 16); + me->arch.stub_offset = me->core_size; + me->core_size += stubs * sizeof(struct stub_entry); + + return 0; } -long module_init_size(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - const char *secstrings, - struct module *module) +static Elf_Addr get_got(struct module *me, unsigned long value, long addend) { - return module->init_size; + unsigned int i; + struct got_entry *got; + + value += addend; + + BUG_ON(value == 0); + + got = me->module_core + me->arch.got_offset; + for (i = 0; got[i].addr; i++) + if (got[i].addr == value) + return i * sizeof(struct got_entry); + + got[i].addr = value; + return i * sizeof(struct got_entry); } -int module_frob_arch_sections(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - char *secstrings, - struct module *mod) +static Elf_Addr get_fdesc(struct module *me, unsigned long value) { - /* parisc should not need this ... */ - printk(KERN_ERR "module %s: %s not yet implemented.\n", - mod->name, __FUNCTION__); - return 0; + struct fdesc_entry *fdesc = me->module_core + me->arch.fdesc_offset; + + if (!value) { + printk(KERN_ERR "%s: zero OPD requested!\n", me->name); + return 0; + } + + /* Look for existing fdesc entry. */ + while (fdesc->addr) { + if (fdesc->addr == value) + return (Elf_Addr)fdesc; + fdesc++; + } + + /* Create new one */ + fdesc->addr = value; + fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset; + return (Elf_Addr)fdesc; } +static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, + int millicode) +{ + unsigned long i; + struct stub_entry *stub; + i = me->arch.stub_count++; + stub = me->module_core + me->arch.stub_offset + + i * sizeof(struct stub_entry); + +#ifndef __LP64__ +/* for 32-bit the stub looks like this: + * ldil L'XXX,%r1 + * be,n R'XXX(%sr4,%r1) + */ + stub->insns[0] = 0x20200000; /* ldil L'XXX,%r1 */ + stub->insns[1] = 0xe0202002; /* be,n R'XXX(%sr4,%r1) */ + + stub->insns[0] |= reassemble_21(lrsel(value, addend)); + stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4); +#else +/* for 64-bit we have two kinds of stubs: + * for normal function calls: + * ldd 0(%dp),%dp + * ldd 10(%dp), %r1 + * bve (%r1) + * ldd 18(%dp), %dp + * + * for millicode: + * ldil 0, %r1 + * ldo 0(%r1), %r1 + * ldd 10(%r1), %r1 + * bve,n (%r1) + */ + if (!millicode) + { + stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */ + stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */ + stub->insns[2] = 0xe820d000; /* bve (%r1) */ + stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */ + + stub->insns[0] |= reassemble_21(get_got(me, value, addend)); + } + else + { + stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ + stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ + stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */ + stub->insns[3] = 0xe820d002; /* bve,n (%r1) */ + + stub->insns[0] |= reassemble_21(lrsel(value, addend)); + stub->insns[1] |= reassemble_14(rrsel(value, addend)); + } +#endif + + return (Elf_Addr)stub; +} int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, @@ -104,7 +368,10 @@ Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; Elf32_Sym *sym; Elf32_Word *loc; - Elf32_Addr value; + Elf32_Addr val; + Elf32_Sword addend; + Elf32_Addr dot; + register unsigned long dp asm ("r27"); DEBUGP("Applying relocate section %u to %u\n", relsec, sechdrs[relsec].sh_info); @@ -120,59 +387,81 @@ me->name, strtab + sym->st_name); return -ENOENT; } + dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03; - value = sym->st_value + rel[i].r_addend; + val = sym->st_value; + addend = rel[i].r_addend; - DEBUGP("Symbol %s loc 0x%lx value 0x%lx: ", +#if 0 +#define r(t) ELF32_R_TYPE(rel[i].r_info)==t ? #t : + DEBUGP("Symbol %s loc 0x%x val 0x%x addend 0x%x: %s\n", strtab + sym->st_name, - (uint32_t)loc, value); + (uint32_t)loc, val, addend, + r(R_PARISC_PLABEL32) + r(R_PARISC_DIR32) + r(R_PARISC_DIR21L) + r(R_PARISC_DIR14R) + r(R_PARISC_SEGREL32) + r(R_PARISC_DPREL21L) + r(R_PARISC_DPREL14R) + r(R_PARISC_PCREL17F) + r(R_PARISC_PCREL22F) + "UNKNOWN"); +#undef r +#endif switch (ELF32_R_TYPE(rel[i].r_info)) { case R_PARISC_PLABEL32: /* 32-bit function address */ - DEBUGP("R_PARISC_PLABEL32\n"); + /* no function descriptors... */ + *loc = fsel(val, addend); break; case R_PARISC_DIR32: /* direct 32-bit ref */ - DEBUGP("R_PARISC_DIR32\n"); + *loc = fsel(val, addend); break; case R_PARISC_DIR21L: /* left 21 bits of effective address */ - DEBUGP("R_PARISC_DIR21L\n"); + *loc = mask(*loc, 21) | reassemble_21(lrsel(val, addend)); break; case R_PARISC_DIR14R: /* right 14 bits of effective address */ - DEBUGP("R_PARISC_DIR14R\n"); + *loc = mask(*loc, 14) | reassemble_14(rrsel(val, addend)); break; case R_PARISC_SEGREL32: /* 32-bit segment relative address */ - DEBUGP("R_PARISC_SEGREL32\n"); + val -= (uint32_t)me->module_core; + *loc = fsel(val, addend); break; case R_PARISC_DPREL21L: /* left 21 bit of relative address */ - DEBUGP("R_PARISC_DPREL21L\n"); + val -= dp; + *loc = mask(*loc, 21) | reassemble_21(lrsel(val, addend) - dp); break; case R_PARISC_DPREL14R: /* right 14 bit of relative address */ - DEBUGP("R_PARISC_DPREL14R\n"); + val -= dp; + *loc = mask(*loc, 14) | reassemble_14(rrsel(val, addend) - dp); break; case R_PARISC_PCREL17F: /* 17-bit PC relative address */ - DEBUGP("R_PARISC_PCREL17F\n"); + val = get_stub(me, val, addend, 0) - dot - 8; + *loc = (*loc&0x1f1ffd) | reassemble_17(val); break; case R_PARISC_PCREL22F: - /* 22-bit PC relative address */ - DEBUGP("R_PARISC_PCREL22F\n"); + /* 22-bit PC relative address; only defined for pa20 */ + val = get_stub(me, val, addend, 0) - dot - 8; + *loc = (*loc&0x3ff1ffd) | reassemble_22(val); break; default: - printk(KERN_ERR "module %s: Unknown relocation: %Lu\n", + printk(KERN_ERR "module %s: Unknown relocation: %u\n", me->name, ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } } - return -ENOEXEC; + return 0; } #else @@ -186,7 +475,9 @@ Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr; Elf64_Sym *sym; Elf64_Word *loc; - Elf64_Addr value; + Elf64_Addr val; + Elf64_Sxword addend; + Elf64_Addr dot; DEBUGP("Applying relocate section %u to %u\n", relsec, sechdrs[relsec].sh_info); @@ -202,38 +493,56 @@ me->name, strtab + sym->st_name); return -ENOENT; } + dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03; - value = sym->st_value + rel[i].r_addend; + val = sym->st_value; + addend = rel[i].r_addend; - DEBUGP("Symbol %s loc 0x%Lx value 0x%Lx: ", +#if 1 +#define r(t) ELF64_R_TYPE(rel[i].r_info)==t ? #t : + DEBUGP("Symbol %s loc %p val 0x%Lx addend 0x%Lx: %s\n", strtab + sym->st_name, - (uint64_t)loc, value); + loc, val, addend, + r(R_PARISC_LTOFF14R) + r(R_PARISC_LTOFF21L) + r(R_PARISC_PCREL22F) + r(R_PARISC_DIR64) + r(R_PARISC_SEGREL32) + r(R_PARISC_FPTR64) + "UNKNOWN"); +#undef r +#endif switch (ELF64_R_TYPE(rel[i].r_info)) { - case R_PARISC_LTOFF14R: - /* LT-relative; right 14 bits */ - DEBUGP("R_PARISC_LTOFF14R\n"); - break; case R_PARISC_LTOFF21L: /* LT-relative; left 21 bits */ - DEBUGP("R_PARISC_LTOFF21L\n"); + *loc = mask(*loc, 21) | reassemble_21(get_got(me, val, addend)); + break; + case R_PARISC_LTOFF14R: + /* L(ltoff(val+addend)) */ + /* LT-relative; right 14 bits */ + *loc = mask(*loc, 14) | reassemble_14(get_got(me, val, addend)); break; case R_PARISC_PCREL22F: /* PC-relative; 22 bits */ - DEBUGP("R_PARISC_PCREL22F\n"); + if (strncmp(strtab + sym->st_name, "$$", 2) == 0) + val = get_stub(me, val, addend, 1) - dot - 8; + else + val = get_stub(me, val, addend, 0) - dot - 8; + *loc = (*loc&0x3ff1ffd) | reassemble_22(val); break; case R_PARISC_DIR64: /* 64-bit effective address */ - DEBUGP("R_PARISC_DIR64\n"); - *loc = value; + *loc = fsel(val, addend); break; case R_PARISC_SEGREL32: /* 32-bit segment relative address */ - DEBUGP("R_PARISC_SEGREL32\n"); + val -= (uint64_t)me->module_core; + *loc = fsel(val, addend); break; case R_PARISC_FPTR64: /* 64-bit function address */ - DEBUGP("R_PARISC_FPTR64\n"); + *loc = get_fdesc(me, val+addend); break; default: @@ -242,7 +551,7 @@ return -ENOEXEC; } } - return -ENOEXEC; + return 0; } #endif @@ -250,5 +559,14 @@ const Elf_Shdr *sechdrs, struct module *me) { +#ifdef __LP64__ + me->init = (void *)get_fdesc(me, (Elf_Addr)me->init); +#ifdef CONFIG_MODULE_UNLOAD + if (me->cleanup) + me->cleanup = (void *)get_fdesc(me, (Elf_Addr)me->cleanup); + if (me->destroy) + me->destroy = (void *)get_fdesc(me, (Elf_Addr)me->destroy); +#endif +#endif return 0; } diff -Nru a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c --- a/arch/parisc/kernel/parisc_ksyms.c Sun Feb 9 21:13:37 2003 +++ b/arch/parisc/kernel/parisc_ksyms.c Sun Feb 9 21:13:37 2003 @@ -31,10 +31,6 @@ EXPORT_SYMBOL(get_pci_node_path); #endif -#ifdef CONFIG_IOMMU_CCIO -EXPORT_SYMBOL(ccio_get_fake); -#endif - #include #include EXPORT_SYMBOL(enable_irq); diff -Nru a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c --- a/arch/parisc/kernel/signal.c Sun Feb 9 21:13:36 2003 +++ b/arch/parisc/kernel/signal.c Sun Feb 9 21:13:36 2003 @@ -118,11 +118,11 @@ #endif sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->gr[28] = -EINTR; while (1) { @@ -177,10 +177,10 @@ goto give_sigsegv; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); /* Good thing we saved the old gr[30], eh? */ if (restore_sigcontext(&frame->uc.uc_mcontext, regs)) @@ -407,11 +407,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } return 1; } diff -Nru a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c --- a/arch/parisc/kernel/signal32.c Sun Feb 9 21:13:29 2003 +++ b/arch/parisc/kernel/signal32.c Sun Feb 9 21:13:29 2003 @@ -17,59 +17,6 @@ struct sigaction32 sa; }; -typedef unsigned int old_sigset_t32; - -static int -put_old_sigset32(old_sigset_t32 *up, old_sigset_t *set) -{ - old_sigset_t32 set32 = *set; - return put_user(set32, up); -} - -static int -get_old_segset32(old_sigset_t32 *up, old_sigset_t *set) -{ - old_sigset_t32 set32; - int r; - - if ((r = get_user(set32, up)) == 0) - *set = set32; - - return r; -} - -long -sys32_sigpending(old_sigset_t32 *set) -{ - extern long sys_sigpending(old_sigset_t *set); - old_sigset_t pending; - int ret; - - KERNEL_SYSCALL(ret, sys_sigpending, &pending); - - /* can't put_user an old_sigset_t -- it is too big */ - if (put_old_sigset32(set, &pending)) - return -EFAULT; - - return ret; -} - -int sys32_sigprocmask(int how, old_sigset_t32 *set, - old_sigset_t32 *oset) -{ - extern int sys_sigprocmask(int how, old_sigset_t *set, - old_sigset_t *oset); - old_sigset_t s; - int ret; - - if (set && get_old_segset32 (set, &s)) - return -EFAULT; - KERNEL_SYSCALL(ret, sys_sigprocmask, how, set ? &s : NULL, oset ? &s : NULL); - if (!ret && oset && put_old_sigset32(oset, &s)) - return -EFAULT; - return ret; -} - static inline void sigset_32to64(sigset_t *s64, sigset_t32 *s32) { diff -Nru a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c --- a/arch/parisc/kernel/sys_parisc32.c Sun Feb 9 21:13:30 2003 +++ b/arch/parisc/kernel/sys_parisc32.c Sun Feb 9 21:13:30 2003 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -314,74 +315,6 @@ return -ENOSYS; } -/* 32-bit user apps use struct statfs which uses 'long's */ -struct statfs32 { - __s32 f_type; - __s32 f_bsize; - __s32 f_blocks; - __s32 f_bfree; - __s32 f_bavail; - __s32 f_files; - __s32 f_ffree; - __kernel_fsid_t f_fsid; - __s32 f_namelen; - __s32 f_spare[6]; -}; - -/* convert statfs struct to statfs32 struct and copy result to user */ -static unsigned long statfs32_to_user(struct statfs32 *ust32, struct statfs *st) -{ - struct statfs32 st32; -#undef CP -#define CP(a) st32.a = st->a - CP(f_type); - CP(f_bsize); - CP(f_blocks); - CP(f_bfree); - CP(f_bavail); - CP(f_files); - CP(f_ffree); - CP(f_fsid); - CP(f_namelen); - return copy_to_user(ust32, &st32, sizeof st32); -} - -/* The following statfs calls are copies of code from linux/fs/open.c and - * should be checked against those from time to time */ -asmlinkage long sys32_statfs(const char * path, struct statfs32 * buf) -{ - struct nameidata nd; - int error; - - error = user_path_walk(path, &nd); - if (!error) { - struct statfs tmp; - error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); - if (!error && statfs32_to_user(buf, &tmp)) - error = -EFAULT; - path_release(&nd); - } - return error; -} - -asmlinkage long sys32_fstatfs(unsigned int fd, struct statfs32 * buf) -{ - struct file * file; - struct statfs tmp; - int error; - - error = -EBADF; - file = fget(fd); - if (!file) - goto out; - error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); - if (!error && statfs32_to_user(buf, &tmp)) - error = -EFAULT; - fput(file); -out: - return error; -} - extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) @@ -2429,21 +2362,23 @@ { struct sysinfo val; int err; - extern rwlock_t xtime_lock; + unsigned long seq; /* We don't need a memset here because we copy the * struct to userspace once element at a time. */ - read_lock_irq(&xtime_lock); - val.uptime = jiffies / HZ; + do { + seq = read_seqbegin(&xtime_lock); + val.uptime = jiffies / HZ; + + val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); + val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); + val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); - val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); - val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); - val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); + val.procs = nr_threads; + } while (read_seqretry(&xtime_lock, seq)); - val.procs = nr_threads; - read_unlock_irq(&xtime_lock); si_meminfo(&val); si_swapinfo(&val); diff -Nru a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S --- a/arch/parisc/kernel/syscall.S Sun Feb 9 21:13:37 2003 +++ b/arch/parisc/kernel/syscall.S Sun Feb 9 21:13:37 2003 @@ -425,30 +425,27 @@ /* I don't like this */ ENTRY_UHOH(sgetmask) ENTRY_UHOH(ssetmask) - ENTRY_SAME(setreuid) /* 70 */ + ENTRY_SAME(setreuid) /* 70 */ ENTRY_SAME(setregid) ENTRY_SAME(mincore) - ENTRY_DIFF(sigpending) + ENTRY_COMP(sigpending) ENTRY_SAME(sethostname) /* Following 3 have linux-common-code structs containing longs -( */ - ENTRY_DIFF(setrlimit) /* 75 */ + ENTRY_DIFF(setrlimit) /* 75 */ ENTRY_DIFF(getrlimit) ENTRY_DIFF(getrusage) /* struct timeval and timezone are maybe?? consistent wide and narrow */ ENTRY_DIFF(gettimeofday) ENTRY_DIFF(settimeofday) - ENTRY_SAME(getgroups) /* 80 */ + ENTRY_SAME(getgroups) /* 80 */ ENTRY_SAME(setgroups) /* struct socketaddr... */ ENTRY_SAME(sendto) ENTRY_SAME(symlink) /* see stat comment */ ENTRY_COMP(newlstat) - ENTRY_SAME(readlink) /* 85 */ - /* suspect we'll need some work for narrow shlibs on wide kernel */ - /* NOTE this doesn't get used when I boot 32-bit userspace */ - /* containing working shlib apps -- can this be nuked? */ - ENTRY_UHOH(uselib) + ENTRY_SAME(readlink) /* 85 */ + ENTRY_SAME(ni_syscall) /* was uselib */ ENTRY_SAME(swapon) ENTRY_SAME(reboot) ENTRY_SAME(mmap2) @@ -461,17 +458,15 @@ ENTRY_SAME(getpriority) ENTRY_SAME(setpriority) ENTRY_SAME(recv) - ENTRY_DIFF(statfs) - ENTRY_DIFF(fstatfs) /* 100 */ + ENTRY_COMP(statfs) + ENTRY_COMP(fstatfs) /* 100 */ ENTRY_SAME(stat64) - /* don't think hppa glibc even provides an entry pt for this - * so disable for now */ - ENTRY_UHOH(socketcall) + ENTRY_SAME(ni_syscall) /* was socketcall */ ENTRY_SAME(syslog) /* even though manpage says struct timeval contains longs, ours has * time_t and suseconds_t -- both of which are safe wide/narrow */ ENTRY_COMP(setitimer) - ENTRY_COMP(getitimer) /* 105 */ + ENTRY_COMP(getitimer) /* 105 */ ENTRY_SAME(capget) ENTRY_SAME(capset) ENTRY_OURS(pread64) @@ -494,10 +489,10 @@ ENTRY_SAME(recvfrom) /* struct timex contains longs */ ENTRY_DIFF(adjtimex) - ENTRY_SAME(mprotect) /* 125 */ + ENTRY_SAME(mprotect) /* 125 */ /* old_sigset_t forced to 32 bits. Beware glibc sigset_t */ - ENTRY_DIFF(sigprocmask) - ENTRY_SAME(ni_syscall) /* create_module */ + ENTRY_COMP(sigprocmask) + ENTRY_SAME(ni_syscall) /* create_module */ ENTRY_SAME(init_module) ENTRY_SAME(delete_module) ENTRY_SAME(ni_syscall) /* 130: get_kernel_syms */ @@ -547,13 +542,13 @@ ENTRY_COMP(nanosleep) ENTRY_SAME(mremap) ENTRY_SAME(setresuid) - ENTRY_SAME(getresuid) /* 165 */ + ENTRY_SAME(getresuid) /* 165 */ ENTRY_DIFF(sigaltstack_wrapper) ENTRY_SAME(ni_syscall) /* query_module */ ENTRY_SAME(poll) /* structs contain pointers and an in_addr... */ ENTRY_DIFF(nfsservctl) - ENTRY_SAME(setresgid) /* 170 */ + ENTRY_SAME(setresgid) /* 170 */ ENTRY_SAME(getresgid) ENTRY_SAME(prctl) /* signals need a careful review */ @@ -594,15 +589,9 @@ ENTRY_OURS(ftruncate64) /* 200 */ ENTRY_SAME(getdents64) ENTRY_DIFF(fcntl64) -#ifdef CONFIG_XFS_FS - ENTRY_SAME(attrctl) - ENTRY_SAME(acl_get) - ENTRY_SAME(acl_set) /* 205 */ -#else ENTRY_SAME(ni_syscall) ENTRY_SAME(ni_syscall) ENTRY_SAME(ni_syscall) /* 205 */ -#endif ENTRY_SAME(gettid) ENTRY_SAME(readahead) ENTRY_SAME(ni_syscall) /* tkill */ diff -Nru a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c --- a/arch/parisc/kernel/time.c Sun Feb 9 21:13:31 2003 +++ b/arch/parisc/kernel/time.c Sun Feb 9 21:13:31 2003 @@ -36,7 +36,6 @@ /* xtime and wall_jiffies keep wall-clock time */ extern unsigned long wall_jiffies; -extern rwlock_t xtime_lock; static long clocktick; /* timer cycles per tick */ static long halftick; @@ -115,9 +114,9 @@ smp_do_timer(regs); #endif if (cpu == 0) { - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); do_timer(regs); - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } } @@ -172,16 +171,14 @@ void do_gettimeofday (struct timeval *tv) { - unsigned long flags, usec, sec; + unsigned long flags, seq, usec, sec; - read_lock_irqsave(&xtime_lock, flags); - { + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = gettimeoffset(); - sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); - } - read_unlock_irqrestore(&xtime_lock, flags); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; @@ -195,7 +192,7 @@ void do_settimeofday (struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); { /* * This is revolting. We need to set "xtime" @@ -219,7 +216,7 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; } - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } @@ -241,10 +238,10 @@ mtctl(next_tick, 16); if(pdc_tod_read(&tod_data) == 0) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); xtime.tv_sec = tod_data.tod_sec; xtime.tv_nsec = tod_data.tod_usec * 1000; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } else { printk(KERN_ERR "Error reading tod clock\n"); xtime.tv_sec = 0; diff -Nru a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c --- a/arch/parisc/kernel/traps.c Sun Feb 9 21:13:37 2003 +++ b/arch/parisc/kernel/traps.c Sun Feb 9 21:13:37 2003 @@ -123,7 +123,11 @@ } -static int kstack_depth_to_print = 48; +#ifndef __LP64__ +static int kstack_depth_to_print = 64 * 4; +#else +static int kstack_depth_to_print = 128 * 4; +#endif void show_stack(unsigned long *sp) { diff -Nru a/arch/ppc/8xx_io/Makefile b/arch/ppc/8xx_io/Makefile --- a/arch/ppc/8xx_io/Makefile Sun Feb 9 21:13:37 2003 +++ b/arch/ppc/8xx_io/Makefile Sun Feb 9 21:13:37 2003 @@ -2,8 +2,6 @@ # Makefile for the linux MPC8xx ppc-specific parts of comm processor # -export-objs := fec.o - obj-y := commproc.o uart.o obj-$(CONFIG_FEC_ENET) += fec.o diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig --- a/arch/ppc/Kconfig Sun Feb 9 21:13:37 2003 +++ b/arch/ppc/Kconfig Sun Feb 9 21:13:37 2003 @@ -776,7 +776,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. source "drivers/pci/Kconfig" @@ -989,9 +989,9 @@ for which 8 pin to DB25 adapters were supplied. The card also had jumpers internally to toggle various pinning configurations. - This driver can be built as a module; but then "generic_serial.o" + This driver can be built as a module; but then "generic_serial" will also be built as a module. This has to be loaded before - "ser_a2232.o". If you want to do this, answer M here and read + "ser_a2232". If you want to do this, answer M here and read "". config WHIPPET_SERIAL @@ -1010,7 +1010,7 @@ 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 apne.o. If you want to compile it as a + want). The module is called apne. If you want to compile it as a module, say M here and read . config SERIAL_CONSOLE @@ -1192,7 +1192,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -1219,7 +1219,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -1428,7 +1428,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile --- a/arch/ppc/Makefile Sun Feb 9 21:13:28 2003 +++ b/arch/ppc/Makefile Sun Feb 9 21:13:28 2003 @@ -36,15 +36,12 @@ CFLAGS += $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') endif -head-y := head.o -head-$(CONFIG_8xx) := head_8xx.o -head-$(CONFIG_4xx) := head_4xx.o -head-$(CONFIG_440) := head_44x.o - -HEAD := arch/ppc/kernel/$(head-y) -ifdef CONFIG_6xx - HEAD += arch/ppc/kernel/idle_6xx.o -endif +head-y := arch/ppc/kernel/head.o +head-$(CONFIG_8xx) := arch/ppc/kernel/head_8xx.o +head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o +head-$(CONFIG_440) := arch/ppc/kernel/head_44x.o + +head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o core-y += arch/ppc/kernel/ arch/ppc/platforms/ \ arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/ @@ -59,7 +56,7 @@ BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd pImage vmlinux.sm -.PHONY: $(BOOT_TARGETS) clean archclean archmrproper +.PHONY: $(BOOT_TARGETS) all: zImage @@ -77,8 +74,6 @@ archclean: $(Q)$(MAKE) $(clean)=arch/ppc/boot - -archmrproper: prepare: include/asm-$(ARCH)/offsets.h checkbin diff -Nru a/arch/ppc/amiga/Makefile b/arch/ppc/amiga/Makefile --- a/arch/ppc/amiga/Makefile Sun Feb 9 21:13:31 2003 +++ b/arch/ppc/amiga/Makefile Sun Feb 9 21:13:31 2003 @@ -2,8 +2,6 @@ # Makefile for Linux arch/m68k/amiga source directory # -export-objs := amiga_ksyms.o - obj-y := config.o amiints.o cia.o time.o bootinfo.o amisound.o \ chipram.o amiga_ksyms.o diff -Nru a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile --- a/arch/ppc/boot/simple/Makefile Sun Feb 9 21:13:28 2003 +++ b/arch/ppc/boot/simple/Makefile Sun Feb 9 21:13:28 2003 @@ -19,7 +19,7 @@ # ENTRYPOINT which the image should be loaded at. The optimal setting # for ENTRYPOINT is the link address. # (4) It is advisable to pass in the memory size using BI_MEMSIZE and -# get_mem_size(), which is memory controller dependant. Add in the correct +# get_mem_size(), which is memory controller dependent. Add in the correct # XXX_memory.o file for this to work, as well as editing the $(MISC) file. boot: zImage diff -Nru a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c --- a/arch/ppc/boot/simple/misc.c Sun Feb 9 21:13:35 2003 +++ b/arch/ppc/boot/simple/misc.c Sun Feb 9 21:13:35 2003 @@ -82,7 +82,7 @@ #if defined(CONFIG_LOPEC) || defined(CONFIG_PAL4) /* - * Call get_mem_size(), which is memory controller dependant, + * Call get_mem_size(), which is memory controller dependent, * and we must have the correct file linked in here. */ TotalMemory = get_mem_size(); diff -Nru a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile --- a/arch/ppc/kernel/Makefile Sun Feb 9 21:13:35 2003 +++ b/arch/ppc/kernel/Makefile Sun Feb 9 21:13:35 2003 @@ -17,8 +17,6 @@ EXTRA_TARGETS := $(HEAD-y) -export-objs := ppc_ksyms.o time.o - obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ process.o signal.o ptrace.o align.o \ semaphore.o syscalls.o setup.o \ diff -Nru a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c --- a/arch/ppc/kernel/pci.c Sun Feb 9 21:13:32 2003 +++ b/arch/ppc/kernel/pci.c Sun Feb 9 21:13:32 2003 @@ -1069,7 +1069,7 @@ if (ppc_md.pci_swizzle && ppc_md.pci_map_irq) pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq); - /* Call machine dependant fixup */ + /* Call machine dependent fixup */ if (ppc_md.pcibios_fixup) ppc_md.pcibios_fixup(); diff -Nru a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c --- a/arch/ppc/kernel/signal.c Sun Feb 9 21:13:37 2003 +++ b/arch/ppc/kernel/signal.c Sun Feb 9 21:13:37 2003 @@ -65,11 +65,11 @@ sigset_t saveset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->result = -EINTR; regs->ccr |= 0x10000000; @@ -96,11 +96,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->result = -EINTR; regs->ccr |= 0x10000000; @@ -208,10 +208,10 @@ || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st))) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (regs->msr & MSR_FP) giveup_fpu(current); @@ -311,10 +311,10 @@ set.sig[1] = sigctx._unused[3]; #endif sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (regs->msr & MSR_FP ) giveup_fpu(current); @@ -450,11 +450,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } return; diff -Nru a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c --- a/arch/ppc/kernel/time.c Sun Feb 9 21:13:34 2003 +++ b/arch/ppc/kernel/time.c Sun Feb 9 21:13:34 2003 @@ -76,7 +76,6 @@ /* keep track of when we need to update the rtc */ time_t last_rtc_update; -extern rwlock_t xtime_lock; /* The decrementer counts down by 128 every 128ns on a 601. */ #define DECREMENTER_COUNT_601 (1000000000 / HZ) @@ -161,7 +160,7 @@ continue; /* We are in an interrupt, no need to save/restore flags */ - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); tb_last_stamp = jiffy_stamp; do_timer(regs); @@ -191,7 +190,7 @@ /* Try again one minute later */ last_rtc_update += 60; } - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } if ( !disarm_decr[smp_processor_id()] ) set_dec(next_dec); @@ -213,21 +212,23 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; unsigned delta, lost_ticks, usec, sec; - read_lock_irqsave(&xtime_lock, flags); - sec = xtime.tv_sec; - usec = (xtime.tv_nsec / 1000); - delta = tb_ticks_since(tb_last_stamp); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + sec = xtime.tv_sec; + usec = (xtime.tv_nsec / 1000); + delta = tb_ticks_since(tb_last_stamp); #ifdef CONFIG_SMP - /* As long as timebases are not in sync, gettimeofday can only - * have jiffy resolution on SMP. - */ - if (!smp_tb_synchronized) - delta = 0; + /* As long as timebases are not in sync, gettimeofday can only + * have jiffy resolution on SMP. + */ + if (!smp_tb_synchronized) + delta = 0; #endif /* CONFIG_SMP */ - lost_ticks = jiffies - wall_jiffies; - read_unlock_irqrestore(&xtime_lock, flags); + lost_ticks = jiffies - wall_jiffies; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); usec += mulhwu(tb_to_us, tb_ticks_per_jiffy * lost_ticks + delta); while (usec >= 1000000) { @@ -243,7 +244,7 @@ unsigned long flags; int tb_delta, new_usec, new_sec; - write_lock_irqsave(&xtime_lock, flags); + write_seqlock_irqsave(&xtime_lock, flags); /* Updating the RTC is not the job of this code. If the time is * stepped under NTP, the RTC will be update after STA_UNSYNC * is cleared. Tool like clock/hwclock either copy the RTC @@ -283,7 +284,7 @@ time_state = TIME_ERROR; /* p. 24, (a) */ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irqrestore(&xtime_lock, flags); + write_sequnlock_irqrestore(&xtime_lock, flags); } /* This function is only called on the boot processor */ diff -Nru a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile --- a/arch/ppc/lib/Makefile Sun Feb 9 21:13:28 2003 +++ b/arch/ppc/lib/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for ppc-specific library files.. # -export-objs := dec_and_lock.o - obj-y := checksum.o string.o strcase.o dec_and_lock.o div64.o obj-$(CONFIG_SMP) += locks.o diff -Nru a/arch/ppc/ocp/Makefile b/arch/ppc/ocp/Makefile --- a/arch/ppc/ocp/Makefile Sun Feb 9 21:13:30 2003 +++ b/arch/ppc/ocp/Makefile Sun Feb 9 21:13:30 2003 @@ -9,6 +9,5 @@ # # NB: cribbed from the drivers/sbus/Makefile -- PMM -export-objs := ocp.o ocp-driver.o ocp-probe.o obj-y += ocp.o ocp-driver.o ocp-probe.o diff -Nru a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile --- a/arch/ppc/platforms/4xx/Makefile Sun Feb 9 21:13:35 2003 +++ b/arch/ppc/platforms/4xx/Makefile Sun Feb 9 21:13:35 2003 @@ -1,8 +1,6 @@ # # Makefile for the PowerPC 4xx linux kernel. -export-objs := ibm405lp.o - obj-$(CONFIG_ASH) += ash.o obj-$(CONFIG_BEECH) += beech.o obj-$(CONFIG_CEDAR) += cedar.o diff -Nru a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile --- a/arch/ppc/platforms/Makefile Sun Feb 9 21:13:37 2003 +++ b/arch/ppc/platforms/Makefile Sun Feb 9 21:13:37 2003 @@ -12,8 +12,6 @@ # Extra CFLAGS so we don't have to do relative includes CFLAGS_pmac_setup.o += -I$(TOPDIR)/arch/$(ARCH)/mm -export-objs := prep_setup.o - obj-$(CONFIG_APUS) += apus_setup.o ifeq ($(CONFIG_APUS),y) obj-$(CONFIG_PCI) += apus_pci.o diff -Nru a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c --- a/arch/ppc/platforms/pmac_time.c Sun Feb 9 21:13:30 2003 +++ b/arch/ppc/platforms/pmac_time.c Sun Feb 9 21:13:30 2003 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -29,8 +30,6 @@ #include #include -extern rwlock_t xtime_lock; - /* Apparently the RTC stores seconds since 1 Jan 1904 */ #define RTC_OFFSET 2082844800 @@ -215,19 +214,21 @@ { static unsigned long time_diff; unsigned long flags; + unsigned long seq; switch (when) { case PBOOK_SLEEP_NOW: - read_lock_irqsave(&xtime_lock, flags); - time_diff = xtime.tv_sec - pmac_get_rtc_time(); - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + time_diff = xtime.tv_sec - pmac_get_rtc_time(); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); break; case PBOOK_WAKE: - write_lock_irqsave(&xtime_lock, flags); + write_seqlock_irqsave(&xtime_lock, flags); xtime.tv_sec = pmac_get_rtc_time() + time_diff; xtime.tv_nsec = 0; last_rtc_update = xtime.tv_sec; - write_unlock_irqrestore(&xtime_lock, flags); + write_sequnlock_irqrestore(&xtime_lock, flags); break; } return PBOOK_SLEEP_OK; diff -Nru a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile --- a/arch/ppc/syslib/Makefile Sun Feb 9 21:13:28 2003 +++ b/arch/ppc/syslib/Makefile Sun Feb 9 21:13:28 2003 @@ -12,8 +12,6 @@ CFLAGS_prom_init.o += -mrelocatable-lib CFLAGS_btext.o += -mrelocatable-lib -export-objs := ppc4xx_dma.o ppc4xx_pm.o - obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o ifeq ($(CONFIG_4xx),y) obj-$(CONFIG_4xx) += ppc4xx_pic.o diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig --- a/arch/ppc64/Kconfig Sun Feb 9 21:13:32 2003 +++ b/arch/ppc64/Kconfig Sun Feb 9 21:13:32 2003 @@ -128,6 +128,10 @@ tristate "Firmware flash interface" depends on !PPC_ISERIES +config PPC_RTAS + bool "Proc interface to RTAS" + depends on !PPC_ISERIES + endmenu @@ -208,7 +212,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. source "drivers/pci/Kconfig" @@ -307,7 +311,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -334,7 +338,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -400,7 +404,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/ppc64/Makefile b/arch/ppc64/Makefile --- a/arch/ppc64/Makefile Sun Feb 9 21:13:29 2003 +++ b/arch/ppc64/Makefile Sun Feb 9 21:13:29 2003 @@ -22,7 +22,7 @@ -Wno-uninitialized -mminimal-toc -mtraceback=full \ -finline-limit-2000 -mcpu=power4 -HEAD := arch/ppc64/kernel/head.o +head-y := arch/ppc64/kernel/head.o libs-y += arch/ppc64/lib/ core-y += arch/ppc64/kernel/ diff -Nru a/arch/ppc64/defconfig b/arch/ppc64/defconfig --- a/arch/ppc64/defconfig Sun Feb 9 21:13:30 2003 +++ b/arch/ppc64/defconfig Sun Feb 9 21:13:30 2003 @@ -18,10 +18,10 @@ # # General setup # -CONFIG_NET=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=15 # # Loadable module support @@ -41,6 +41,7 @@ # CONFIG_HMT is not set # CONFIG_DISCONTIGMEM is not set # CONFIG_RTAS_FLASH is not set +CONFIG_PPC_RTAS=y # # General setup @@ -50,6 +51,7 @@ CONFIG_BINFMT_ELF=y CONFIG_BINFMT_ELF32=y # CONFIG_BINFMT_MISC is not set +CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set CONFIG_PROC_DEVICETREE=y @@ -182,6 +184,11 @@ # CONFIG_I2O is not set # +# Networking support +# +CONFIG_NET=y + +# # Networking options # CONFIG_PACKET=y @@ -233,10 +240,6 @@ # Network testing # # CONFIG_NET_PKTGEN is not set - -# -# Network device support -# CONFIG_NETDEVICES=y # @@ -258,8 +261,6 @@ # CONFIG_SUNGEM is not set CONFIG_NET_VENDOR_3COM=y CONFIG_VORTEX=y -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set # # Tulip family network device support @@ -268,6 +269,7 @@ # CONFIG_HP100 is not set CONFIG_NET_PCI=y CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set # CONFIG_DGRS is not set @@ -283,7 +285,6 @@ # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set -# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) @@ -429,6 +430,11 @@ # CONFIG_QIC02_TAPE is not set # +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# # Watchdog Cards # # CONFIG_WATCHDOG is not set @@ -516,6 +522,7 @@ # CONFIG_NFSD_V4 is not set CONFIG_NFSD_TCP=y CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y @@ -580,6 +587,7 @@ # CONFIG_FB_CLGEN is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y # CONFIG_FB_CT65550 is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_S3TRIO is not set diff -Nru a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile --- a/arch/ppc64/kernel/Makefile Sun Feb 9 21:13:36 2003 +++ b/arch/ppc64/kernel/Makefile Sun Feb 9 21:13:36 2003 @@ -4,8 +4,6 @@ EXTRA_CFLAGS += -mno-minimal-toc EXTRA_TARGETS := head.o -export-objs := ppc_ksyms.o - obj-y := setup.o entry.o traps.o irq.o idle.o \ time.o process.o signal.o syscalls.o misc.o ptrace.o \ align.o semaphore.o bitops.o stab.o htab.o pacaData.o \ @@ -25,9 +23,10 @@ # Change this to pSeries only once we've got iSeries up to date obj-y += open_pic.o xics.o pSeries_htab.o rtas.o \ - rtas-proc.o chrp_setup.o i8259.o ras.o prom.o + chrp_setup.o i8259.o ras.o prom.o obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_PROFILING) += profile.o obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o +obj-$(CONFIG_PPC_RTAS) += rtas-proc.o diff -Nru a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S --- a/arch/ppc64/kernel/entry.S Sun Feb 9 21:13:28 2003 +++ b/arch/ppc64/kernel/entry.S Sun Feb 9 21:13:28 2003 @@ -57,6 +57,7 @@ * Handle a system call. */ _GLOBAL(DoSyscall) + std r3,ORIG_GPR3(r1) ld r11,_CCR(r1) /* Clear SO bit in CR */ lis r10,0x1000 andc r11,r11,r10 @@ -226,6 +227,10 @@ _GLOBAL(ppc32_rt_sigreturn) bl .sys32_rt_sigreturn + b 80f + +_GLOBAL(ppc64_sigreturn) + bl .sys_sigreturn b 80f _GLOBAL(ppc64_rt_sigreturn) diff -Nru a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S --- a/arch/ppc64/kernel/head.S Sun Feb 9 21:13:32 2003 +++ b/arch/ppc64/kernel/head.S Sun Feb 9 21:13:32 2003 @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE @@ -789,7 +790,6 @@ beq+ HardwareInterrupt_entry 1: #endif - std r3,ORIG_GPR3(r1) #ifdef DO_SOFT_DISABLE ld r20,SOFTE(r1) #else @@ -1141,9 +1141,9 @@ * If from user state, update THREAD.regs */ beq 2f /* Modify THREAD.regs if from user */ - addi r24,r1,STACK_FRAME_OVERHEAD + addi r23,r1,STACK_FRAME_OVERHEAD ld r22, PACACURRENT(r13) - std r24,THREAD+PT_REGS(r22) + std r23,THREAD+PT_REGS(r22) 2: SET_REG_TO_CONST(r22, MSR_KERNEL) diff -Nru a/arch/ppc64/kernel/htab.c b/arch/ppc64/kernel/htab.c --- a/arch/ppc64/kernel/htab.c Sun Feb 9 21:13:33 2003 +++ b/arch/ppc64/kernel/htab.c Sun Feb 9 21:13:33 2003 @@ -333,7 +333,7 @@ hpteflags, 0, large); /* Primary is full, try the secondary */ - if (slot == -1) { + if (unlikely(slot == -1)) { pte_val(new_pte) |= 1 << 15; hpte_group = ((~hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; @@ -393,6 +393,7 @@ mm = &init_mm; vsid = get_kernel_vsid(ea); break; +#if 0 case EEH_REGION_ID: /* * Should only be hit if there is an access to MMIO space @@ -404,6 +405,7 @@ * Should never get here - entire 0xC0... region is bolted. * Send the problem up to do_page_fault */ +#endif default: /* Not a valid range * Send the problem up to do_page_fault diff -Nru a/arch/ppc64/kernel/init_task.c b/arch/ppc64/kernel/init_task.c --- a/arch/ppc64/kernel/init_task.c Sun Feb 9 21:13:29 2003 +++ b/arch/ppc64/kernel/init_task.c Sun Feb 9 21:13:29 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); /* diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S --- a/arch/ppc64/kernel/misc.S Sun Feb 9 21:13:35 2003 +++ b/arch/ppc64/kernel/misc.S Sun Feb 9 21:13:35 2003 @@ -443,26 +443,61 @@ * kernel_thread(fn, arg, flags) */ _GLOBAL(kernel_thread) - /* XXX fix this when we optimise syscall entry to not save volatiles */ - mr r6,r3 /* function */ - mr r7,r4 /* arg */ + std r29,-24(r1) + std r30,-16(r1) + stdu r1,-STACK_FRAME_OVERHEAD(r1) + mr r29,r3 + mr r30,r4 ori r3,r5,CLONE_VM /* flags */ oris r3,r3,(CLONE_UNTRACED>>16) li r4,0 /* new sp (unused) */ li r0,__NR_clone sc cmpi 0,r3,0 /* parent or child? */ - bnelr /* return if parent */ + bne 1f /* return if parent */ li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) - ld r2,8(r6) - ld r6,0(r6) - mtlr r6 /* fn addr in lr */ - mr r3,r7 /* load arg and call fn */ + ld r2,8(r29) + ld r29,0(r29) + mtlr r29 /* fn addr in lr */ + mr r3,r30 /* load arg and call fn */ blrl li r0,__NR_exit /* exit after child exits */ li r3,0 sc +1: addi r1,r1,STACK_FRAME_OVERHEAD + ld r29,-24(r1) + ld r30,-16(r1) + blr + + .section ".toc","aw" +.SYSCALL_ERRNO: + .tc errno[TC],errno + + .section ".text" + .align 3 + +#define SYSCALL(name) \ +_GLOBAL(name) \ + li r0,__NR_##name; \ + sc; \ + bnslr; \ + ld r4,.SYSCALL_ERRNO@toc(2); \ + std r3,0(r4); \ + li r3,-1; \ + blr + +#define __NR__exit __NR_exit + +SYSCALL(setsid) +SYSCALL(open) +SYSCALL(read) +SYSCALL(write) +SYSCALL(lseek) +SYSCALL(close) +SYSCALL(dup) +SYSCALL(execve) +SYSCALL(waitpid) #ifdef CONFIG_BINFMT_ELF32 /* Why isn't this a) automatic, b) written in 'C'? */ @@ -540,8 +575,8 @@ .llong .sys32_ssetmask .llong .sys_setreuid /* 70 */ .llong .sys_setregid - .llong .sys32_sigsuspend - .llong .sys32_sigpending + .llong .sys_sigsuspend + .llong .compat_sys_sigpending .llong .sys32_sethostname .llong .sys32_setrlimit /* 75 */ .llong .sys32_old_getrlimit @@ -594,7 +629,7 @@ .llong .sys_ni_syscall /* old modify_ldt syscall */ .llong .sys32_adjtimex .llong .sys_mprotect /* 125 */ - .llong .sys32_sigprocmask + .llong .compat_sys_sigprocmask .llong .sys_ni_syscall /* old create_module syscall */ .llong .sys32_init_module .llong .sys32_delete_module @@ -783,13 +818,13 @@ .llong .sys_getppid .llong .sys_getpgrp /* 65 */ .llong .sys_setsid - .llong .sys_ni_syscall /* 32 bit only sigaction */ + .llong .sys_sigaction .llong .sys_sgetmask .llong .sys_ssetmask .llong .sys_setreuid /* 70 */ .llong .sys_setregid - .llong .sys_ni_syscall /* 32bit only sigsuspend */ - .llong .sys_ni_syscall /* 32bit only sigpending */ + .llong .sys_sigsuspend + .llong .sys_sigpending .llong .sys_sethostname .llong .sys_setrlimit /* 75 */ .llong .sys_ni_syscall /* old getrlimit syscall */ @@ -835,14 +870,14 @@ .llong .sys_sysinfo .llong .sys_ipc .llong .sys_fsync - .llong .sys_ni_syscall /* 32bit only sigreturn */ + .llong .ppc64_sigreturn .llong .sys_clone /* 120 */ .llong .sys_setdomainname .llong .ppc64_newuname .llong .sys_ni_syscall /* old modify_ldt syscall */ .llong .sys_adjtimex .llong .sys_mprotect /* 125 */ - .llong .sys_ni_syscall /* 32bit only sigprocmask */ + .llong .sys_sigprocmask .llong .sys_ni_syscall /* old create_module syscall */ .llong .sys_init_module .llong .sys_delete_module diff -Nru a/arch/ppc64/kernel/module.c b/arch/ppc64/kernel/module.c --- a/arch/ppc64/kernel/module.c Sun Feb 9 21:13:36 2003 +++ b/arch/ppc64/kernel/module.c Sun Feb 9 21:13:36 2003 @@ -136,6 +136,20 @@ return relocs * sizeof(struct ppc64_stub_entry); } +/* Undefined symbols which refer to .funcname, hack to funcname */ +static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) +{ + unsigned int i; + + for (i = 1; i < numsyms; i++) { + if (syms[i].st_shndx == SHN_UNDEF) { + char *name = strtab + syms[i].st_name; + if (name[0] == '.') + memmove(name, name+1, strlen(name)); + } + } +} + int module_frob_arch_sections(Elf64_Ehdr *hdr, Elf64_Shdr *sechdrs, char *secstrings, @@ -143,7 +157,7 @@ { unsigned int i; - /* Find .toc and .stubs sections */ + /* Find .toc and .stubs sections, symtab and strtab */ for (i = 1; i < hdr->e_shnum; i++) { char *p; if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0) @@ -154,6 +168,12 @@ /* We don't handle .init for the moment: rename to _init */ while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init"))) p[0] = '_'; + + if (sechdrs[i].sh_type == SHT_SYMTAB) + dedotify((void *)hdr + sechdrs[i].sh_offset, + sechdrs[i].sh_size / sizeof(Elf64_Sym), + (void *)hdr + + sechdrs[sechdrs[i].sh_link].sh_offset); } if (!me->arch.stubs_section || !me->arch.toc_section) { printk("%s: doesn't contain .toc or .stubs.\n", me->name); @@ -175,6 +195,14 @@ return -ENOEXEC; } +/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this + gives the value maximum span in an instruction which uses a signed + offset) */ +static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) +{ + return sechdrs[me->arch.toc_section].sh_addr + 0x8000; +} + /* Both low and high 16 bits are added as SIGNED additions, so if low 16 bits has high bit set, high 16 bits must be adjusted. These macros do that (stolen from binutils). */ @@ -183,10 +211,10 @@ #define PPC_HA(v) PPC_HI ((v) + 0x8000) /* Patch stub to reference function and correct r2 value. */ -static inline int create_stub(struct ppc64_stub_entry *entry, - unsigned long my_r2, - unsigned long func, - unsigned long r2) +static inline int create_stub(Elf64_Shdr *sechdrs, + struct ppc64_stub_entry *entry, + struct ppc64_opd_entry *opd, + struct module *me) { Elf64_Half *loc1, *loc2; long reladdr; @@ -196,72 +224,32 @@ loc1 = (Elf64_Half *)&entry->jump[2]; loc2 = (Elf64_Half *)&entry->jump[6]; - /* Stub uses address relative to r2, which is set to the TOC + - 0x8000. */ - reladdr = (unsigned long)entry - my_r2; + /* Stub uses address relative to r2. */ + reladdr = (unsigned long)entry - my_r2(sechdrs, me); if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) { - printk("Address %p of stub out of range of %p.\n", - (void *)reladdr, (void *)my_r2); + printk("%s: Address %p of stub out of range of %p.\n", + me->name, (void *)reladdr, (void *)my_r2); return 0; } DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr); *loc1 = PPC_HA(reladdr); *loc2 = PPC_LO(reladdr); - entry->opd.funcaddr = func; - entry->opd.r2 = r2; - - DEBUGP("Stub: %08X %08X %08X %08X %08X %08X %08X: %p %p\n", - ((unsigned int *)entry->jump)[0], - ((unsigned int *)entry->jump)[1], - ((unsigned int *)entry->jump)[2], - ((unsigned int *)entry->jump)[3], - ((unsigned int *)entry->jump)[4], - ((unsigned int *)entry->jump)[5], - ((unsigned int *)entry->jump)[6], - (void *)entry->opd.funcaddr, - (void *)entry->opd.r2); + entry->opd.funcaddr = opd->funcaddr; + entry->opd.r2 = opd->r2; return 1; } -/* Given ".function" reference, return address of "function" opd entry */ -static struct ppc64_opd_entry *find_function(const char *name, - Elf64_Shdr *sechdrs, - unsigned int symindex, - const char *strtab, - struct module *me, - struct kernel_symbol_group **ksg) -{ - unsigned long val; - - if (name[0] != '.') - return 0; - - val = find_symbol_internal(sechdrs, symindex, strtab, name+1, me, ksg); - - DEBUGP("Function %s is at %p\n", name+1, (void *)val); - return (void *)val; -} - -/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this - gives the value maximum span in an instruction which uses a signed - offset) */ -static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) -{ - return sechdrs[me->arch.toc_section].sh_addr + 0x8000; -} - -/* Create stub for this OPD address */ +/* Create stub to jump to function described in this OPD: we need the + stub to set up the TOC ptr (r2) for the function. */ static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, - unsigned long addr, - unsigned long r2, + unsigned long opdaddr, struct module *me) { struct ppc64_stub_entry *stubs; + struct ppc64_opd_entry *opd = (void *)opdaddr; unsigned int i, num_stubs; - DEBUGP("Looking for stub for %p\n", (void *)addr); - num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs); /* Find this stub, or if that fails, the next avail. entry */ @@ -269,50 +257,23 @@ for (i = 0; stubs[i].opd.funcaddr; i++) { BUG_ON(i >= num_stubs); - if (stubs[i].opd.funcaddr == addr) { - DEBUGP("Reusing stub %u (%p) for %p\n", - i, &stubs[i], (void *)addr); + if (stubs[i].opd.funcaddr == opd->funcaddr) return (unsigned long)&stubs[i]; - } } - DEBUGP("Here for %p\n", (void *)addr); - - if (!create_stub(&stubs[i], my_r2(sechdrs, me), addr, r2)) - return (unsigned long)-EINVAL; - DEBUGP("CREATED stub %u for %p\n", i, (void *)addr); + if (!create_stub(sechdrs, &stubs[i], opd, me)) + return 0; return (unsigned long)&stubs[i]; } -/* We need a stub to set the toc ptr when we make external calls. */ -static unsigned long do_stub_call(Elf64_Shdr *sechdrs, - const char *strtab, - unsigned int symindex, - void *location, - const char *funcname, - struct module *me) -{ - struct ppc64_opd_entry *opd; - struct kernel_symbol_group *ksg; - - DEBUGP("Doing stub for %lu (%s)\n", - (unsigned long)location, funcname); - opd = find_function(funcname, sechdrs, symindex, strtab, me, &ksg); - if (!opd) { - printk("%s: Can't find function `%s'\n", me->name, funcname); - return (unsigned long)-ENOENT; - } - - return stub_for_addr(sechdrs, opd->funcaddr, opd->r2, me); -} - /* We expect a noop next: if it is, replace it with instruction to restore r2. */ -static int restore_r2(u32 *instruction) +static int restore_r2(u32 *instruction, struct module *me) { if (*instruction != 0x60000000) { - printk("Expect noop after relocate, got %08x\n", *instruction); + printk("%s: Expect noop after relocate, got %08x\n", + me->name, *instruction); return 0; } *instruction = 0xe8410028; /* ld r2,40(r1) */ @@ -346,31 +307,18 @@ strtab + sym->st_name, (unsigned long)sym->st_value, (long)rela[i].r_addend); - /* REL24 references to (external) .function won't - resolve; deal with that below */ - if (!sym->st_value - && ELF64_R_TYPE(rela[i].r_info) != R_PPC_REL24) { - printk("%s: Unknown symbol %s (index %u)\n", - me->name, strtab + sym->st_name, - sym->st_shndx); - return -ENOENT; - } /* `Everything is relative'. */ value = sym->st_value + rela[i].r_addend; switch (ELF64_R_TYPE(rela[i].r_info)) { case R_PPC64_ADDR32: /* Simply set it */ - DEBUGP("Setting location %p to 32-bit value %u\n", - location, (unsigned int)value); *(u32 *)location = value; break; case R_PPC64_ADDR64: /* Simply set it */ *(unsigned long *)location = value; - DEBUGP("Setting location %p to 64-bit value %p\n", - location, (void *)value); break; case R_PPC64_TOC: @@ -381,37 +329,31 @@ /* Subtact TOC pointer */ value -= my_r2(sechdrs, me); if ((value & 3) != 0 || value + 0x8000 > 0xffff) { - DEBUGP("%s: bad TOC16_DS relocation (%lu)\n", + printk("%s: bad TOC16_DS relocation (%lu)\n", me->name, value); return -ENOEXEC; } *((uint16_t *) location) = (*((uint16_t *) location) & ~0xfffc) | (value & 0xfffc); - DEBUGP("Modifying location %p by TOC (%p) => %i\n", - location, - (void *)my_r2(sechdrs, me), - *(uint16_t *)location); break; case R_PPC_REL24: /* FIXME: Handle weak symbols here --RR */ if (sym->st_shndx == SHN_UNDEF) { - value = do_stub_call(sechdrs, strtab, - symindex, location, - strtab+sym->st_name, me); - if (IS_ERR((void *)value)) - return value; - value += rela[i].r_addend; - if (!restore_r2((u32 *)location + 1)) + /* External: go via stub */ + value = stub_for_addr(sechdrs, value, me); + if (!value) + return -ENOENT; + if (!restore_r2((u32 *)location + 1, me)) return -ENOEXEC; } /* Convert value to relative */ value -= (unsigned long)location; if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){ - printk("REL24 relocation %li out of range!\n", - (long int)value); + printk("%s: REL24 %li out of range!\n", + me->name, (long int)value); return -ENOEXEC; } @@ -422,7 +364,8 @@ break; default: - printk("Unknown ADD relocation: %lu\n", + printk("%s: Unknown ADD relocation: %lu\n", + me->name, (unsigned long)ELF64_R_TYPE(rela[i].r_info)); return -ENOEXEC; } @@ -439,25 +382,6 @@ const Elf_Shdr *sechdrs, struct module *me) { - struct ppc64_stub_entry *stubs; - unsigned int i; - - /* Here is where we copy the OPD entry into the stub: we don't - do it ealier in case it's actually in the same module, and - hasn't been relocated yet. */ - stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr; - for (i = 0; stubs[i].opd.funcaddr; i++) { - struct ppc64_opd_entry *opd; - - /* We mark opd pointers by setting r2 to 0: otherwise - it's a function pointer already. */ - if (stubs[i].opd.r2 == 0) { - /* We put the opd entry ptr in the funcaddr member. */ - opd = (void *)stubs[i].opd.funcaddr; - stubs[i].opd = *opd; - } - } - sort_ex_table(me->extable.entry, me->extable.entry + me->extable.num_entries); return 0; diff -Nru a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c --- a/arch/ppc64/kernel/pci.c Sun Feb 9 21:13:35 2003 +++ b/arch/ppc64/kernel/pci.c Sun Feb 9 21:13:35 2003 @@ -413,7 +413,7 @@ next_busno = hose->last_busno+1; } - /* Call machine dependant fixup */ + /* Call machine dependent fixup */ if (ppc_md.pcibios_fixup) { ppc_md.pcibios_fixup(); } diff -Nru a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c --- a/arch/ppc64/kernel/process.c Sun Feb 9 21:13:33 2003 +++ b/arch/ppc64/kernel/process.c Sun Feb 9 21:13:33 2003 @@ -163,6 +163,11 @@ void flush_thread(void) { + struct thread_info *t = current_thread_info(); + + if (t->flags & _TIF_ABI_PENDING) + t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT); + if (last_task_used_math == current) last_task_used_math = NULL; } diff -Nru a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c --- a/arch/ppc64/kernel/rtas-proc.c Sun Feb 9 21:13:32 2003 +++ b/arch/ppc64/kernel/rtas-proc.c Sun Feb 9 21:13:32 2003 @@ -115,9 +115,10 @@ /* Globals */ -static struct proc_dir_entry *proc_rtas; +extern struct proc_dir_entry *proc_rtas; + static struct rtas_sensors sensors; -static struct device_node *rtas_node; +static struct device_node *rtas_node = NULL; static unsigned long power_on_time = 0; /* Save the time the user set */ static char progress_led[MAX_LINELENGTH]; @@ -200,13 +201,18 @@ struct proc_dir_entry *entry; rtas_node = find_devices("rtas"); - if ((rtas_node == 0) || (naca->platform == PLATFORM_ISERIES_LPAR)) { + if ((rtas_node == NULL) || (naca->platform == PLATFORM_ISERIES_LPAR)) { return; } - proc_rtas = proc_mkdir("rtas", 0); - if (proc_rtas == 0) + if (proc_rtas == NULL) { + proc_rtas = proc_mkdir("rtas", 0); + } + + if (proc_rtas == NULL) { + printk(KERN_ERR "Failed to create /proc/rtas in proc_rtas_init\n"); return; + } /* /proc/rtas entries */ @@ -405,10 +411,14 @@ j = sensors.sensor[i].quant; /* A sensor may have multiple instances */ while (j >= 0) { + error = rtas_call(get_sensor_state, 2, 2, &ret, - sensors.sensor[i].token, sensors.sensor[i].quant-j); + sensors.sensor[i].token, + sensors.sensor[i].quant - j); + state = (int) ret; - n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n ); + n += ppc_rtas_process_sensor(sensors.sensor[i], state, + error, buffer+n ); n += sprintf (buffer+n, "\n"); j--; } /* while */ @@ -426,6 +436,7 @@ n = count; else *eof = 1; + memcpy(buf, buffer + off, n); *start = buf; kfree(buffer); @@ -436,10 +447,10 @@ int ppc_rtas_find_all_sensors (void) { - unsigned long *utmp; - int len, i, j; + unsigned int *utmp; + int len, i; - utmp = (unsigned long *) get_property(rtas_node, "rtas-sensors", &len); + utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len); if (utmp == NULL) { printk (KERN_ERR "error: could not get rtas-sensors\n"); return 1; @@ -447,9 +458,9 @@ sensors.quant = len / 8; /* int + int */ - for (i=0, j=0; jproc_fops = &proc_rtas_log_operations; else diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c --- a/arch/ppc64/kernel/signal.c Sun Feb 9 21:13:28 2003 +++ b/arch/ppc64/kernel/signal.c Sun Feb 9 21:13:28 2003 @@ -99,6 +99,40 @@ extern int do_signal(sigset_t *oldset, struct pt_regs *regs); +/* + * Atomically swap in the new signal mask, and wait for a signal. + */ +long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, + struct pt_regs *regs) +{ + sigset_t saveset; + + mask &= _BLOCKABLE; + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + regs->result = -EINTR; + regs->gpr[3] = EINTR; + regs->ccr |= 0x10000000; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(&saveset, regs)) + /* + * If a signal handler needs to be called, + * do_signal() has set R3 to the signal number (the + * first argument of the signal handler), so don't + * overwrite that with EINTR ! + * In the other cases, do_signal() doesn't touch + * R3, so it's still set to -EINTR (see above). + */ + return regs->gpr[3]; + } +} + long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6, int p7, struct pt_regs *regs) { @@ -112,11 +146,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->result = -EINTR; regs->gpr[3] = EINTR; @@ -136,6 +170,37 @@ return do_sigaltstack(uss, uoss, regs->gpr[1]); } +long sys_sigaction(int sig, const struct old_sigaction *act, + struct old_sigaction *oact) +{ + struct k_sigaction new_ka, old_ka; + int ret; + + if (act) { + old_sigset_t mask; + + if (verify_area(VERIFY_READ, act, sizeof(*act)) || + __get_user(new_ka.sa.sa_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) + return -EFAULT; + __get_user(new_ka.sa.sa_flags, &act->sa_flags); + __get_user(mask, &act->sa_mask); + siginitset(&new_ka.sa.sa_mask, mask); + } + + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); + if (!ret && oact) { + if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) + return -EFAULT; + __put_user(old_ka.sa.sa_flags, &oact->sa_flags); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); + } + + return ret; +} + /* * When we have rt signals to deliver, we set up on the * user stack, going down from the original stack pointer: @@ -164,10 +229,10 @@ || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st))) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (regs->msr & MSR_FP) giveup_fpu(current); @@ -264,6 +329,116 @@ } /* + * Do a signal return; undo the signal stack. + */ +long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, unsigned long r8, + struct pt_regs *regs) +{ + struct sigcontext *sc, sigctx; + struct sigregs *sr; + elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */ + sigset_t set; + + sc = (struct sigcontext *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); + if (copy_from_user(&sigctx, sc, sizeof(sigctx))) + goto badframe; + + set.sig[0] = sigctx.oldmask; +#if _NSIG_WORDS > 1 + set.sig[1] = sigctx._unused[3]; +#endif + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + if (regs->msr & MSR_FP) + giveup_fpu(current); + + /* restore registers */ + sr = (struct sigregs *)sigctx.regs; + if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs))) + goto badframe; + saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE) + | (saved_regs[PT_MSR] & MSR_USERCHANGE); + saved_regs[PT_SOFTE] = regs->softe; + memcpy(regs, saved_regs, GP_REGS_SIZE); + + if (copy_from_user(current->thread.fpr, &sr->fp_regs, + sizeof(sr->fp_regs))) + goto badframe; + + return regs->result; + +badframe: + do_exit(SIGSEGV); +} + +/* + * Set up a signal frame. + */ +static void setup_frame(struct pt_regs *regs, struct sigregs *frame, + unsigned long newsp) +{ + + /* Handler is *really* a pointer to the function descriptor for + * the signal routine. The first entry in the function + * descriptor is the entry address of signal and the second + * entry is the TOC value we need to use. + */ + struct funct_descr_entry { + unsigned long entry; + unsigned long toc; + }; + + struct funct_descr_entry * funct_desc_ptr; + unsigned long temp_ptr; + + struct sigcontext *sc = (struct sigcontext *)newsp; + + if (verify_area(VERIFY_WRITE, frame, sizeof(*frame))) + goto badframe; + if (regs->msr & MSR_FP) + giveup_fpu(current); + if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE) + || __copy_to_user(&frame->fp_regs, current->thread.fpr, + ELF_NFPREG * sizeof(double)) + /* li r0, __NR_sigreturn */ + || __put_user(0x38000000UL + __NR_sigreturn, &frame->tramp[0]) + /* sc */ + || __put_user(0x44000002UL, &frame->tramp[1])) + goto badframe; + flush_icache_range((unsigned long)&frame->tramp[0], + (unsigned long)&frame->tramp[2]); + current->thread.fpscr = 0; /* turn off all fp exceptions */ + + newsp -= __SIGNAL_FRAMESIZE; + if (get_user(temp_ptr, &sc->handler)) + goto badframe; + + funct_desc_ptr = (struct funct_descr_entry *)temp_ptr; + + if (put_user(regs->gpr[1], (unsigned long *)newsp) + || get_user(regs->nip, &funct_desc_ptr ->entry) + || get_user(regs->gpr[2],&funct_desc_ptr->toc) + || get_user(regs->gpr[3], &sc->signal)) + goto badframe; + regs->gpr[1] = newsp; + regs->gpr[4] = (unsigned long)sc; + regs->link = (unsigned long)frame->tramp; + + return; + +badframe: +#if DEBUG_SIG + printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n", + regs, frame, newsp); +#endif + do_exit(SIGSEGV); +} + +/* * OK, we're invoking a handler */ static void handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, @@ -271,7 +446,7 @@ { struct sigcontext *sc; struct rt_sigframe *rt_sf; - struct k_sigaction *ka = ¤t->sig->action[sig-1]; + struct k_sigaction *ka = ¤t->sighand->action[sig-1]; if (regs->trap == 0x0C00 /* System Call! */ && ((int)regs->result == -ERESTARTNOHAND || @@ -333,11 +508,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } return; @@ -378,7 +553,7 @@ signr = get_signal_to_deliver(&info, regs); if (signr > 0) { - ka = ¤t->sig->action[signr-1]; + ka = ¤t->sighand->action[signr-1]; if ((ka->sa.sa_flags & SA_ONSTACK) && (!on_sig_stack(regs->gpr[1]))) newsp = (current->sas_ss_sp + current->sas_ss_size); @@ -407,7 +582,10 @@ if (newsp == frame) return 0; /* no signals delivered */ - setup_rt_frame(regs, (struct sigregs *)frame, newsp); - + /* Invoke correct stack setup routine */ + if (ka->sa.sa_flags & SA_SIGINFO) + setup_rt_frame(regs, (struct sigregs *)frame, newsp); + else + setup_frame(regs, (struct sigregs *)frame, newsp); return 1; } diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c --- a/arch/ppc64/kernel/signal32.c Sun Feb 9 21:13:36 2003 +++ b/arch/ppc64/kernel/signal32.c Sun Feb 9 21:13:36 2003 @@ -104,8 +104,6 @@ * * System Calls * sigaction sys32_sigaction - * sigpending sys32_sigpending - * sigprocmask sys32_sigprocmask * sigreturn sys32_sigreturn * * Note sigsuspend has no special 32 bit routine - uses the 64 bit routine @@ -114,43 +112,6 @@ * setup_frame32 */ -/* - * Atomically swap in the new signal mask, and wait for a signal. - */ - -extern int do_signal(sigset_t *oldset, struct pt_regs *regs); - -long sys32_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, - int p7, struct pt_regs *regs) -{ - sigset_t saveset; - - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); - saveset = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); - - regs->result = -EINTR; - regs->gpr[3] = EINTR; - regs->ccr |= 0x10000000; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&saveset, regs)) - /* - * If a signal handler needs to be called, - * do_signal() has set R3 to the signal number (the - * first argument of the signal handler), so don't - * overwrite that with EINTR ! - * In the other cases, do_signal() doesn't touch - * R3, so it's still set to -EINTR (see above). - */ - return regs->gpr[3]; - } -} - long sys32_sigaction(int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact) { @@ -161,7 +122,7 @@ sig = -sig; if (act) { - old_sigset_t32 mask; + compat_old_sigset_t mask; if (get_user((long)new_ka.sa.sa_handler, &act->sa_handler) || __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer) || @@ -184,54 +145,6 @@ } -extern long sys_sigpending(old_sigset_t *set); - -long sys32_sigpending(old_sigset_t32 *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 long sys_sigprocmask(int how, old_sigset_t *set, - old_sigset_t *oset); - -/* - * Note: it is necessary to treat how as an unsigned int, with the - * corresponding cast to a signed int to insure that the proper - * conversion (sign extension) between the register representation - * of a signed int (msr in 32-bit mode) and the register representation - * of a signed int (msr in 64-bit mode) is performed. - */ -long sys32_sigprocmask(u32 how, old_sigset_t32 *set, - old_sigset_t32 *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((int)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; -} - - - /* * When we have signals to deliver, we set up on the * user stack, going down from the original stack pointer: @@ -268,10 +181,10 @@ */ set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32); sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (regs->msr & MSR_FP ) giveup_fpu(current); /* Last stacked signal - restore registers */ @@ -487,10 +400,10 @@ */ sigdelsetmask(&set, ~_BLOCKABLE); /* update the current based on the sigmask found in the rt_stackframe */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); /* If currently owning the floating point - give them up */ if (regs->msr & MSR_FP) @@ -565,16 +478,16 @@ { 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) { ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler); ret |= __copy_from_user(&set32, &act->sa_mask, - sizeof(sigset32_t)); + sizeof(compat_sigset_t)); switch (_NSIG_WORDS) { case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32); @@ -608,7 +521,7 @@ } ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler); ret |= __copy_to_user(&oact->sa_mask, &set32, - sizeof(sigset32_t)); + sizeof(compat_sigset_t)); ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); } return ret; @@ -625,16 +538,16 @@ * of a signed int (msr in 32-bit mode) and the register representation * of a signed int (msr in 64-bit mode) is performed. */ -long sys32_rt_sigprocmask(u32 how, sigset32_t *set, - sigset32_t *oset, size_t sigsetsize) +long sys32_rt_sigprocmask(u32 how, compat_sigset_t *set, + compat_sigset_t *oset, size_t 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) { @@ -658,7 +571,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; @@ -668,10 +581,10 @@ extern long sys_rt_sigpending(sigset_t *set, size_t sigsetsize); -long sys32_rt_sigpending(sigset32_t *set, compat_size_t sigsetsize) +long 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(); @@ -685,7 +598,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; @@ -739,17 +652,17 @@ siginfo_t *uinfo, const struct timespec *uts, size_t sigsetsize); -long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo, +long 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; - 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); @@ -837,11 +750,11 @@ return ret; } -int sys32_rt_sigsuspend(sigset32_t* unewset, size_t sigsetsize, int p3, +int sys32_rt_sigsuspend(compat_sigset_t* unewset, size_t sigsetsize, int p3, int p4, int p6, int p7, struct pt_regs *regs) { sigset_t saveset, newset; - sigset32_t s32; + compat_sigset_t s32; /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(sigset_t)) @@ -863,11 +776,11 @@ sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->result = -EINTR; regs->gpr[3] = EINTR; @@ -991,7 +904,7 @@ { struct sigcontext32 *sc; struct rt_sigframe_32 *rt_sf; - struct k_sigaction *ka = ¤t->sig->action[sig-1]; + struct k_sigaction *ka = ¤t->sighand->action[sig-1]; if (regs->trap == 0x0C00 /* System Call! */ && ((int)regs->result == -ERESTARTNOHAND || @@ -1055,11 +968,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } return; @@ -1152,7 +1065,7 @@ signr = get_signal_to_deliver(&info, regs); if (signr > 0) { - ka = ¤t->sig->action[signr-1]; + ka = ¤t->sighand->action[signr-1]; if ((ka->sa.sa_flags & SA_ONSTACK) && (!on_sig_stack(regs->gpr[1]))) newsp = (current->sas_ss_sp + current->sas_ss_size); diff -Nru a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c --- a/arch/ppc64/kernel/smp.c Sun Feb 9 21:13:34 2003 +++ b/arch/ppc64/kernel/smp.c Sun Feb 9 21:13:34 2003 @@ -494,8 +494,10 @@ while (atomic_read(&data.started) != cpus) { HMT_low(); if (--timeout == 0) { +#ifdef CONFIG_DEBUG_KERNEL if (debugger) debugger(0); +#endif printk("smp_call_function on cpu %d: other cpus not " "responding (%d)\n", smp_processor_id(), atomic_read(&data.started)); @@ -508,8 +510,10 @@ while (atomic_read(&data.finished) != cpus) { HMT_low(); if (--timeout == 0) { +#ifdef CONFIG_DEBUG_KERNEL if (debugger) debugger(0); +#endif printk("smp_call_function on cpu %d: other " "cpus not finishing (%d/%d)\n", smp_processor_id(), diff -Nru a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c --- a/arch/ppc64/kernel/sys_ppc32.c Sun Feb 9 21:13:34 2003 +++ b/arch/ppc64/kernel/sys_ppc32.c Sun Feb 9 21:13:34 2003 @@ -2756,10 +2756,27 @@ __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type); clen64 = kcmsg32->cmsg_len; - copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), - clen64 - CMSG_ALIGN(sizeof(*ucmsg))); - clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + - CMSG32_ALIGN(sizeof(struct cmsghdr32))); + if (kcmsg32->cmsg_level == SOL_SOCKET && + kcmsg32->cmsg_type == SO_TIMESTAMP) { + struct timeval tv; + struct compat_timeval *tv32; + + if (clen64 != CMSG_LEN(sizeof(struct timeval))) { + kfree(workbuf); + goto fail; + } + copy_from_user(&tv, CMSG_DATA(ucmsg), sizeof(tv)); + tv32 = (struct compat_timeval *) CMSG32_DATA(kcmsg32); + tv32->tv_sec = tv.tv_sec; + tv32->tv_usec = tv.tv_usec; + clen32 = sizeof(*tv32) + + CMSG32_ALIGN(sizeof(struct cmsghdr32)); + } else { + copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg), + clen64 - CMSG_ALIGN(sizeof(*ucmsg))); + clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) + + CMSG32_ALIGN(sizeof(struct cmsghdr32))); + } kcmsg32->cmsg_len = clen32; switch (kcmsg32->cmsg_type) { diff -Nru a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c --- a/arch/ppc64/kernel/time.c Sun Feb 9 21:13:36 2003 +++ b/arch/ppc64/kernel/time.c Sun Feb 9 21:13:36 2003 @@ -69,7 +69,6 @@ /* keep track of when we need to update the rtc */ time_t last_rtc_update; -extern rwlock_t xtime_lock; extern int piranha_simulator; #ifdef CONFIG_PPC_ISERIES unsigned long iSeries_recal_titan = 0; @@ -284,12 +283,12 @@ smp_local_timer_interrupt(regs); #endif if (cpu == boot_cpuid) { - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); tb_last_stamp = lpaca->next_jiffy_update_tb; do_timer(regs); timer_sync_xtime( cur_tb ); timer_check_rtc(); - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); if ( adjusting_time && (time_adjust == 0) ) ppc_adjtimex(); } @@ -348,7 +347,7 @@ long int tb_delta, new_usec, new_sec; unsigned long new_xsec; - write_lock_irqsave(&xtime_lock, flags); + write_seqlock_irqsave(&xtime_lock, flags); /* Updating the RTC is not the job of this code. If the time is * stepped under NTP, the RTC will be update after STA_UNSYNC * is cleared. Tool like clock/hwclock either copy the RTC @@ -399,7 +398,7 @@ do_gtod.tb_orig_stamp = tb_last_stamp; } - write_unlock_irqrestore(&xtime_lock, flags); + write_sequnlock_irqrestore(&xtime_lock, flags); } /* @@ -465,7 +464,7 @@ #endif ppc_md.get_boot_time(&tm); - write_lock_irqsave(&xtime_lock, flags); + write_seqlock_irqsave(&xtime_lock, flags); xtime.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); tb_last_stamp = get_tb(); @@ -484,7 +483,7 @@ xtime.tv_nsec = 0; last_rtc_update = xtime.tv_sec; - write_unlock_irqrestore(&xtime_lock, flags); + write_sequnlock_irqrestore(&xtime_lock, flags); /* Not exact, but the timer interrupt takes care of this */ set_dec(tb_ticks_per_jiffy); @@ -587,7 +586,7 @@ new_tb_to_xs = divres.result_low; new_xsec = mulhdu( tb_ticks, new_tb_to_xs ); - write_lock_irqsave( &xtime_lock, flags ); + write_seqlock_irqsave( &xtime_lock, flags ); old_xsec = mulhdu( tb_ticks, do_gtod.varp->tb_to_xs ); new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec; @@ -609,7 +608,7 @@ do_gtod.varp = temp_varp; do_gtod.var_idx = temp_idx; - write_unlock_irqrestore( &xtime_lock, flags ); + write_sequnlock_irqrestore( &xtime_lock, flags ); } diff -Nru a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c --- a/arch/ppc64/kernel/traps.c Sun Feb 9 21:13:32 2003 +++ b/arch/ppc64/kernel/traps.c Sun Feb 9 21:13:32 2003 @@ -81,8 +81,10 @@ _exception(int signr, siginfo_t *info, struct pt_regs *regs) { if (!user_mode(regs)) { +#ifdef CONFIG_DEBUG_KERNEL if (debugger) debugger(regs); +#endif die("Exception in kernel mode\n", regs, signr); } @@ -133,8 +135,10 @@ FWNMI_release_errinfo(); } +#ifdef CONFIG_DEBUG_KERNEL if (debugger) debugger(regs); +#endif #ifdef PANIC_ON_ERROR panic("System Reset"); @@ -174,13 +178,14 @@ return; } +#ifdef CONFIG_DEBUG_KERNEL if (debugger_fault_handler) { debugger_fault_handler(regs); return; } if (debugger) debugger(regs); - +#endif console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); @@ -223,9 +228,10 @@ { siginfo_t info; +#ifdef CONFIG_DEBUG_KERNEL if (debugger_iabr_match && debugger_iabr_match(regs)) return; - +#endif info.si_signo = SIGTRAP; info.si_errno = 0; info.si_code = TRAP_BRKPT; @@ -292,9 +298,10 @@ } else if (regs->msr & 0x20000) { /* trap exception */ +#ifdef CONFIG_DEBUG_KERNEL if (debugger_bpt && debugger_bpt(regs)) return; - +#endif info.si_signo = SIGTRAP; info.si_errno = 0; info.si_code = TRAP_BRKPT; @@ -318,9 +325,10 @@ regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ +#ifdef CONFIG_DEBUG_KERNEL if (debugger_sstep && debugger_sstep(regs)) return; - +#endif info.si_signo = SIGTRAP; info.si_errno = 0; info.si_code = TRAP_TRACE; diff -Nru a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile --- a/arch/ppc64/lib/Makefile Sun Feb 9 21:13:28 2003 +++ b/arch/ppc64/lib/Makefile Sun Feb 9 21:13:28 2003 @@ -4,7 +4,5 @@ L_TARGET = lib.a -export-objs := dec_and_lock.o - obj-y := checksum.o dec_and_lock.o string.o strcase.o obj-y += copypage.o memcpy.o copyuser.o diff -Nru a/arch/s390/Makefile b/arch/s390/Makefile --- a/arch/s390/Makefile Sun Feb 9 21:13:29 2003 +++ b/arch/s390/Makefile Sun Feb 9 21:13:29 2003 @@ -20,7 +20,7 @@ CFLAGS += -pipe -fno-strength-reduce -HEAD := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o +head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ libs-y += arch/$(ARCH)/lib/ @@ -38,7 +38,6 @@ install: vmlinux $(call makeboot, $@) -archmrproper: archclean: $(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/$(ARCH)/boot diff -Nru a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile --- a/arch/s390/kernel/Makefile Sun Feb 9 21:13:36 2003 +++ b/arch/s390/kernel/Makefile Sun Feb 9 21:13:36 2003 @@ -5,7 +5,6 @@ EXTRA_TARGETS := head.o init_task.o EXTRA_AFLAGS := -traditional -export-objs := debug.o ebcdic.o s390_ext.o smp.o s390_ksyms.o obj-y := entry.o bitmap.o traps.o time.o process.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ semaphore.o reipl.o s390_ext.o debug.o diff -Nru a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c --- a/arch/s390/kernel/signal.c Sun Feb 9 21:13:35 2003 +++ b/arch/s390/kernel/signal.c Sun Feb 9 21:13:35 2003 @@ -61,11 +61,11 @@ sigset_t saveset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->gprs[2] = -EINTR; while (1) { @@ -89,11 +89,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->gprs[2] = -EINTR; while (1) { @@ -194,10 +194,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigregs(regs, &frame->sregs)) goto badframe; @@ -220,10 +220,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigregs(regs, &frame->uc.uc_mcontext)) goto badframe; @@ -427,11 +427,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c --- a/arch/s390/kernel/time.c Sun Feb 9 21:13:28 2003 +++ b/arch/s390/kernel/time.c Sun Feb 9 21:13:28 2003 @@ -52,7 +52,6 @@ static uint64_t xtime_cc; static uint64_t init_timer_cc; -extern rwlock_t xtime_lock; extern unsigned long wall_jiffies; void tod_to_timeval(__u64 todval, struct timespec *xtime) @@ -83,12 +82,15 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; unsigned long usec, sec; - read_lock_irqsave(&xtime_lock, flags); - sec = xtime.tv_sec; - usec = xtime.tv_nsec / 1000 + do_gettimeoffset(); - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + + sec = xtime.tv_sec; + usec = xtime.tv_nsec / 1000 + do_gettimeoffset(); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; @@ -102,7 +104,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* This is revolting. We need to set the xtime.tv_nsec * correctly. However, the value in this location is * is value at the last tick. @@ -122,7 +124,7 @@ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } static inline __u32 div64_32(__u64 dividend, __u32 divisor) @@ -166,7 +168,7 @@ * Do not rely on the boot cpu to do the calls to do_timer. * Spread it over all cpus instead. */ - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); if (S390_lowcore.jiffy_timer > xtime_cc) { __u32 xticks; @@ -181,7 +183,7 @@ while (xticks--) do_timer(regs); } - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); while (ticks--) update_process_times(user_mode(regs)); #else diff -Nru a/arch/s390x/Makefile b/arch/s390x/Makefile --- a/arch/s390x/Makefile Sun Feb 9 21:13:32 2003 +++ b/arch/s390x/Makefile Sun Feb 9 21:13:32 2003 @@ -21,7 +21,7 @@ CFLAGS += -pipe -fno-strength-reduce -HEAD := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o +head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ libs-y += arch/$(ARCH)/lib/ @@ -38,7 +38,6 @@ install: vmlinux $(call makeboot, $@) -archmrproper: archclean: $(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/$(ARCH)/boot diff -Nru a/arch/s390x/kernel/Makefile b/arch/s390x/kernel/Makefile --- a/arch/s390x/kernel/Makefile Sun Feb 9 21:13:31 2003 +++ b/arch/s390x/kernel/Makefile Sun Feb 9 21:13:31 2003 @@ -5,9 +5,6 @@ EXTRA_TARGETS := head.o init_task.o EXTRA_AFLAGS := -traditional -export-objs := debug.o ebcdic.o s390_ext.o smp.o s390_ksyms.o \ - exec32.o - obj-y := entry.o bitmap.o traps.o time.o process.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ semaphore.o reipl.o s390_ext.o debug.o diff -Nru a/arch/s390x/kernel/linux32.c b/arch/s390x/kernel/linux32.c --- a/arch/s390x/kernel/linux32.c Sun Feb 9 21:13:34 2003 +++ b/arch/s390x/kernel/linux32.c Sun Feb 9 21:13:34 2003 @@ -1725,7 +1725,7 @@ return -EINVAL; } - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sig = dequeue_signal(&these, &info); if (!sig) { /* None ready -- temporarily unblock those we're interested @@ -1733,7 +1733,7 @@ current->real_blocked = current->blocked; sigandsets(¤t->blocked, ¤t->blocked, &these); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); timeout = MAX_SCHEDULE_TIMEOUT; if (uts) @@ -1743,13 +1743,13 @@ current->state = TASK_INTERRUPTIBLE; timeout = schedule_timeout(timeout); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sig = dequeue_signal(&these, &info); current->blocked = current->real_blocked; siginitset(¤t->real_blocked, 0); recalc_sigpending(); } - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (sig) { ret = sig; diff -Nru a/arch/s390x/kernel/signal.c b/arch/s390x/kernel/signal.c --- a/arch/s390x/kernel/signal.c Sun Feb 9 21:13:33 2003 +++ b/arch/s390x/kernel/signal.c Sun Feb 9 21:13:33 2003 @@ -60,11 +60,11 @@ sigset_t saveset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->gprs[2] = -EINTR; while (1) { @@ -88,11 +88,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->gprs[2] = -EINTR; while (1) { @@ -188,10 +188,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigregs(regs, &frame->sregs)) goto badframe; @@ -214,10 +214,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigregs(regs, &frame->uc.uc_mcontext)) goto badframe; @@ -421,11 +421,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/arch/s390x/kernel/signal32.c b/arch/s390x/kernel/signal32.c --- a/arch/s390x/kernel/signal32.c Sun Feb 9 21:13:31 2003 +++ b/arch/s390x/kernel/signal32.c Sun Feb 9 21:13:31 2003 @@ -112,11 +112,11 @@ sigset_t saveset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->gprs[2] = -EINTR; while (1) { @@ -147,11 +147,11 @@ } sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->gprs[2] = -EINTR; while (1) { @@ -345,10 +345,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigregs32(regs, &frame->sregs)) goto badframe; @@ -375,10 +375,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) goto badframe; @@ -588,11 +588,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/arch/s390x/kernel/time.c b/arch/s390x/kernel/time.c --- a/arch/s390x/kernel/time.c Sun Feb 9 21:13:35 2003 +++ b/arch/s390x/kernel/time.c Sun Feb 9 21:13:35 2003 @@ -51,7 +51,6 @@ static uint64_t xtime_cc; static uint64_t init_timer_cc; -extern rwlock_t xtime_lock; extern unsigned long wall_jiffies; void tod_to_timeval(__u64 todval, struct timespec *xtime) @@ -78,12 +77,14 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; unsigned long usec, sec; - read_lock_irqsave(&xtime_lock, flags); - sec = xtime.tv_sec; - usec = xtime.tv_nsec + do_gettimeoffset(); - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + sec = xtime.tv_sec; + usec = xtime.tv_nsec + do_gettimeoffset(); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; @@ -97,7 +98,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is * is value at the last tick. @@ -117,7 +118,7 @@ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } /* @@ -152,7 +153,7 @@ * Do not rely on the boot cpu to do the calls to do_timer. * Spread it over all cpus instead. */ - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); if (S390_lowcore.jiffy_timer > xtime_cc) { __u32 xticks; @@ -167,7 +168,7 @@ while (xticks--) do_timer(regs); } - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); while (ticks--) update_process_times(user_mode(regs)); #else diff -Nru a/arch/sh/Kconfig b/arch/sh/Kconfig --- a/arch/sh/Kconfig Sun Feb 9 21:13:37 2003 +++ b/arch/sh/Kconfig Sun Feb 9 21:13:37 2003 @@ -623,7 +623,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config BINFMT_MISC @@ -648,7 +648,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. source "drivers/parport/Kconfig" @@ -704,7 +704,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -731,7 +731,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -855,7 +855,7 @@ If you want to compile this driver as a module, say M here and read . The module will be called - serial.o. + serial. [WARNING: Do not compile this driver as a module if you are using non-standard serial ports, since the configuration information will be lost when the driver is unloaded. This limitation may be lifted @@ -992,7 +992,7 @@ driver as a module however ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read and - . The module will be called lp.o. + . The module will be called lp. If you have several parallel ports, you can specify which ports to use with the "lp" kernel command line option. (Try "man bootparam" @@ -1036,7 +1036,7 @@ This support is also available as a module. If you want to compile it as a module, say M here and read . The module will be called - ppdev.o. + ppdev. If unsure, say N. @@ -1108,7 +1108,7 @@ 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 shwdt.o. If you want to compile it as a module, + The module is called shwdt. If you want to compile it as a module, say M here and read Documentation/modules.txt. endmenu @@ -1137,7 +1137,7 @@ 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 rtc.o. If you want to compile it as a module, + The module is called rtc. If you want to compile it as a module, say M here and read . source "drivers/char/pcmcia/Kconfig" @@ -1175,7 +1175,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/sh/Makefile b/arch/sh/Makefile --- a/arch/sh/Makefile Sun Feb 9 21:13:33 2003 +++ b/arch/sh/Makefile Sun Feb 9 21:13:33 2003 @@ -53,7 +53,7 @@ # CFLAGS += -pipe -HEAD := arch/sh/kernel/head.o arch/sh/kernel/init_task.o +head-y := arch/sh/kernel/head.o arch/sh/kernel/init_task.o LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) @@ -80,6 +80,4 @@ $(MAKE) -C arch/$(ARCH)/kernel clean $(MAKE) -C arch/$(ARCH)/stboards clean # $(MAKE) -C arch/$(ARCH)/tools clean - -archmrproper: diff -Nru a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile --- a/arch/sh/kernel/Makefile Sun Feb 9 21:13:33 2003 +++ b/arch/sh/kernel/Makefile Sun Feb 9 21:13:33 2003 @@ -4,9 +4,6 @@ EXTRA_TARGETS := head.o init_task.o -export-objs := io.o io_generic.o io_hd64465.o setup_hd64465.o sh_ksyms.o \ - io_adx.o io_bigsur.o io_cat68701.o hd64465_gpio.o - obj-y := process.o signal.o entry.o traps.o irq.o irq_ipr.o \ ptrace.o setup.o time.o sys_sh.o semaphore.o \ irq_imask.o io.o io_generic.o sh_ksyms.o diff -Nru a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c --- a/arch/sh/kernel/io.c Sun Feb 9 21:13:31 2003 +++ b/arch/sh/kernel/io.c Sun Feb 9 21:13:31 2003 @@ -4,7 +4,7 @@ * Copyright (C) 2000 Stuart Menefy * * Provide real functions which expand to whatever the header file defined. - * Also definitions of machine independant IO functions. + * Also definitions of machine independent IO functions. */ #include diff -Nru a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c --- a/arch/sh/kernel/time.c Sun Feb 9 21:13:28 2003 +++ b/arch/sh/kernel/time.c Sun Feb 9 21:13:28 2003 @@ -72,7 +72,6 @@ u64 jiffies_64; -extern rwlock_t xtime_lock; extern unsigned long wall_jiffies; #define TICK_SIZE tick @@ -128,18 +127,20 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; unsigned long usec, sec; - read_lock_irqsave(&xtime_lock, flags); - usec = do_gettimeoffset(); - { - unsigned long lost = jiffies - wall_jiffies; - if (lost) - usec += lost * (1000000 / HZ); - } - sec = xtime.tv_sec; - usec += xtime.tv_usec; - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += xtime.tv_usec; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; @@ -152,7 +153,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* * This is revolting. We need to set "xtime" correctly. However, the * value in this location is the value at the most recent update of @@ -172,7 +173,7 @@ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } /* last time the RTC clock got updated */ @@ -231,9 +232,9 @@ * the irq version of write_lock because as just said we have irq * locally disabled. -arca */ - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); do_timer_interrupt(irq, NULL, regs); - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } static unsigned int __init get_timer_frequency(void) diff -Nru a/arch/sparc/Kconfig b/arch/sparc/Kconfig --- a/arch/sparc/Kconfig Sun Feb 9 21:13:28 2003 +++ b/arch/sparc/Kconfig Sun Feb 9 21:13:28 2003 @@ -182,8 +182,8 @@ This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - When compiled this way, there will be modules called pcmcia_core.o - and ds.o. If you want to compile it as a module, say M here and + When compiled this way, there will be modules called pcmcia_core + and ds. If you want to compile it as a module, say M here and read . config SBUS @@ -276,7 +276,7 @@ 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 openpromfs.o. If unsure, say M. + The module will be called openpromfs. If unsure, say M. config KCORE_ELF bool @@ -319,7 +319,7 @@ QMAGIC support" then you'll have to say Y here. You may answer M to compile a.out support as a module and later load the module when you want to use a program or library in a.out format. The module will be - called binfmt_aout.o. Saying M or N here is dangerous though, + called binfmt_aout. Saying M or N here is dangerous though, because some crucial programs on your system might still be in A.OUT format. @@ -349,7 +349,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config BINFMT_MISC @@ -374,7 +374,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. config SUNOS_EMUL @@ -404,7 +404,7 @@ driver as a module however ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read and - . The module will be called lp.o. + . The module will be called lp. If you have several parallel ports, you can specify which ports to use with the "lp" kernel command line option. (Try "man bootparam" @@ -442,7 +442,7 @@ 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 will be called floppy.o. If you want to compile it as a + The module will be called floppy. If you want to compile it as a module, say M here and read . config BLK_DEV_LOOP @@ -492,7 +492,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called loop.o. + will be called loop. Most users will answer N here. @@ -521,7 +521,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called nbd.o. + will be called nbd. If unsure, say N. @@ -543,7 +543,7 @@ 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 and read . The module will be - called rd.o. + called rd. Most normal users won't need the RAM disk functionality, and can thus say N here. @@ -613,7 +613,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -644,7 +644,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -665,7 +665,7 @@ 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 will be called sd_mod.o. If you want to compile it as a + The module will be called sd_mod. If you want to compile it as a module, say M here and read and . Do not compile this driver as a module if your root file system (the one containing the directory /) @@ -701,7 +701,7 @@ 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 will be called st.o. If you want to compile it as a + The module will be called st. If you want to compile it as a module, say M here and read and . @@ -726,7 +726,7 @@ 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 will be called osst.o. If you want to compile it as a + The module will be called osst. If you want to compile it as a module, say M here and read and . @@ -741,7 +741,7 @@ 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 will be called sr_mod.o. If you want to compile it as a + The module will be called sr_mod. If you want to compile it as a module, say M here and read and . @@ -794,7 +794,7 @@ 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 and - . The module will be called sg.o. + . The module will be called sg. If unsure, say N. comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs" @@ -856,7 +856,7 @@ This is the driver for the Sun ESP SCSI host adapter. The ESP chipset is present in most SPARC SBUS-based computers. - This support is also available as a module called esp.o ( = code + This support is also available as a module called esp ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -870,7 +870,7 @@ PTI,ptisp or QLGC,isp. Note that PCI QLogic SCSI controllers are driven by a different driver. - This support is also available as a module called qlogicpti.o ( = + This support is also available as a module called qlogicpti ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -963,7 +963,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. @@ -992,7 +992,7 @@ inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . The module will be called - softdog.o. + softdog. endmenu diff -Nru a/arch/sparc/Makefile b/arch/sparc/Makefile --- a/arch/sparc/Makefile Sun Feb 9 21:13:29 2003 +++ b/arch/sparc/Makefile Sun Feb 9 21:13:29 2003 @@ -37,7 +37,8 @@ # Actual linking is done with "make image". LDFLAGS_vmlinux = -r -HEAD := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o +head-y := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o +HEAD := $(head-y) core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/ libs-y += arch/sparc/prom/ arch/sparc/lib/ @@ -60,8 +61,6 @@ archclean: $(Q)$(MAKE) -f scripts/Makefile.clean obj=arch/$(ARCH)/boot - -archmrproper: prepare: include/asm-$(ARCH)/asm_offsets.h diff -Nru a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile --- a/arch/sparc/kernel/Makefile Sun Feb 9 21:13:35 2003 +++ b/arch/sparc/kernel/Makefile Sun Feb 9 21:13:35 2003 @@ -6,7 +6,6 @@ EXTRA_AFLAGS := -ansi -export-objs := sparc_ksyms.o IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \ process.o signal.o ioport.o setup.o idprom.o \ diff -Nru a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S --- a/arch/sparc/kernel/entry.S Sun Feb 9 21:13:32 2003 +++ b/arch/sparc/kernel/entry.S Sun Feb 9 21:13:32 2003 @@ -1808,6 +1808,15 @@ retl nop + .globl C_LABEL(ndelay) +C_LABEL(ndelay): + save %sp, -REGWIN_SZ, %sp + mov %i0, %o0 + call .umul + mov 5, %o1 + ba delay_continue + nop + .globl C_LABEL(udelay) C_LABEL(udelay): save %sp, -REGWIN_SZ, %sp @@ -1815,6 +1824,7 @@ sethi %hi(0x10c6), %o1 call .umul or %o1, %lo(0x10c6), %o1 +delay_continue: #ifndef CONFIG_SMP sethi %hi(C_LABEL(loops_per_jiffy)), %o3 call .umul @@ -1879,7 +1889,7 @@ wr %o4, 0x0, %psr ! the uwinmask state WRITE_PAUSE ! burn them cycles 1: - ld [%g6 + TI_UWINMASK], %o0 ! get consistant state + ld [%g6 + TI_UWINMASK], %o0 ! get consistent state orcc %g0, %o0, %g0 ! did an interrupt come in? be 4f ! yep, we are done rd %wim, %o3 ! get current wim diff -Nru a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c --- a/arch/sparc/kernel/pcic.c Sun Feb 9 21:13:32 2003 +++ b/arch/sparc/kernel/pcic.c Sun Feb 9 21:13:32 2003 @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -34,8 +35,6 @@ #include #include -extern rwlock_t xtime_lock; - #ifndef CONFIG_PCI asmlinkage int sys_pciconfig_read(unsigned long bus, @@ -739,10 +738,10 @@ static void pcic_timer_handler (int irq, void *h, struct pt_regs *regs) { - write_lock(&xtime_lock); /* Dummy, to show that we remember */ + write_seqlock(&xtime_lock); /* Dummy, to show that we remember */ pcic_clear_clock_irq(); do_timer(regs); - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } #define USECS_PER_JIFFY 10000 /* We have 100HZ "standard" timer for sparc */ @@ -795,18 +794,20 @@ static void pci_do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; unsigned long usec, sec; - read_lock_irqsave(&xtime_lock, flags); - usec = do_gettimeoffset(); - { - unsigned long lost = jiffies - wall_jiffies; - if (lost) - usec += lost * (1000000 / HZ); - } - sec = xtime.tv_sec; - usec += (xtime.tv_nsec / 1000); - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; diff -Nru a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c --- a/arch/sparc/kernel/signal.c Sun Feb 9 21:13:34 2003 +++ b/arch/sparc/kernel/signal.c Sun Feb 9 21:13:34 2003 @@ -104,11 +104,11 @@ sigset_t saveset; set &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, set); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->pc = regs->npc; regs->npc += 4; @@ -161,11 +161,11 @@ } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); oldset = current->blocked; current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->pc = regs->npc; regs->npc += 4; @@ -267,10 +267,10 @@ goto segv_and_exit; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return; segv_and_exit: @@ -314,10 +314,10 @@ goto segv_and_exit; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->pc = pc; regs->npc = npc; @@ -384,10 +384,10 @@ do_sigaltstack(&st, NULL, (unsigned long)sf); sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return; segv: send_sig(SIGSEGV, current, 1); @@ -967,10 +967,10 @@ set.sig[3] = setv.sigbits[3]; } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->pc = pc; regs->npc = npc | 1; err |= __get_user(regs->y, &((*gr) [SVR4_Y])); @@ -1007,11 +1007,11 @@ if(ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; if(!(ka->sa.sa_flags & SA_NOMASK)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked, signr); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } @@ -1066,9 +1066,9 @@ sigset_t *mask = ¤t->blocked; unsigned long signr = 0; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); signr = dequeue_signal(mask, &info); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (!signr) break; diff -Nru a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c --- a/arch/sparc/kernel/sparc_ksyms.c Sun Feb 9 21:13:29 2003 +++ b/arch/sparc/kernel/sparc_ksyms.c Sun Feb 9 21:13:29 2003 @@ -151,6 +151,7 @@ #endif EXPORT_SYMBOL(udelay); +EXPORT_SYMBOL(ndelay); EXPORT_SYMBOL(mostek_lock); EXPORT_SYMBOL(mstk48t02_regs); #if CONFIG_SUN_AUXIO diff -Nru a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c --- a/arch/sparc/kernel/sys_sparc.c Sun Feb 9 21:13:31 2003 +++ b/arch/sparc/kernel/sys_sparc.c Sun Feb 9 21:13:31 2003 @@ -409,7 +409,7 @@ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); if (!ret && oact) { - /* In the clone() case we could copy half consistant + /* In the clone() case we could copy half consistent * state to the user, however this could sleep and * deadlock us if we held the signal lock on SMP. So for * now I take the easy way out and do no locking. diff -Nru a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c --- a/arch/sparc/kernel/sys_sunos.c Sun Feb 9 21:13:31 2003 +++ b/arch/sparc/kernel/sys_sunos.c Sun Feb 9 21:13:31 2003 @@ -281,11 +281,11 @@ { unsigned long old; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); old = current->blocked.sig[0]; current->blocked.sig[0] |= (blk_mask & _BLOCKABLE); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return old; } @@ -293,11 +293,11 @@ { unsigned long retval; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); retval = current->blocked.sig[0]; current->blocked.sig[0] = (newmask & _BLOCKABLE); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return retval; } @@ -1168,7 +1168,7 @@ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); if (!ret && oact) { - /* In the clone() case we could copy half consistant + /* In the clone() case we could copy half consistent * state to the user, however this could sleep and * deadlock us if we held the signal lock on SMP. So for * now I take the easy way out and do no locking. diff -Nru a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c --- a/arch/sparc/kernel/time.c Sun Feb 9 21:13:32 2003 +++ b/arch/sparc/kernel/time.c Sun Feb 9 21:13:32 2003 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -42,8 +43,6 @@ #include #include -extern rwlock_t xtime_lock; - extern unsigned long wall_jiffies; u64 jiffies_64; @@ -131,7 +130,7 @@ #endif /* Protect counter clear so that do_gettimeoffset works */ - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); #ifdef CONFIG_SUN4 if((idprom->id_machtype == (SM_SUN4 | SM_4_260)) || (idprom->id_machtype == (SM_SUN4 | SM_4_110))) { @@ -155,7 +154,7 @@ else last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ } - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ @@ -470,18 +469,20 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; unsigned long usec, sec; - read_lock_irqsave(&xtime_lock, flags); - usec = do_gettimeoffset(); - { - unsigned long lost = jiffies - wall_jiffies; - if (lost) - usec += lost * (1000000 / HZ); - } - sec = xtime.tv_sec; - usec += (xtime.tv_nsec / 1000); - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; @@ -494,9 +495,9 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); bus_do_settimeofday(tv); - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } static void sbus_do_settimeofday(struct timeval *tv) diff -Nru a/arch/sparc/math-emu/math.c b/arch/sparc/math-emu/math.c --- a/arch/sparc/math-emu/math.c Sun Feb 9 21:13:31 2003 +++ b/arch/sparc/math-emu/math.c Sun Feb 9 21:13:31 2003 @@ -203,7 +203,7 @@ } /* All routines returning an exception to raise should detect - * such exceptions _before_ rounding to be consistant with + * such exceptions _before_ rounding to be consistent with * the behavior of the hardware in the implemented cases * (and thus with the recommendations in the V9 architecture * manual). diff -Nru a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c --- a/arch/sparc/mm/sun4c.c Sun Feb 9 21:13:34 2003 +++ b/arch/sparc/mm/sun4c.c Sun Feb 9 21:13:34 2003 @@ -1042,7 +1042,7 @@ get_locked_segment(addr); /* We are changing the virtual color of the page(s) - * so we must flush the cache to guarentee consistancy. + * so we must flush the cache to guarentee consistency. */ sun4c_flush_page(pages); #ifndef CONFIG_SUN4 diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig --- a/arch/sparc64/Kconfig Sun Feb 9 21:13:35 2003 +++ b/arch/sparc64/Kconfig Sun Feb 9 21:13:35 2003 @@ -232,7 +232,7 @@ Say Y here if you would like support for ISA Plug and Play devices. Some information is in . - This support is also available as a module called isapnp.o ( = + This support is also available as a module called isapnp ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -279,8 +279,8 @@ This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - When compiled this way, there will be modules called pcmcia_core.o - and ds.o. If you want to compile it as a module, say M here and + When compiled this way, there will be modules called pcmcia_core + and ds. If you want to compile it as a module, say M here and read . config SBUS @@ -338,7 +338,7 @@ 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 rtc.o. If you want to compile it as a module, + The module is called rtc. If you want to compile it as a module, say M here and read . source "drivers/pci/Kconfig" @@ -354,7 +354,7 @@ 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 openpromfs.o. If unsure, say M. + The module will be called openpromfs. If unsure, say M. config KCORE_ELF bool @@ -431,7 +431,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config BINFMT_MISC @@ -456,7 +456,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. config SUNOS_EMUL @@ -477,7 +477,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called solaris.o. If you want to compile it as a + The module will be called solaris. If you want to compile it as a module, say M here and read . source "drivers/parport/Kconfig" @@ -498,7 +498,7 @@ driver as a module however ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read and - . The module will be called lp.o. + . The module will be called lp. If you have several parallel ports, you can specify which ports to use with the "lp" kernel command line option. (Try "man bootparam" @@ -518,7 +518,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called envctrl.o. If you want to compile it as a + The module will be called envctrl. If you want to compile it as a module, say M here and read . config DISPLAY7SEG @@ -530,7 +530,7 @@ 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 will be called display7seg.o. If you want to compile it + The module will be called display7seg. If you want to compile it as a module, say M here and read . If you do not have a CompactPCI model CP1400 or CP1500, or @@ -546,7 +546,7 @@ 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 will be called cpwatchdog.o. If you want to compile it + The module will be called cpwatchdog. If you want to compile it as a module, say M here and read . If you do not have a CompactPCI model CP1400 or CP1500, or @@ -586,7 +586,7 @@ 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 will be called floppy.o. If you want to compile it as a + The module will be called floppy. If you want to compile it as a module, say M here and read . config BLK_DEV_LOOP @@ -636,7 +636,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called loop.o. + will be called loop. Most users will answer N here. @@ -665,7 +665,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called nbd.o. + will be called nbd. If unsure, say N. @@ -687,7 +687,7 @@ 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 and read . The module will be - called rd.o. + called rd. Most normal users won't need the RAM disk functionality, and can thus say N here. @@ -755,7 +755,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -782,7 +782,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -803,7 +803,7 @@ 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 will be called sd_mod.o. If you want to compile it as a + The module will be called sd_mod. If you want to compile it as a module, say M here and read and . Do not compile this driver as a module if your root file system (the one containing the directory /) @@ -839,7 +839,7 @@ 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 will be called st.o. If you want to compile it as a + The module will be called st. If you want to compile it as a module, say M here and read and . @@ -864,7 +864,7 @@ 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 will be called osst.o. If you want to compile it as a + The module will be called osst. If you want to compile it as a module, say M here and read and . @@ -879,7 +879,7 @@ 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 will be called sr_mod.o. If you want to compile it as a + The module will be called sr_mod. If you want to compile it as a module, say M here and read and . @@ -932,7 +932,7 @@ 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 and - . The module will be called sg.o. + . The module will be called sg. If unsure, say N. comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs" @@ -994,7 +994,7 @@ This is the driver for the Sun ESP SCSI host adapter. The ESP chipset is present in most SPARC SBUS-based computers. - This support is also available as a module called esp.o ( = code + This support is also available as a module called esp ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -1008,7 +1008,7 @@ PTI,ptisp or QLGC,isp. Note that PCI QLogic SCSI controllers are driven by a different driver. - This support is also available as a module called qlogicpti.o ( = + This support is also available as a module called qlogicpti ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -1060,7 +1060,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called aic7xxx_old.o. + will be called aic7xxx_old. config AIC7XXX_OLD_TCQ_ON_BY_DEFAULT bool "Enable Tagged Command Queueing (TCQ) by default" @@ -1404,7 +1404,7 @@ 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 will be called qlogicisp.o. If you want to compile it as + The module will be called qlogicisp. If you want to compile it as a module, say M here and read . config SCSI_QLOGIC_FC @@ -1415,7 +1415,7 @@ 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 will be called qlogicfc.o. If you want to compile it as + The module will be called qlogicfc. If you want to compile it as a module, say M here and read . config SCSI_QLOGIC_FC_FIRMWARE @@ -1502,7 +1502,7 @@ device or user software interacting with such a driver, please read the file . - This driver is also available as a module called videodev.o ( = code + This driver is also available as a module called videodev ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -1518,7 +1518,7 @@ If you say Y or M here, you need to say Y or M to "I2C support" and "I2C bit-banging interfaces" in the character device section. - This driver is available as a module called bttv.o ( = code + This driver is available as a module called bttv ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -1552,14 +1552,14 @@ depends on DRM help Choose this option if you have a 3dfx Banshee or Voodoo3 (or later), - graphics card. If M is selected, the module will be called tdfx.o. + graphics card. If M is selected, the module will be called tdfx. config DRM_R128 tristate "ATI Rage 128" depends on DRM help Choose this option if you have an ATI Rage 128 graphics card. If M - is selected, the module will be called r128.o. AGP support for + is selected, the module will be called r128. AGP support for this card is strongly suggested (unless you have a PCI version). endmenu @@ -1594,7 +1594,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. @@ -1623,7 +1623,7 @@ inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . The module will be called - softdog.o. + softdog. endmenu diff -Nru a/arch/sparc64/Makefile b/arch/sparc64/Makefile --- a/arch/sparc64/Makefile Sun Feb 9 21:13:37 2003 +++ b/arch/sparc64/Makefile Sun Feb 9 21:13:37 2003 @@ -61,7 +61,7 @@ CFLAGS := $(CFLAGS) -pg endif -HEAD := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o +head-y := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o core-y += arch/sparc64/kernel/ arch/sparc64/mm/ core-$(CONFIG_SOLARIS_EMUL) += arch/sparc64/solaris/ @@ -73,10 +73,6 @@ tftpboot.img vmlinux.aout: $(Q)$(MAKE) $(build)=arch/sparc64/boot arch/sparc64/boot/$@ - -archclean: - -archmrproper: define archhelp echo '* vmlinux - Standard sparc64 kernel' diff -Nru a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile --- a/arch/sparc64/kernel/Makefile Sun Feb 9 21:13:29 2003 +++ b/arch/sparc64/kernel/Makefile Sun Feb 9 21:13:29 2003 @@ -6,7 +6,6 @@ EXTRA_TARGETS := head.o init_task.o -export-objs := sparc64_ksyms.o ebus.o obj-y := process.o setup.o cpu.o idprom.o \ traps.o devices.o auxio.o \ irq.o ptrace.o time.o sys_sparc.o signal.o \ diff -Nru a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c --- a/arch/sparc64/kernel/power.c Sun Feb 9 21:13:35 2003 +++ b/arch/sparc64/kernel/power.c Sun Feb 9 21:13:35 2003 @@ -70,9 +70,9 @@ again: while (button_pressed == 0) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); flush_signals(current); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); interruptible_sleep_on(&powerd_wait); } diff -Nru a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c --- a/arch/sparc64/kernel/sbus.c Sun Feb 9 21:13:37 2003 +++ b/arch/sparc64/kernel/sbus.c Sun Feb 9 21:13:37 2003 @@ -767,7 +767,7 @@ } imap += reg_base; - /* SYSIO inconsistancy. For external SLOTS, we have to select + /* SYSIO inconsistency. For external SLOTS, we have to select * the right ICLR register based upon the lower SBUS irq level * bits. */ diff -Nru a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c --- a/arch/sparc64/kernel/signal.c Sun Feb 9 21:13:32 2003 +++ b/arch/sparc64/kernel/signal.c Sun Feb 9 21:13:32 2003 @@ -9,6 +9,9 @@ */ #include +#ifdef CONFIG_SPARC32_COMPAT +#include /* for compat_old_sigset_t */ +#endif #include #include #include @@ -67,10 +70,10 @@ goto do_sigsegv; } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } if (test_thread_flag(TIF_32BIT)) { pc &= 0xffffffff; @@ -247,18 +250,18 @@ #ifdef CONFIG_SPARC32_COMPAT if (test_thread_flag(TIF_32BIT)) { - extern asmlinkage void _sigpause32_common(old_sigset_t32, + extern asmlinkage void _sigpause32_common(compat_old_sigset_t, struct pt_regs *); _sigpause32_common(set, regs); return; } #endif set &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, set); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (test_thread_flag(TIF_32BIT)) { regs->tpc = (regs->tnpc & 0xffffffff); @@ -314,11 +317,11 @@ } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); oldset = current->blocked; current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (test_thread_flag(TIF_32BIT)) { regs->tpc = (regs->tnpc & 0xffffffff); @@ -425,10 +428,10 @@ set_fs(old_fs); sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return; segv: send_sig(SIGSEGV, current, 1); @@ -561,11 +564,11 @@ if (ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NOMASK)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,signr); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } @@ -616,9 +619,9 @@ sigset_t *mask = ¤t->blocked; unsigned long signr = 0; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); signr = dequeue_signal(mask, &info); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (!signr) break; diff -Nru a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c --- a/arch/sparc64/kernel/signal32.c Sun Feb 9 21:13:28 2003 +++ b/arch/sparc64/kernel/signal32.c Sun Feb 9 21:13:28 2003 @@ -56,7 +56,7 @@ /* struct sigcontext32 * */ u32 sig_scptr; int sig_address; struct sigcontext32 sig_context; - unsigned extramask[_NSIG_WORDS32 - 1]; + unsigned extramask[_COMPAT_NSIG_WORDS - 1]; }; /* @@ -69,7 +69,7 @@ __siginfo32_t info; /* __siginfo_fpu32_t * */ u32 fpu_save; unsigned int insns [2]; - unsigned extramask[_NSIG_WORDS32 - 1]; + unsigned extramask[_COMPAT_NSIG_WORDS - 1]; unsigned extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ siginfo_extra_v8plus_t v8plus; @@ -80,7 +80,7 @@ struct sparc_stackf32 ss; siginfo_t32 info; struct pt_regs32 regs; - sigset_t32 mask; + compat_sigset_t mask; /* __siginfo_fpu32_t * */ u32 fpu_save; unsigned int insns [2]; stack_t32 stack; @@ -139,16 +139,16 @@ * atomically swap in the new signal mask, and wait for a signal. * This is really tricky on the Sparc, watch out... */ -asmlinkage void _sigpause32_common(old_sigset_t32 set, struct pt_regs *regs) +asmlinkage void _sigpause32_common(compat_old_sigset_t set, struct pt_regs *regs) { sigset_t saveset; set &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, set); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->tpc = regs->tnpc; regs->tnpc += 4; @@ -179,7 +179,7 @@ asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *regs) { sigset_t oldset, set; - sigset_t32 set32; + compat_sigset_t set32; /* XXX: Don't preclude handling different sized sigset_t's. */ if (((compat_size_t)sigsetsize) != sizeof(sigset_t)) { @@ -199,11 +199,11 @@ case 1: set.sig[0] = set32.sig[0] + (((long)set32.sig[1]) << 32); } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); oldset = current->blocked; current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->tpc = regs->tnpc; regs->tnpc += 4; @@ -256,7 +256,7 @@ unsigned int psr; unsigned pc, npc, fpu_save; sigset_t set; - unsigned seta[_NSIG_WORDS32]; + unsigned seta[_COMPAT_NSIG_WORDS]; int err, i; regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL; @@ -302,7 +302,7 @@ if (fpu_save) err |= restore_fpu_state32(regs, &sf->fpu_state); err |= __get_user(seta[0], &sf->info.si_mask); - err |= copy_from_user(seta+1, &sf->extramask, (_NSIG_WORDS32 - 1) * sizeof(unsigned)); + err |= copy_from_user(seta+1, &sf->extramask, (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned)); if (err) goto segv; switch (_NSIG_WORDS) { @@ -312,10 +312,10 @@ case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32); } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return; segv: @@ -327,7 +327,7 @@ struct sigcontext32 *scptr; unsigned pc, npc, psr; sigset_t set; - unsigned seta[_NSIG_WORDS32]; + unsigned seta[_COMPAT_NSIG_WORDS]; int err; synchronize_user_stack(); @@ -349,7 +349,7 @@ err |= __get_user(seta[0], &scptr->sigc_mask); /* Note that scptr + 1 points to extramask */ - err |= copy_from_user(seta+1, scptr + 1, (_NSIG_WORDS32 - 1) * sizeof(unsigned)); + err |= copy_from_user(seta+1, scptr + 1, (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned)); if (err) goto segv; switch (_NSIG_WORDS) { @@ -359,10 +359,10 @@ case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32); } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (test_thread_flag(TIF_32BIT)) { pc &= 0xffffffff; @@ -393,7 +393,7 @@ unsigned pc, npc, fpu_save; mm_segment_t old_fs; sigset_t set; - sigset_t32 seta; + compat_sigset_t seta; stack_t st; int err, i; @@ -440,7 +440,7 @@ err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) err |= restore_fpu_state32(regs, &sf->fpu_state); - err |= copy_from_user(&seta, &sf->mask, sizeof(sigset_t32)); + err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); err |= __get_user((long)st.ss_sp, &sf->stack.ss_sp); err |= __get_user(st.ss_flags, &sf->stack.ss_flags); err |= __get_user(st.ss_size, &sf->stack.ss_size); @@ -461,10 +461,10 @@ case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32); } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return; segv: do_exit(SIGSEGV); @@ -498,7 +498,7 @@ { struct signal_sframe32 *sframep; struct sigcontext32 *sc; - unsigned seta[_NSIG_WORDS32]; + unsigned seta[_COMPAT_NSIG_WORDS]; int err = 0; void *sig_address; int sig_code; @@ -544,7 +544,7 @@ } err |= __put_user(seta[0], &sc->sigc_mask); err |= __copy_to_user(sframep->extramask, seta + 1, - (_NSIG_WORDS32 - 1) * sizeof(unsigned)); + (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned)); err |= __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp); err |= __put_user(pc, &sc->sigc_pc); err |= __put_user(npc, &sc->sigc_npc); @@ -673,7 +673,7 @@ int sigframe_size; u32 psr; int i, err; - unsigned seta[_NSIG_WORDS32]; + unsigned seta[_COMPAT_NSIG_WORDS]; /* 1. Make sure everything is clean */ synchronize_user_stack(); @@ -729,7 +729,7 @@ } err |= __put_user(seta[0], &sf->info.si_mask); err |= __copy_to_user(sf->extramask, seta + 1, - (_NSIG_WORDS32 - 1) * sizeof(unsigned)); + (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned)); err |= copy_in_user((u32 *)sf, (u32 *)(regs->u_regs[UREG_FP]), @@ -1059,10 +1059,10 @@ set_fs(old_fs); sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->tpc = pc; regs->tnpc = npc | 1; if (test_thread_flag(TIF_32BIT)) { @@ -1098,7 +1098,7 @@ int sigframe_size; u32 psr; int i, err; - sigset_t32 seta; + compat_sigset_t seta; /* 1. Make sure everything is clean */ synchronize_user_stack(); @@ -1160,7 +1160,7 @@ case 1: seta.sig[1] = (oldset->sig[0] >> 32); seta.sig[0] = oldset->sig[0]; } - err |= __copy_to_user(&sf->mask, &seta, sizeof(sigset_t32)); + err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t)); err |= copy_in_user((u32 *)sf, (u32 *)(regs->u_regs[UREG_FP]), @@ -1241,11 +1241,11 @@ if (ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NOMASK)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,signr); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } @@ -1288,9 +1288,9 @@ sigset_t *mask = ¤t->blocked; unsigned long signr = 0; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); signr = dequeue_signal(mask, &info); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (!signr) break; diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c --- a/arch/sparc64/kernel/sys_sparc32.c Sun Feb 9 21:13:33 2003 +++ b/arch/sparc64/kernel/sys_sparc32.c Sun Feb 9 21:13:33 2003 @@ -1681,7 +1681,7 @@ extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset); -asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset) +asmlinkage int sys32_sigprocmask(int how, compat_old_sigset_t *set, compat_old_sigset_t *oset) { old_sigset_t s; int ret; @@ -1698,15 +1698,15 @@ extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize); -asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, compat_size_t sigsetsize) +asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset, compat_size_t sigsetsize) { sigset_t s; - sigset_t32 s32; + compat_sigset_t s32; int ret; mm_segment_t old_fs = get_fs(); if (set) { - if (copy_from_user (&s32, set, sizeof(sigset_t32))) + 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); @@ -1726,7 +1726,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(sigset_t32))) + if (copy_to_user (oset, &s32, sizeof(compat_sigset_t))) return -EFAULT; } return 0; @@ -1734,7 +1734,7 @@ extern asmlinkage int sys_sigpending(old_sigset_t *set); -asmlinkage int sys32_sigpending(old_sigset_t32 *set) +asmlinkage int sys32_sigpending(compat_old_sigset_t *set) { old_sigset_t s; int ret; @@ -1749,10 +1749,10 @@ extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize); -asmlinkage int sys32_rt_sigpending(sigset_t32 *set, compat_size_t sigsetsize) +asmlinkage int sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize) { sigset_t s; - sigset_t32 s32; + compat_sigset_t s32; int ret; mm_segment_t old_fs = get_fs(); @@ -1766,19 +1766,19 @@ 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(sigset_t32))) + if (copy_to_user (set, &s32, sizeof(compat_sigset_t))) return -EFAULT; } return ret; } asmlinkage int -sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo, +sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo, struct compat_timespec *uts, compat_size_t sigsetsize) { int ret, sig; sigset_t these; - sigset_t32 these32; + compat_sigset_t these32; struct timespec ts; siginfo_t info; long timeout = 0; @@ -1787,7 +1787,7 @@ if (sigsetsize != sizeof(sigset_t)) return -EINVAL; - if (copy_from_user (&these32, uthese, sizeof(sigset_t32))) + if (copy_from_user (&these32, uthese, sizeof(compat_sigset_t))) return -EFAULT; switch (_NSIG_WORDS) { @@ -1812,7 +1812,7 @@ return -EINVAL; } - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sig = dequeue_signal(&these, &info); if (!sig) { timeout = MAX_SCHEDULE_TIMEOUT; @@ -1827,19 +1827,19 @@ current->real_blocked = current->blocked; sigandsets(¤t->blocked, ¤t->blocked, &these); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; timeout = schedule_timeout(timeout); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sig = dequeue_signal(&these, &info); current->blocked = current->real_blocked; siginitset(¤t->real_blocked, 0); recalc_sigpending(); } } - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (sig) { ret = sig; @@ -2718,7 +2718,7 @@ } if (act) { - old_sigset_t32 mask; + compat_old_sigset_t mask; ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler); ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer); @@ -2748,10 +2748,10 @@ { struct k_sigaction new_ka, old_ka; int ret; - sigset_t32 set32; + compat_sigset_t set32; /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t32)) + if (sigsetsize != sizeof(compat_sigset_t)) return -EINVAL; /* All tasks which use RT signals (effectively) use @@ -2762,7 +2762,7 @@ if (act) { new_ka.ka_restorer = restorer; ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler); - ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(sigset_t32)); + ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t)); switch (_NSIG_WORDS) { case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32); case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32); @@ -2785,7 +2785,7 @@ case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0]; } ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler); - ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset_t32)); + ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)); ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer); if (ret) diff -Nru a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c --- a/arch/sparc64/kernel/sys_sunos32.c Sun Feb 9 21:13:33 2003 +++ b/arch/sparc64/kernel/sys_sunos32.c Sun Feb 9 21:13:33 2003 @@ -238,11 +238,11 @@ { u32 old; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); old = (u32) current->blocked.sig[0]; current->blocked.sig[0] |= (blk_mask & _BLOCKABLE); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return old; } @@ -250,11 +250,11 @@ { u32 retval; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); retval = (u32) current->blocked.sig[0]; current->blocked.sig[0] = (newmask & _BLOCKABLE); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return retval; } @@ -1297,7 +1297,7 @@ int ret; if (act) { - old_sigset_t32 mask; + compat_old_sigset_t mask; if (get_user((long)new_ka.sa.sa_handler, &((struct old_sigaction32 *)A(act))->sa_handler) || __get_user(new_ka.sa.sa_flags, &((struct old_sigaction32 *)A(act))->sa_flags)) diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S --- a/arch/sparc64/kernel/systbls.S Sun Feb 9 21:13:31 2003 +++ b/arch/sparc64/kernel/systbls.S Sun Feb 9 21:13:31 2003 @@ -65,9 +65,6 @@ .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 .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 - - /* 234 and 235 were for the hugetlb syscalls. They can be reused */ - /*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 /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler diff -Nru a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c --- a/arch/sparc64/kernel/time.c Sun Feb 9 21:13:32 2003 +++ b/arch/sparc64/kernel/time.c Sun Feb 9 21:13:32 2003 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -37,8 +38,6 @@ #include #include -extern rwlock_t xtime_lock; - spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED; spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; unsigned long mstk48t02_regs = 0UL; @@ -134,7 +133,7 @@ { unsigned long ticks, pstate; - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); do { #ifndef CONFIG_SMP @@ -196,13 +195,13 @@ timer_check_rtc(); - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } #ifdef CONFIG_SMP void timer_tick_interrupt(struct pt_regs *regs) { - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); do_timer(regs); @@ -225,7 +224,7 @@ timer_check_rtc(); - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } #endif @@ -665,7 +664,7 @@ if (this_is_starfire) return; - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); /* * This is revolting. We need to set "xtime" correctly. However, the * value in this location is the value at the most recent update of @@ -686,7 +685,7 @@ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } /* Ok, my cute asm atomicity trick doesn't work anymore. @@ -696,18 +695,20 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long seq; unsigned long usec, sec; - read_lock_irqsave(&xtime_lock, flags); - usec = do_gettimeoffset(); - { - unsigned long lost = jiffies - wall_jiffies; - if (lost) - usec += lost * (1000000 / HZ); - } - sec = xtime.tv_sec; - usec += (xtime.tv_nsec / 1000); - read_unlock_irqrestore(&xtime_lock, flags); + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; diff -Nru a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S --- a/arch/sparc64/kernel/winfixup.S Sun Feb 9 21:13:32 2003 +++ b/arch/sparc64/kernel/winfixup.S Sun Feb 9 21:13:32 2003 @@ -60,7 +60,7 @@ sll %g2, 3, %g2 ! NORMAL-->OTHER wrpr %g0, 0x0, %canrestore ! Standard etrap stuff. - wrpr %g2, 0x0, %wstate ! This must be consistant. + wrpr %g2, 0x0, %wstate ! This must be consistent. wrpr %g0, 0x0, %otherwin ! We know this. mov PRIMARY_CONTEXT, %g1 ! Change contexts... stxa %g0, [%g1] ASI_DMMU ! Back into the nucleus. @@ -181,7 +181,7 @@ sll %g2, 3, %g2 ! NORMAL-->OTHER wrpr %g0, 0x0, %canrestore ! Standard etrap stuff. - wrpr %g2, 0x0, %wstate ! This must be consistant. + wrpr %g2, 0x0, %wstate ! This must be consistent. wrpr %g0, 0x0, %otherwin ! We know this. mov PRIMARY_CONTEXT, %g1 ! Change contexts... stxa %g0, [%g1] ASI_DMMU ! Back into the nucleus. @@ -287,7 +287,7 @@ sll %g2, 3, %g2 ! NORMAL-->OTHER wrpr %g0, 0x0, %canrestore ! Standard etrap stuff. - wrpr %g2, 0x0, %wstate ! This must be consistant. + wrpr %g2, 0x0, %wstate ! This must be consistent. wrpr %g0, 0x0, %otherwin ! We know this. mov PRIMARY_CONTEXT, %g1 ! Change contexts... stxa %g0, [%g1] ASI_DMMU ! Back into the nucleus. diff -Nru a/arch/sparc64/math-emu/math.c b/arch/sparc64/math-emu/math.c --- a/arch/sparc64/math-emu/math.c Sun Feb 9 21:13:33 2003 +++ b/arch/sparc64/math-emu/math.c Sun Feb 9 21:13:33 2003 @@ -88,7 +88,7 @@ #define FSR_CEXC_MASK (0x1fUL << FSR_CEXC_SHIFT) /* All routines returning an exception to raise should detect - * such exceptions _before_ rounding to be consistant with + * such exceptions _before_ rounding to be consistent with * the behavior of the hardware in the implemented cases * (and thus with the recommendations in the V9 architecture * manual). diff -Nru a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c --- a/arch/sparc64/mm/hugetlbpage.c Sun Feb 9 21:13:34 2003 +++ b/arch/sparc64/mm/hugetlbpage.c Sun Feb 9 21:13:34 2003 @@ -288,6 +288,7 @@ page = pte_page(pte); if (pages) { page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT); + get_page(page); pages[i] = page; } if (vmas) @@ -584,11 +585,6 @@ page = alloc_pages(GFP_ATOMIC, HUGETLB_PAGE_ORDER); if (page == NULL) break; - map = page; - for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) { - SetPageReserved(map); - map++; - } spin_lock(&htlbpage_lock); list_add(&page->list, &htlbpage_freelist); htlbpagemem++; @@ -613,7 +609,6 @@ map->flags &= ~(1UL << PG_locked | 1UL << PG_error | 1UL << PG_referenced | 1UL << PG_dirty | 1UL << PG_active | - 1UL << PG_reserved | 1UL << PG_private | 1UL << PG_writeback); set_page_count(page, 0); map++; @@ -624,6 +619,14 @@ return (int) htlbzone_pages; } +static struct page * +hugetlb_nopage(struct vm_area_struct *vma, unsigned long address, int unused) +{ + BUG(); + return NULL; +} + static struct vm_operations_struct hugetlb_vm_ops = { + .nopage = hugetlb_nopage, .close = zap_hugetlb_resources, }; diff -Nru a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c --- a/arch/sparc64/solaris/signal.c Sun Feb 9 21:13:37 2003 +++ b/arch/sparc64/solaris/signal.c Sun Feb 9 21:13:37 2003 @@ -99,16 +99,16 @@ static long solaris_sigset(int sig, u32 arg) { if (arg != 2) /* HOLD */ { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigdelsetmask(¤t->blocked, _S(sig)); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return sig_handler (sig, arg, 0); } else { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigaddsetmask(¤t->blocked, (_S(sig) & ~_BLOCKABLE)); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return 0; } } @@ -120,10 +120,10 @@ static inline long solaris_sigrelse(int sig) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigdelsetmask(¤t->blocked, _S(sig)); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return 0; } @@ -311,10 +311,10 @@ u32 tmp[4]; switch (which) { case 1: /* sigpending */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigandsets(&s, ¤t->blocked, ¤t->pending.signal); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); break; case 2: /* sigfillset - I just set signals which have linux equivalents */ sigfillset(&s); diff -Nru a/arch/um/Kconfig b/arch/um/Kconfig --- a/arch/um/Kconfig Sun Feb 9 21:13:32 2003 +++ b/arch/um/Kconfig Sun Feb 9 21:13:32 2003 @@ -30,36 +30,42 @@ bool default y +menu "UML-specific options" + config MODE_TT - bool + bool "Tracing thread support" default y + help + This option controls whether tracing thread support is compiled + into UML. Normally, this should be set to Y. If you intend to + use only skas mode (and the host has the skas patch applied to it), + then it is OK to say N here. + +config STATIC_LINK + bool "Force a static link" + default n + depends on !MODE_TT + help + If CONFIG_MODE_TT is disabled, then this option gives you the ability + to force a static link of UML. Normally, if only skas mode is built + in to UML, it will be linked as a shared binary. This is inconvenient + for use in a chroot jail. So, if you intend to run UML inside a + chroot, and you disable CONFIG_MODE_TT, you probably want to say Y + here. config MODE_SKAS - bool + bool "Separate Kernel Address Space support" default y - -menu "Code maturity level options" - -config EXPERIMENTAL - bool "Prompt for development and/or incomplete code/drivers" - -endmenu - - -menu "General Setup" + help + This option controls whether skas (separate kernel address space) + support is compiled in. If you have applied the skas patch to the + host, then you certainly want to say Y here (and consider saying N + to CONFIG_MODE_TT). Otherwise, it is safe to say Y. Disabling this + option will shrink the UML binary slightly. config NET bool "Networking support" -config SYSVIPC - bool "System V IPC" - -config BSD_PROCESS_ACCT - bool "BSD Process Accounting" - -config SYSCTL - bool "Sysctl support" - config BINFMT_AOUT tristate "Kernel support for a.out binaries" @@ -164,22 +170,18 @@ config HIGHMEM bool "Highmem support" -endmenu - - -menu "Loadable module support" - -config MODULES - bool "Enable loadable module support" - -# MODVERSIONS does not yet work in this architecture -# bool ' Set version information on all module symbols' CONFIG_MODVERSIONS -config KMOD - bool "Kernel module loader" - depends on MODULES +config KERNEL_STACK_ORDER + int "Kernel stack size order" + default 2 + help + This option determines the size of UML kernel stacks. They will + be 1 << order pages. The default is OK unless you're running Valgrind + on UML, in which case, set this to 3. endmenu +source "init/Kconfig" + source "arch/um/Kconfig_char" source "arch/um/Kconfig_block" @@ -194,6 +196,10 @@ source "fs/Kconfig" +source "security/Kconfig" + +source "crypto/Kconfig" + source "lib/Kconfig" menu "SCSI support" @@ -221,6 +227,9 @@ config DEBUG_SLAB bool "Debug memory allocations" +config DEBUG_SPINLOCK + bool "Debug spinlocks usage" + config DEBUGSYM bool "Enable kernel debugging symbols" help @@ -231,6 +240,10 @@ If you're truly short on disk space or don't expect to report any bugs back to the UML developers, say N, otherwise say Y. + +config FRAME_POINTER + bool + default y if DEBUGSYM config PT_PROXY bool "Enable ptrace proxy" diff -Nru a/arch/um/Makefile b/arch/um/Makefile --- a/arch/um/Makefile Sun Feb 9 21:13:33 2003 +++ b/arch/um/Makefile Sun Feb 9 21:13:33 2003 @@ -6,9 +6,6 @@ ARCH_DIR = arch/um OS := $(shell uname -s) -EXTRAVERSION := $(EXTRAVERSION)-1um -include/linux/version.h: arch/$(ARCH)/Makefile - # Recalculate MODLIB to reflect the EXTRAVERSION changes (via KERNELRELEASE) # The way the toplevel Makefile is written EXTRAVERSION is not supposed # to be changed outside the toplevel Makefile, but recalculating MODLIB is @@ -21,17 +18,34 @@ endif CFLAGS-$(CONFIG_DEBUGSYM) += -g -CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage -CFLAGS-$(CONFIG_GPROF) += $(PROFILE) -LINK-$(CONFIG_GPROF) += $(PROFILE) -Wl,--wrap,__monstartup core-y += $(ARCH_DIR)/kernel/ \ $(ARCH_DIR)/drivers/ \ $(ARCH_DIR)/sys-$(SUBARCH)/ +# Have to precede the include because the included Makefiles reference them. +SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \ + include/asm-um/sigcontext.h include/asm-um/processor.h \ + include/asm-um/ptrace.h include/asm-um/arch-signal.h + +ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \ + $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h + +GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h + +include $(ARCH_DIR)/Makefile-$(SUBARCH) +include $(ARCH_DIR)/Makefile-os-$(OS) + +MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt +MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas + +ifneq ($(MAKEFILE-y),) + include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y)) +endif + +EXTRAVERSION := $(EXTRAVERSION)-1um + ARCH_INCLUDE = -I$(ARCH_DIR)/include -MODE_INCLUDE = -I$(ARCH_DIR)/kernel/tt/include \ - -I$(ARCH_DIR)/kernel/skas/include # -Derrno=kernel_errno - This turns all kernel references to errno into # kernel_errno to separate them from the libc errno. This allows -fno-common @@ -46,23 +60,11 @@ SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000) -SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \ - include/asm-um/sigcontext.h include/asm-um/processor.h \ - include/asm-um/ptrace.h include/asm-um/arch-signal.h - -ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \ - $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h - ifeq ($(CONFIG_MODE_SKAS), y) -GEN_HEADERS = $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h - $(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h endif -GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h - -include $(ARCH_DIR)/Makefile-$(SUBARCH) -include $(ARCH_DIR)/Makefile-os-$(OS) +include/linux/version.h: arch/$(ARCH)/Makefile $(ARCH_DIR)/vmlinux.lds.S : touch $@ @@ -73,16 +75,46 @@ vmlinux: $(ARCH_DIR)/main.o -$(ARCH_DIR)/uml.lds.s : $(ARCH_DIR)/uml.lds.S scripts FORCE - $(call if_changed_dep,as_s_S) +# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT + +# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case. -AFLAGS_uml.lds.o = -U$(SUBARCH) -DSTART=$$(($(TOP_ADDR) - $(SIZE))) \ - -DELF_ARCH=$(ELF_ARCH) -DELF_FORMAT=\"$(ELF_FORMAT)\" -P -C -Uum +LINK_TT = -static +LD_SCRIPT_TT := uml.lds.s -linux: $(ARCH_DIR)/uml.lds.s vmlinux - $(CC) -Wl,-T,$(ARCH_DIR)/uml.lds.s -static $(LINK-y) $(LINK_WRAPS) \ - -o linux $(ARCH_DIR)/main.o vmlinux -L/usr/lib -lutil +ifeq ($(CONFIG_STATIC_LINK),y) + LINK-y += $(LINK_TT) + LD_SCRIPT-y := $(LD_SCRIPT_TT) +else +ifeq ($(CONFIG_MODE_TT),y) + LINK-y += $(LINK_TT) + LD_SCRIPT-y := $(LD_SCRIPT_TT) +else +ifeq ($(CONFIG_MODE_SKAS),y) + LINK-y += $(LINK_SKAS) + LD_SCRIPT-y := $(LD_SCRIPT_SKAS) +endif +endif +endif + +CPP_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT) +CONFIG_KERNEL_STACK_ORDER ?= 2 +STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) + +AFLAGS_vmlinux.lds.o = -U$(SUBARCH) \ + -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \ + -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \ + -DKERNEL_STACK_SIZE=$(STACK_SIZE) + +AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum +LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y) + +$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE + $(call if_changed_dep,as_s_S) + +linux: vmlinux $(LD_SCRIPT-y) + $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \ + -o linux $(ARCH_DIR)/main.o vmlinux -L/usr/lib -lutil USER_CFLAGS := $(patsubst -I%,,$(CFLAGS)) USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS)) @@ -92,7 +124,8 @@ # To get a definition of F_SETSIG USER_CFLAGS += -D_GNU_SOURCE -CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/link.ld $(GEN_HEADERS) +CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \ + $(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS) $(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< @@ -102,8 +135,7 @@ do \ $(MAKE) -C $$d archmrproper; \ done - rm -f $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \ - $(ARCH_DIR)/link.ld \ + rm -f $(CLEAN_FILES) $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \ $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) archclean: sysclean @@ -132,7 +164,7 @@ cd $(ARCH_DIR) && ln -sf os-$(OS) os $(ARCH_DIR)/include/uml-config.h : - ln -sf $(TOPDIR)/include/linux/autoconf.h $@ + sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@ $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task $< > $@ @@ -145,8 +177,5 @@ $(ARCH_DIR)/util: FORCE @$(call descend,$@,) - -$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h : - $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h export SUBARCH USER_CFLAGS OS diff -Nru a/arch/um/Makefile-skas b/arch/um/Makefile-skas --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/um/Makefile-skas Sun Feb 9 21:13:37 2003 @@ -0,0 +1,20 @@ +# +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) +# Licensed under the GPL +# + +PROFILE += -pg + +CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage +CFLAGS-$(CONFIG_GPROF) += $(PROFILE) +LINK-$(CONFIG_GPROF) += $(PROFILE) + +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/skas/include + +LINK_SKAS = -Wl,-rpath,/lib +LD_SCRIPT_SKAS = dyn.lds.s + +GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h + +$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h : + $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h diff -Nru a/arch/um/Makefile-tt b/arch/um/Makefile-tt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/um/Makefile-tt Sun Feb 9 21:13:38 2003 @@ -0,0 +1,7 @@ +# +# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) +# Licensed under the GPL +# + +MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/tt/include + diff -Nru a/arch/um/defconfig b/arch/um/defconfig --- a/arch/um/defconfig Sun Feb 9 21:13:33 2003 +++ b/arch/um/defconfig Sun Feb 9 21:13:33 2003 @@ -2,11 +2,11 @@ # Automatically generated make config: don't edit # CONFIG_USERMODE=y -# CONFIG_ISA is not set -# CONFIG_SBUS is not set -# CONFIG_PCI is not set +CONFIG_MMU=y +CONFIG_SWAP=y CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_CONFIG_LOG_BUF_SHIFT=14 # # Code maturity level options @@ -16,6 +16,8 @@ # # General Setup # +CONFIG_MODE_TT=y +CONFIG_MODE_SKAS=y CONFIG_NET=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -32,6 +34,8 @@ CONFIG_NEST_LEVEL=0 CONFIG_KERNEL_HALF_GIGS=1 # CONFIG_HIGHMEM is not set +CONFIG_PROC_MM=y +CONFIG_KERNEL_STACK_ORDER=2 # # Loadable module support @@ -56,13 +60,9 @@ CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_WATCHDOG is not set -# CONFIG_WATCHDOG_NOWAYOUT is not set -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_UML_WATCHDOG is not set CONFIG_UML_SOUND=y CONFIG_SOUND=y CONFIG_HOSTAUDIO=y -# CONFIG_TTY_LOG is not set # # Block Devices @@ -87,13 +87,14 @@ CONFIG_UML_NET_DAEMON=y CONFIG_UML_NET_MCAST=y # CONFIG_UML_NET_PCAP is not set +CONFIG_UML_NET_SLIRP=y CONFIG_DUMMY=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set CONFIG_TUN=y +# CONFIG_ETHERTAP is not set CONFIG_PPP=y # CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set # CONFIG_PPP_ASYNC is not set # CONFIG_PPP_SYNC_TTY is not set # CONFIG_PPP_DEFLATE is not set @@ -105,6 +106,10 @@ # CONFIG_SLIP_MODE_SLIP6 is not set # +# Networking support +# + +# # Networking options # CONFIG_PACKET=y @@ -113,6 +118,7 @@ # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set CONFIG_UNIX=y +# CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set @@ -122,19 +128,19 @@ # CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_XFRM_USER is not set # CONFIG_IPV6 is not set # -# SCTP Configuration (EXPERIMENTAL) +# SCTP Configuration (EXPERIMENTAL) # CONFIG_IPV6_SCTP__=y # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set # CONFIG_LLC is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_DEV_APPLETALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -151,6 +157,35 @@ # CONFIG_NET_SCHED is not set # +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# # File systems # CONFIG_QUOTA=y @@ -163,16 +198,14 @@ # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m -# CONFIG_UMSDOS_FS is not set CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set CONFIG_JFFS_FS=y @@ -186,13 +219,9 @@ # CONFIG_JOLIET is not set # CONFIG_ZISOFS is not set # CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set CONFIG_MINIX_FS=m # CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y CONFIG_DEVFS_FS=y @@ -200,17 +229,13 @@ # CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set # CONFIG_SYSV_FS is not set # CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # CONFIG_XFS_FS is not set -# CONFIG_XFS_RT is not set -# CONFIG_XFS_QUOTA is not set # # Network File Systems @@ -218,36 +243,18 @@ # CONFIG_CODA_FS is not set # CONFIG_INTERMEZZO_FS is not set # CONFIG_NFS_FS is not set -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_V4 is not set -# CONFIG_NFSD_TCP is not set -# CONFIG_SUNRPC is not set -# CONFIG_LOCKD is not set # CONFIG_EXPORTFS is not set # CONFIG_CIFS is not set # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set # CONFIG_AFS_FS is not set -# CONFIG_ZISOFS_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set CONFIG_NLS=y # @@ -293,6 +300,21 @@ # CONFIG_NLS_UTF8 is not set # +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set + +# # SCSI support # CONFIG_SCSI=y @@ -322,13 +344,6 @@ # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_LVM is not set # # Memory Technology Devices (MTD) @@ -337,8 +352,6 @@ # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_PARTITIONS is not set # CONFIG_MTD_CONCAT is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set # # User Modules And Translation Layers @@ -353,28 +366,18 @@ # # CONFIG_MTD_CFI is not set # CONFIG_MTD_JEDECPROBE is not set -# CONFIG_MTD_GEN_PROBE is not set -# CONFIG_MTD_CFI_INTELEXT is not set -# CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set # CONFIG_MTD_OBSOLETE_CHIPS is not set -# CONFIG_MTD_AMDSTD is not set -# CONFIG_MTD_SHARP is not set -# CONFIG_MTD_JEDEC is not set # # Mapping drivers for chip access # -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PCI is not set -# CONFIG_MTD_PCMCIA is not set # # Self-contained MTD device drivers # -# CONFIG_MTD_PMC551 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_MTDRAM is not set CONFIG_MTD_BLKMTD=m @@ -385,7 +388,6 @@ # CONFIG_MTD_DOC1000 is not set # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOCPROBE is not set # # NAND Flash Device Drivers @@ -396,7 +398,9 @@ # Kernel hacking # # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUGSYM=y +CONFIG_FRAME_POINTER=y CONFIG_PT_PROXY=y # CONFIG_GPROF is not set # CONFIG_GCOV is not set diff -Nru a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile --- a/arch/um/drivers/Makefile Sun Feb 9 21:13:32 2003 +++ b/arch/um/drivers/Makefile Sun Feb 9 21:13:32 2003 @@ -20,8 +20,6 @@ port-objs := port_kern.o port_user.o harddog-objs := harddog_kern.o harddog_user.o -export-objs := mconsole_kern.o - obj-y = obj-$(CONFIG_SSL) += ssl.o obj-$(CONFIG_UML_NET_SLIP) += slip.o diff -Nru a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c --- a/arch/um/drivers/chan_kern.c Sun Feb 9 21:13:37 2003 +++ b/arch/um/drivers/chan_kern.c Sun Feb 9 21:13:37 2003 @@ -75,15 +75,15 @@ } static struct chan_ops not_configged_ops = { - init: not_configged_init, - open: not_configged_open, - close: not_configged_close, - read: not_configged_read, - write: not_configged_write, - console_write: not_configged_console_write, - window_size: not_configged_window_size, - free: not_configged_free, - winch: 0, + .init = not_configged_init, + .open = not_configged_open, + .close = not_configged_close, + .read = not_configged_read, + .write = not_configged_write, + .console_write = not_configged_console_write, + .window_size = not_configged_window_size, + .free = not_configged_free, + .winch = 0, }; static void tty_receive_char(struct tty_struct *tty, char ch) @@ -395,15 +395,15 @@ chan = kmalloc(sizeof(*chan), GFP_KERNEL); if(chan == NULL) return(NULL); - *chan = ((struct chan) { list : LIST_HEAD_INIT(chan->list), - primary : 1, - input : 0, - output : 0, - opened : 0, - fd : -1, - pri : pri, - ops : ops, - data : data }); + *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list), + .primary = 1, + .input = 0, + .output = 0, + .opened = 0, + .fd = -1, + .pri = pri, + .ops = ops, + .data = data }); return(chan); } diff -Nru a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c --- a/arch/um/drivers/chan_user.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/drivers/chan_user.c Sun Feb 9 21:13:28 2003 @@ -159,9 +159,9 @@ return(err); } - data = ((struct winch_data) { pty_fd : fd, - pipe_fd : fds[1], - close_me : fds[0] } ); + data = ((struct winch_data) { .pty_fd = fd, + .pipe_fd = fds[1], + .close_me = fds[0] } ); pid = run_helper_thread(winch_thread, &data, 0, &stack, 0); if(pid < 0){ printk("fork of winch_thread failed - errno = %d\n", errno); diff -Nru a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c --- a/arch/um/drivers/daemon_kern.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/drivers/daemon_kern.c Sun Feb 9 21:13:28 2003 @@ -28,14 +28,14 @@ pri = dev->priv; dpri = (struct daemon_data *) pri->user; *dpri = ((struct daemon_data) - { sock_type : init->sock_type, - ctl_sock : init->ctl_sock, - ctl_addr : NULL, - data_addr : NULL, - local_addr : NULL, - fd : -1, - control : -1, - dev : dev }); + { .sock_type = init->sock_type, + .ctl_sock = init->ctl_sock, + .ctl_addr = NULL, + .data_addr = NULL, + .local_addr = NULL, + .fd = -1, + .control = -1, + .dev = dev }); printk("daemon backend (uml_switch version %d) - %s:%s", SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock); @@ -59,10 +59,10 @@ } static struct net_kern_info daemon_kern_info = { - init: daemon_init, - protocol: eth_protocol, - read: daemon_read, - write: daemon_write, + .init = daemon_init, + .protocol = eth_protocol, + .read = daemon_read, + .write = daemon_write, }; int daemon_setup(char *str, char **mac_out, void *data) @@ -71,8 +71,8 @@ char *remain; *init = ((struct daemon_init) - { sock_type : "unix", - ctl_sock : "/tmp/uml.ctl" }); + { .sock_type = "unix", + .ctl_sock = "/tmp/uml.ctl" }); remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock, NULL); @@ -84,13 +84,13 @@ } static struct transport daemon_transport = { - list : LIST_HEAD_INIT(daemon_transport.list), - name : "daemon", - setup : daemon_setup, - user : &daemon_user_info, - kern : &daemon_kern_info, - private_size : sizeof(struct daemon_data), - setup_size : sizeof(struct daemon_init), + .list = LIST_HEAD_INIT(daemon_transport.list), + .name = "daemon", + .setup = daemon_setup, + .user = &daemon_user_info, + .kern = &daemon_kern_info, + .private_size = sizeof(struct daemon_data), + .setup_size = sizeof(struct daemon_init), }; static int register_daemon(void) diff -Nru a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c --- a/arch/um/drivers/daemon_user.c Sun Feb 9 21:13:31 2003 +++ b/arch/um/drivers/daemon_user.c Sun Feb 9 21:13:31 2003 @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -24,8 +25,8 @@ #define SWITCH_MAGIC 0xfeedface struct request_v3 { - unsigned long magic; - int version; + uint32_t magic; + uint32_t version; enum request_type type; struct sockaddr_un sock; }; @@ -172,14 +173,14 @@ } struct net_user_info daemon_user_info = { - init: daemon_user_init, - open: daemon_open, - close: NULL, - remove: daemon_remove, - set_mtu: daemon_set_mtu, - add_address: NULL, - delete_address: NULL, - max_packet: MAX_PACKET - ETH_HEADER_OTHER + .init = daemon_user_init, + .open = daemon_open, + .close = NULL, + .remove = daemon_remove, + .set_mtu = daemon_set_mtu, + .add_address = NULL, + .delete_address = NULL, + .max_packet = MAX_PACKET - ETH_HEADER_OTHER }; /* diff -Nru a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c --- a/arch/um/drivers/fd.c Sun Feb 9 21:13:36 2003 +++ b/arch/um/drivers/fd.c Sun Feb 9 21:13:36 2003 @@ -36,8 +36,8 @@ return(NULL); } if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL); - *data = ((struct fd_chan) { fd : n, - raw : opts->raw }); + *data = ((struct fd_chan) { .fd = n, + .raw = opts->raw }); return(data); } @@ -72,16 +72,16 @@ } struct chan_ops fd_ops = { - type: "fd", - init: fd_init, - open: fd_open, - close: fd_close, - read: generic_read, - write: generic_write, - console_write: fd_console_write, - window_size: generic_window_size, - free: generic_free, - winch: 1, + .type = "fd", + .init = fd_init, + .open = fd_open, + .close = fd_close, + .read = generic_read, + .write = generic_write, + .console_write = fd_console_write, + .window_size = generic_window_size, + .free = generic_free, + .winch = 1, }; /* diff -Nru a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c --- a/arch/um/drivers/harddog_kern.c Sun Feb 9 21:13:33 2003 +++ b/arch/um/drivers/harddog_kern.c Sun Feb 9 21:13:33 2003 @@ -145,17 +145,17 @@ } static struct file_operations harddog_fops = { - owner: THIS_MODULE, - write: harddog_write, - ioctl: harddog_ioctl, - open: harddog_open, - release: harddog_release, + .owner = THIS_MODULE, + .write = harddog_write, + .ioctl = harddog_ioctl, + .open = harddog_open, + .release = harddog_release, }; static struct miscdevice harddog_miscdev = { - minor: WATCHDOG_MINOR, - name: "watchdog", - fops: &harddog_fops, + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &harddog_fops, }; static char banner[] __initdata = KERN_INFO "UML Watchdog Timer\n"; diff -Nru a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c --- a/arch/um/drivers/harddog_user.c Sun Feb 9 21:13:30 2003 +++ b/arch/um/drivers/harddog_user.c Sun Feb 9 21:13:30 2003 @@ -11,6 +11,8 @@ #include "helper.h" #include "mconsole.h" #include "os.h" +#include "choose-mode.h" +#include "mode.h" struct dog_data { int stdin; @@ -63,7 +65,8 @@ args = mconsole_args; } else { - sprintf(pid_buf, "%d", tracing_pid); + /* XXX The os_getpid() is not SMP correct */ + sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid())); args = pid_args; } diff -Nru a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c --- a/arch/um/drivers/hostaudio_kern.c Sun Feb 9 21:13:36 2003 +++ b/arch/um/drivers/hostaudio_kern.c Sun Feb 9 21:13:36 2003 @@ -195,23 +195,23 @@ /* kernel module operations */ static struct file_operations hostaudio_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - read: hostaudio_read, - write: hostaudio_write, - poll: hostaudio_poll, - ioctl: hostaudio_ioctl, - mmap: NULL, - open: hostaudio_open, - release: hostaudio_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = hostaudio_read, + .write = hostaudio_write, + .poll = hostaudio_poll, + .ioctl = hostaudio_ioctl, + .mmap = NULL, + .open = hostaudio_open, + .release = hostaudio_release, }; static struct file_operations hostmixer_fops = { - owner: THIS_MODULE, - llseek: no_llseek, - ioctl: hostmixer_ioctl_mixdev, - open: hostmixer_open_mixdev, - release: hostmixer_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .ioctl = hostmixer_ioctl_mixdev, + .open = hostmixer_open_mixdev, + .release = hostmixer_release, }; struct { diff -Nru a/arch/um/drivers/line.c b/arch/um/drivers/line.c --- a/arch/um/drivers/line.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/drivers/line.c Sun Feb 9 21:13:35 2003 @@ -35,7 +35,7 @@ line_interrupt(dev->driver->read_irq, dev, NULL); } -void buffer_data(struct line *line, const char *buf, int len) +static void buffer_data(struct line *line, const char *buf, int len) { int end; @@ -452,11 +452,19 @@ void lines_init(struct line *lines, int nlines) { + struct line *line; int i; for(i = 0; i < nlines; i++){ - INIT_LIST_HEAD(&lines[i].chan_list); - sema_init(&lines[i].sem, 1); + line = &lines[i]; + INIT_LIST_HEAD(&line->chan_list); + sema_init(&line->sem, 1); + if(line->init_str != NULL){ + line->init_str = uml_strdup(line->init_str); + if(line->init_str == NULL) + printk("lines_init - uml_strdup returned " + "NULL\n"); + } } } @@ -511,11 +519,11 @@ printk("register_winch_irq - kmalloc failed\n"); goto out; } - *winch = ((struct winch) { list : LIST_HEAD_INIT(winch->list), - fd : fd, - tty_fd : tty_fd, - pid : pid, - line : line }); + *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list), + .fd = fd, + .tty_fd = tty_fd, + .pid = pid, + .line = line }); list_add(&winch->list, &winch_handlers); if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, @@ -533,7 +541,8 @@ list_for_each(ele, &winch_handlers){ winch = list_entry(ele, struct winch, list); close(winch->fd); - if(winch->pid != -1) os_kill_process(winch->pid, 0); + if(winch->pid != -1) + os_kill_process(winch->pid, 1); } } diff -Nru a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c --- a/arch/um/drivers/mcast_kern.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/drivers/mcast_kern.c Sun Feb 9 21:13:28 2003 @@ -36,11 +36,11 @@ pri = dev->priv; dpri = (struct mcast_data *) pri->user; *dpri = ((struct mcast_data) - { addr : init->addr, - port : init->port, - ttl : init->ttl, - mcast_addr : NULL, - dev : dev }); + { .addr = init->addr, + .port = init->port, + .ttl = init->ttl, + .mcast_addr = NULL, + .dev = dev }); printk("mcast backend "); printk("multicast adddress: %s:%u, TTL:%u ", dpri->addr, dpri->port, dpri->ttl); @@ -64,10 +64,10 @@ } static struct net_kern_info mcast_kern_info = { - init: mcast_init, - protocol: eth_protocol, - read: mcast_read, - write: mcast_write, + .init = mcast_init, + .protocol = eth_protocol, + .read = mcast_read, + .write = mcast_write, }; int mcast_setup(char *str, char **mac_out, void *data) @@ -78,9 +78,9 @@ int n; *init = ((struct mcast_init) - { addr : "239.192.168.1", - port : 1102, - ttl : 1 }); + { .addr = "239.192.168.1", + .port = 1102, + .ttl = 1 }); remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str, NULL); @@ -116,13 +116,13 @@ } static struct transport mcast_transport = { - list : LIST_HEAD_INIT(mcast_transport.list), - name : "mcast", - setup : mcast_setup, - user : &mcast_user_info, - kern : &mcast_kern_info, - private_size : sizeof(struct mcast_data), - setup_size : sizeof(struct mcast_init), + .list = LIST_HEAD_INIT(mcast_transport.list), + .name = "mcast", + .setup = mcast_setup, + .user = &mcast_user_info, + .kern = &mcast_kern_info, + .private_size = sizeof(struct mcast_data), + .setup_size = sizeof(struct mcast_init), }; static int register_mcast(void) diff -Nru a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c --- a/arch/um/drivers/mcast_user.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/drivers/mcast_user.c Sun Feb 9 21:13:32 2003 @@ -153,14 +153,14 @@ } struct net_user_info mcast_user_info = { - init: mcast_user_init, - open: mcast_open, - close: mcast_close, - remove: NULL, - set_mtu: mcast_set_mtu, - add_address: NULL, - delete_address: NULL, - max_packet: MAX_PACKET - ETH_HEADER_OTHER + .init = mcast_user_init, + .open = mcast_open, + .close = mcast_close, + .remove = NULL, + .set_mtu = mcast_set_mtu, + .add_address = NULL, + .delete_address = NULL, + .max_packet = MAX_PACKET - ETH_HEADER_OTHER }; /* diff -Nru a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c --- a/arch/um/drivers/mconsole_kern.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/drivers/mconsole_kern.c Sun Feb 9 21:13:28 2003 @@ -36,8 +36,8 @@ static struct notifier_block reboot_notifier = { - notifier_call: do_unlink_socket, - priority: 0, + .notifier_call = do_unlink_socket, + .priority = 0, }; /* Safe without explicit locking for now. Tasklets provide their own @@ -418,9 +418,9 @@ } static struct notifier_block panic_exit_notifier = { - notifier_call : notify_panic, - next : NULL, - priority : 1 + .notifier_call = notify_panic, + .next = NULL, + .priority = 1 }; static int add_notifier(void) diff -Nru a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c --- a/arch/um/drivers/mmapper_kern.c Sun Feb 9 21:13:29 2003 +++ b/arch/um/drivers/mmapper_kern.c Sun Feb 9 21:13:29 2003 @@ -106,13 +106,13 @@ } static struct file_operations mmapper_fops = { - owner: THIS_MODULE, - read: mmapper_read, - write: mmapper_write, - ioctl: mmapper_ioctl, - mmap: mmapper_mmap, - open: mmapper_open, - release: mmapper_release, + .owner = THIS_MODULE, + .read = mmapper_read, + .write = mmapper_write, + .ioctl = mmapper_ioctl, + .mmap = mmapper_mmap, + .open = mmapper_open, + .release = mmapper_release, }; static int __init mmapper_init(void) diff -Nru a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c --- a/arch/um/drivers/net_kern.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/drivers/net_kern.c Sun Feb 9 21:13:32 2003 @@ -368,22 +368,22 @@ */ save = lp->user[0]; *lp = ((struct uml_net_private) - { list : LIST_HEAD_INIT(lp->list), - lock : SPIN_LOCK_UNLOCKED, - dev : dev, - fd : -1, - mac : { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0}, - have_mac : device->have_mac, - protocol : transport->kern->protocol, - open : transport->user->open, - close : transport->user->close, - remove : transport->user->remove, - read : transport->kern->read, - write : transport->kern->write, - add_address : transport->user->add_address, - delete_address : transport->user->delete_address, - set_mtu : transport->user->set_mtu, - user : { save } }); + { .list = LIST_HEAD_INIT(lp->list), + .lock = SPIN_LOCK_UNLOCKED, + .dev = dev, + .fd = -1, + .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0}, + .have_mac = device->have_mac, + .protocol = transport->kern->protocol, + .open = transport->user->open, + .close = transport->user->close, + .remove = transport->user->remove, + .read = transport->kern->read, + .write = transport->kern->write, + .add_address = transport->user->add_address, + .delete_address = transport->user->delete_address, + .set_mtu = transport->user->set_mtu, + .user = { save } }); init_timer(&lp->tl); lp->tl.function = uml_net_user_timer_expire; memset(&lp->stats, 0, sizeof(lp->stats)); @@ -542,9 +542,9 @@ printk("eth_init : alloc_bootmem failed\n"); return(1); } - *new = ((struct eth_init) { list : LIST_HEAD_INIT(new->list), - index : n, - init : str }); + *new = ((struct eth_init) { .list = LIST_HEAD_INIT(new->list), + .index = n, + .init = str }); list_add_tail(&new->list, ð_cmd_line); return(1); } @@ -618,9 +618,10 @@ } static struct mc_device net_mc = { - name: "eth", - config: net_config, - remove: net_remove, + .name = "eth", + .config = net_config, + .get_config = NULL, + .remove = net_remove, }; static int uml_inetaddr_event(struct notifier_block *this, unsigned long event, @@ -662,7 +663,7 @@ } struct notifier_block uml_inetaddr_notifier = { - notifier_call: uml_inetaddr_event, + .notifier_call = uml_inetaddr_event, }; static int uml_net_init(void) diff -Nru a/arch/um/drivers/null.c b/arch/um/drivers/null.c --- a/arch/um/drivers/null.c Sun Feb 9 21:13:29 2003 +++ b/arch/um/drivers/null.c Sun Feb 9 21:13:29 2003 @@ -32,16 +32,16 @@ } struct chan_ops null_ops = { - type: "null", - init: null_init, - open: null_open, - close: generic_close, - read: null_read, - write: generic_write, - console_write: generic_console_write, - window_size: generic_window_size, - free: null_free, - winch: 0, + .type = "null", + .init = null_init, + .open = null_open, + .close = generic_close, + .read = null_read, + .write = generic_write, + .console_write = generic_console_write, + .window_size = generic_window_size, + .free = null_free, + .winch = 0, }; /* diff -Nru a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c --- a/arch/um/drivers/pcap_kern.c Sun Feb 9 21:13:36 2003 +++ b/arch/um/drivers/pcap_kern.c Sun Feb 9 21:13:36 2003 @@ -27,12 +27,12 @@ pri = dev->priv; ppri = (struct pcap_data *) pri->user; *ppri = ((struct pcap_data) - { host_if : init->host_if, - promisc : init->promisc, - optimize : init->optimize, - filter : init->filter, - compiled : NULL, - pcap : NULL }); + { .host_if = init->host_if, + .promisc = init->promisc, + .optimize = init->optimize, + .filter = init->filter, + .compiled = NULL, + .pcap = NULL }); } static int pcap_read(int fd, struct sk_buff **skb, @@ -51,10 +51,10 @@ } static struct net_kern_info pcap_kern_info = { - init: pcap_init, - protocol: eth_protocol, - read: pcap_read, - write: pcap_write, + .init = pcap_init, + .protocol = eth_protocol, + .read = pcap_read, + .write = pcap_write, }; int pcap_setup(char *str, char **mac_out, void *data) @@ -64,10 +64,10 @@ int i; *init = ((struct pcap_init) - { host_if : "eth0", - promisc : 1, - optimize : 0, - filter : NULL }); + { .host_if = "eth0", + .promisc = 1, + .optimize = 0, + .filter = NULL }); remain = split_if_spec(str, &host_if, &init->filter, &options[0], &options[1], NULL); @@ -98,13 +98,13 @@ } static struct transport pcap_transport = { - list : LIST_HEAD_INIT(pcap_transport.list), - name : "pcap", - setup : pcap_setup, - user : &pcap_user_info, - kern : &pcap_kern_info, - private_size : sizeof(struct pcap_data), - setup_size : sizeof(struct pcap_init), + .list = LIST_HEAD_INIT(pcap_transport.list), + .name = "pcap", + .setup = pcap_setup, + .user = &pcap_user_info, + .kern = &pcap_kern_info, + .private_size = sizeof(struct pcap_data), + .setup_size = sizeof(struct pcap_init), }; static int register_pcap(void) diff -Nru a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c --- a/arch/um/drivers/pcap_user.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/drivers/pcap_user.c Sun Feb 9 21:13:35 2003 @@ -106,8 +106,8 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri) { struct pcap_handler_data hdata = ((struct pcap_handler_data) - { buffer : buffer, - len : len }); + { .buffer = buffer, + .len = len }); int n; n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata); @@ -121,14 +121,14 @@ } struct net_user_info pcap_user_info = { - init: pcap_user_init, - open: pcap_open, - close: NULL, - remove: pcap_remove, - set_mtu: NULL, - add_address: NULL, - delete_address: NULL, - max_packet: MAX_PACKET - ETH_HEADER_OTHER + .init = pcap_user_init, + .open = pcap_open, + .close = NULL, + .remove = pcap_remove, + .set_mtu = NULL, + .add_address = NULL, + .delete_address = NULL, + .max_packet = MAX_PACKET - ETH_HEADER_OTHER }; /* diff -Nru a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c --- a/arch/um/drivers/port_kern.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/drivers/port_kern.c Sun Feb 9 21:13:28 2003 @@ -31,7 +31,6 @@ struct port_dev { struct port_list *port; - int fd; int helper_pid; int telnetd_pid; }; @@ -50,12 +49,13 @@ struct connection *conn = data; int fd; - fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); + fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); if(fd < 0){ if(fd == -EAGAIN) return; - printk("os_rcv_fd returned %d\n", -fd); + printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", + -fd); os_close_file(conn->fd); } @@ -75,37 +75,42 @@ fd = port_connection(port->fd, socket, &pid); if(fd < 0){ if(fd != -EAGAIN) - printk("port_connection returned %d\n", -fd); + printk(KERN_ERR "port_accept : port_connection " + "returned %d\n", -fd); goto out; } conn = kmalloc(sizeof(*conn), GFP_ATOMIC); if(conn == NULL){ - printk("port_interrupt : failed to allocate connection\n"); + printk(KERN_ERR "port_accept : failed to allocate " + "connection\n"); goto out_close; } *conn = ((struct connection) - { list : LIST_HEAD_INIT(conn->list), - fd : fd, - socket : { socket[0], socket[1] }, - telnetd_pid : pid, - port : port }); + { .list = LIST_HEAD_INIT(conn->list), + .fd = fd, + .socket = { socket[0], socket[1] }, + .telnetd_pid = pid, + .port = port }); if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "telnetd", conn)){ - printk(KERN_ERR "Failed to get IRQ for telnetd\n"); + printk(KERN_ERR "port_accept : failed to get IRQ for " + "telnetd\n"); goto out_free; } list_add(&conn->list, &port->pending); - return(1); + ret = 1; + goto out; out_free: kfree(conn); out_close: os_close_file(fd); - if(pid != -1) os_kill_process(pid, 0); + if(pid != -1) + os_kill_process(pid, 1); out: return(ret); } @@ -173,14 +178,15 @@ } *port = ((struct port_list) - { list : LIST_HEAD_INIT(port->list), - has_connection : 0, - sem : __SEMAPHORE_INITIALIZER(port->sem, 0), - lock : SPIN_LOCK_UNLOCKED, - port : port_num, - fd : fd, - pending : LIST_HEAD_INIT(port->pending), - connections : LIST_HEAD_INIT(port->connections) }); + { .list = LIST_HEAD_INIT(port->list), + .has_connection = 0, + .sem = __SEMAPHORE_INITIALIZER(port->sem, + 0), + .lock = SPIN_LOCK_UNLOCKED, + .port = port_num, + .fd = fd, + .pending = LIST_HEAD_INIT(port->pending), + .connections = LIST_HEAD_INIT(port->connections) }); list_add(&port->list, &ports); found: @@ -190,9 +196,9 @@ goto out; } - *dev = ((struct port_dev) { port : port, - fd : -1, - helper_pid : -1 }); + *dev = ((struct port_dev) { .port = port, + .helper_pid = -1, + .telnetd_pid = -1 }); goto out; out_free: @@ -204,38 +210,16 @@ return(dev); } -void port_remove_dev(void *d) -{ - struct port_dev *dev = d; - - if(dev->helper_pid != -1) - os_kill_process(dev->helper_pid, 0); - if(dev->telnetd_pid != -1) - os_kill_process(dev->telnetd_pid, 0); - dev->helper_pid = -1; -} - -static void free_port(void) -{ - struct list_head *ele; - struct port_list *port; - - list_for_each(ele, &ports){ - port = list_entry(ele, struct port_list, list); - os_close_file(port->fd); - } -} - -__uml_exitcall(free_port); - int port_wait(void *data) { struct port_dev *dev = data; struct connection *conn; struct port_list *port = dev->port; + int fd; while(1){ - if(down_interruptible(&port->sem)) return(-ERESTARTSYS); + if(down_interruptible(&port->sem)) + return(-ERESTARTSYS); spin_lock(&port->lock); @@ -262,22 +246,47 @@ kfree(conn); } - dev->fd = conn->fd; + fd = conn->fd; dev->helper_pid = conn->helper_pid; dev->telnetd_pid = conn->telnetd_pid; kfree(conn); - return(dev->fd); + return(fd); +} + +void port_remove_dev(void *d) +{ + struct port_dev *dev = d; + + if(dev->helper_pid != -1) + os_kill_process(dev->helper_pid, 0); + if(dev->telnetd_pid != -1) + os_kill_process(dev->telnetd_pid, 1); + dev->helper_pid = -1; + dev->telnetd_pid = -1; } void port_kern_free(void *d) { struct port_dev *dev = d; - if(dev->helper_pid != -1) os_kill_process(dev->helper_pid, 0); - if(dev->telnetd_pid != -1) os_kill_process(dev->telnetd_pid, 0); + port_remove_dev(dev); kfree(dev); } + +static void free_port(void) +{ + struct list_head *ele; + struct port_list *port; + + list_for_each(ele, &ports){ + port = list_entry(ele, struct port_list, list); + free_irq_by_fd(port->fd); + os_close_file(port->fd); + } +} + +__uml_exitcall(free_port); /* * Overrides for Emacs so that we follow Linus's tabbing style. diff -Nru a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c --- a/arch/um/drivers/port_user.c Sun Feb 9 21:13:33 2003 +++ b/arch/um/drivers/port_user.c Sun Feb 9 21:13:33 2003 @@ -47,14 +47,28 @@ return(NULL); } - if((kern_data = port_data(port)) == NULL) return(NULL); + if((kern_data = port_data(port)) == NULL) + return(NULL); - if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL); - *data = ((struct port_chan) { raw : opts->raw, - kernel_data : kern_data }); + if((data = um_kmalloc(sizeof(*data))) == NULL) + goto err; + + *data = ((struct port_chan) { .raw = opts->raw, + .kernel_data = kern_data }); sprintf(data->dev, "%d", port); - + return(data); + err: + port_kern_free(kern_data); + return(NULL); +} + +void port_free(void *d) +{ + struct port_chan *data = d; + + port_kern_free(data->kernel_data); + kfree(data); } int port_open(int input, int output, int primary, void *d, char **dev_out) @@ -86,25 +100,17 @@ return(generic_console_write(fd, buf, n, &data->tt)); } -void port_free(void *d) -{ - struct port_chan *data = d; - - port_kern_free(data->kernel_data); - kfree(data); -} - struct chan_ops port_ops = { - type: "port", - init: port_init, - open: port_open, - close: port_close, - read: generic_read, - write: generic_write, - console_write: port_console_write, - window_size: generic_window_size, - free: port_free, - winch: 1, + .type = "port", + .init = port_init, + .open = port_open, + .close = port_close, + .read = generic_read, + .write = generic_write, + .console_write = port_console_write, + .window_size = generic_window_size, + .free = port_free, + .winch = 1, }; int port_listen_fd(int port) @@ -113,7 +119,8 @@ int fd, err; fd = socket(PF_INET, SOCK_STREAM, 0); - if(fd == -1) return(-errno); + if(fd == -1) + return(-errno); addr.sin_family = AF_INET; addr.sin_port = htons(port); @@ -163,14 +170,16 @@ return(-errno); err = os_pipe(socket, 0, 0); - if(err) goto out_close; + if(err) + goto out_close; data = ((struct port_pre_exec_data) - { sock_fd : new, - pipe_fd : socket[1] }); + { .sock_fd = new, + .pipe_fd = socket[1] }); err = run_helper(port_pre_exec, &data, argv, NULL); - if(err < 0) goto out_shutdown; + if(err < 0) + goto out_shutdown; *pid_out = err; return(new); diff -Nru a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c --- a/arch/um/drivers/pty.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/drivers/pty.c Sun Feb 9 21:13:35 2003 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -27,9 +27,9 @@ struct pty_chan *data; if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL); - *data = ((struct pty_chan) { announce : opts->announce, - dev : device, - raw : opts->raw }); + *data = ((struct pty_chan) { .announce = opts->announce, + .dev = device, + .raw = opts->raw }); return(data); } @@ -86,34 +86,15 @@ return(-1); } -struct grantpt_info { - int fd; - int res; - int err; -}; - -static void grantpt_cb(void *arg) -{ - struct grantpt_info *info = arg; - - info->res = grantpt(info->fd); - info->err = errno; -} - int pty_open(int input, int output, int primary, void *d, char **dev_out) { struct pty_chan *data = d; int fd; char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx"; - struct grantpt_info info; fd = getmaster(dev); if(fd < 0) return(-errno); - info.fd = fd; - initial_thread_cb(grantpt_cb, &info); - unlockpt(fd); - if(data->raw) raw(fd, 0); if(data->announce) (*data->announce)(dev, data->dev); @@ -130,29 +111,29 @@ } struct chan_ops pty_ops = { - type: "pty", - init: pty_chan_init, - open: pty_open, - close: generic_close, - read: generic_read, - write: generic_write, - console_write: pty_console_write, - window_size: generic_window_size, - free: generic_free, - winch: 0, + .type = "pty", + .init = pty_chan_init, + .open = pty_open, + .close = generic_close, + .read = generic_read, + .write = generic_write, + .console_write = pty_console_write, + .window_size = generic_window_size, + .free = generic_free, + .winch = 0, }; struct chan_ops pts_ops = { - type: "pts", - init: pty_chan_init, - open: pts_open, - close: generic_close, - read: generic_read, - write: generic_write, - console_write: pty_console_write, - window_size: generic_window_size, - free: generic_free, - winch: 0, + .type = "pts", + .init = pty_chan_init, + .open = pts_open, + .close = generic_close, + .read = generic_read, + .write = generic_write, + .console_write = pty_console_write, + .window_size = generic_window_size, + .free = generic_free, + .winch = 0, }; /* diff -Nru a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c --- a/arch/um/drivers/slip_kern.c Sun Feb 9 21:13:31 2003 +++ b/arch/um/drivers/slip_kern.c Sun Feb 9 21:13:31 2003 @@ -22,15 +22,15 @@ private = dev->priv; spri = (struct slip_data *) private->user; *spri = ((struct slip_data) - { name : { '\0' }, - addr: NULL, - gate_addr : init->gate_addr, - slave : -1, - ibuf : { '\0' }, - obuf : { '\0' }, - pos : 0, - esc : 0, - dev : dev }); + { .name = { '\0' }, + .addr = NULL, + .gate_addr = init->gate_addr, + .slave = -1, + .ibuf = { '\0' }, + .obuf = { '\0' }, + .pos = 0, + .esc = 0, + .dev = dev }); dev->init = NULL; dev->hard_header_len = 0; @@ -61,10 +61,10 @@ } struct net_kern_info slip_kern_info = { - init: slip_init, - protocol: slip_protocol, - read: slip_read, - write: slip_write, + .init = slip_init, + .protocol = slip_protocol, + .read = slip_read, + .write = slip_write, }; static int slip_setup(char *str, char **mac_out, void *data) @@ -72,7 +72,7 @@ struct slip_init *init = data; *init = ((struct slip_init) - { gate_addr : NULL }); + { .gate_addr = NULL }); if(str[0] != '\0') init->gate_addr = str; @@ -80,13 +80,13 @@ } static struct transport slip_transport = { - list : LIST_HEAD_INIT(slip_transport.list), - name : "slip", - setup : slip_setup, - user : &slip_user_info, - kern : &slip_kern_info, - private_size : sizeof(struct slip_data), - setup_size : sizeof(struct slip_init), + .list = LIST_HEAD_INIT(slip_transport.list), + .name = "slip", + .setup = slip_setup, + .user = &slip_user_info, + .kern = &slip_kern_info, + .private_size = sizeof(struct slip_data), + .setup_size = sizeof(struct slip_init), }; static int register_slip(void) diff -Nru a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c --- a/arch/um/drivers/slip_user.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/drivers/slip_user.c Sun Feb 9 21:13:35 2003 @@ -257,14 +257,14 @@ } struct net_user_info slip_user_info = { - init: slip_user_init, - open: slip_open, - close: slip_close, - remove: NULL, - set_mtu: slip_set_mtu, - add_address: slip_add_addr, - delete_address: slip_del_addr, - max_packet: BUF_SIZE + .init = slip_user_init, + .open = slip_open, + .close = slip_close, + .remove = NULL, + .set_mtu = slip_set_mtu, + .add_address = slip_add_addr, + .delete_address = slip_del_addr, + .max_packet = BUF_SIZE }; /* diff -Nru a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c --- a/arch/um/drivers/slirp_kern.c Sun Feb 9 21:13:36 2003 +++ b/arch/um/drivers/slirp_kern.c Sun Feb 9 21:13:36 2003 @@ -22,14 +22,14 @@ private = dev->priv; spri = (struct slirp_data *) private->user; *spri = ((struct slirp_data) - { argw : init->argw, - pid : -1, - slave : -1, - ibuf : { '\0' }, - obuf : { '\0' }, - pos : 0, - esc : 0, - dev : dev }); + { .argw = init->argw, + .pid = -1, + .slave = -1, + .ibuf = { '\0' }, + .obuf = { '\0' }, + .pos = 0, + .esc = 0, + .dev = dev }); dev->init = NULL; dev->hard_header_len = 0; @@ -64,10 +64,10 @@ } struct net_kern_info slirp_kern_info = { - init: slirp_init, - protocol: slirp_protocol, - read: slirp_read, - write: slirp_write, + .init = slirp_init, + .protocol = slirp_protocol, + .read = slirp_read, + .write = slirp_write, }; static int slirp_setup(char *str, char **mac_out, void *data) @@ -103,13 +103,13 @@ } static struct transport slirp_transport = { - list : LIST_HEAD_INIT(slirp_transport.list), - name : "slirp", - setup : slirp_setup, - user : &slirp_user_info, - kern : &slirp_kern_info, - private_size : sizeof(struct slirp_data), - setup_size : sizeof(struct slirp_init), + .list = LIST_HEAD_INIT(slirp_transport.list), + .name = "slirp", + .setup = slirp_setup, + .user = &slirp_user_info, + .kern = &slirp_kern_info, + .private_size = sizeof(struct slirp_data), + .setup_size = sizeof(struct slirp_init), }; static int register_slirp(void) diff -Nru a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c --- a/arch/um/drivers/slirp_user.c Sun Feb 9 21:13:29 2003 +++ b/arch/um/drivers/slirp_user.c Sun Feb 9 21:13:29 2003 @@ -180,14 +180,14 @@ } struct net_user_info slirp_user_info = { - init: slirp_user_init, - open: slirp_open, - close: slirp_close, - remove: NULL, - set_mtu: slirp_set_mtu, - add_address: NULL, - delete_address: NULL, - max_packet: BUF_SIZE + .init = slirp_user_init, + .open = slirp_open, + .close = slirp_close, + .remove = NULL, + .set_mtu = slirp_set_mtu, + .add_address = NULL, + .delete_address = NULL, + .max_packet = BUF_SIZE }; /* diff -Nru a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c --- a/arch/um/drivers/ssl.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/drivers/ssl.c Sun Feb 9 21:13:32 2003 @@ -41,11 +41,11 @@ } static struct chan_opts opts = { - announce: ssl_announce, - xterm_title: "Serial Line #%d", - raw: 1, - tramp_stack : 0, - in_kernel : 1, + .announce = ssl_announce, + .xterm_title = "Serial Line #%d", + .raw = 1, + .tramp_stack = 0, + .in_kernel = 1, }; static int ssl_config(char *str); @@ -53,23 +53,23 @@ static int ssl_remove(char *str); static struct line_driver driver = { - name : "UML serial line", - devfs_name : "tts/%d", - major : TTYAUX_MAJOR, - minor_start : 64, - type : TTY_DRIVER_TYPE_SERIAL, - subtype : 0, - read_irq : SSL_IRQ, - read_irq_name : "ssl", - write_irq : SSL_WRITE_IRQ, - write_irq_name : "ssl-write", - symlink_from : "serial", - symlink_to : "tts", - mc : { - name : "ssl", - config : ssl_config, - get_config : ssl_get_config, - remove : ssl_remove, + .name = "UML serial line", + .devfs_name = "tts/%d", + .major = TTYAUX_MAJOR, + .minor_start = 64, + .type = TTY_DRIVER_TYPE_SERIAL, + .subtype = 0, + .read_irq = SSL_IRQ, + .read_irq_name = "ssl", + .write_irq = SSL_WRITE_IRQ, + .write_irq_name = "ssl-write", + .symlink_from = "serial", + .symlink_to = "tts", + .mc = { + .name = "ssl", + .config = ssl_config, + .get_config = ssl_get_config, + .remove = ssl_remove, }, }; @@ -191,21 +191,21 @@ } static struct tty_driver ssl_driver = { - refcount : &ssl_refcount, - open : ssl_open, - close : ssl_close, - write : ssl_write, - put_char : ssl_put_char, - flush_chars : ssl_flush_chars, - chars_in_buffer : ssl_chars_in_buffer, - flush_buffer : ssl_flush_buffer, - ioctl : ssl_ioctl, - throttle : ssl_throttle, - unthrottle : ssl_unthrottle, - set_termios : ssl_set_termios, - stop : ssl_stop, - start : ssl_start, - hangup : ssl_hangup + .refcount = &ssl_refcount, + .open = ssl_open, + .close = ssl_close, + .write = ssl_write, + .put_char = ssl_put_char, + .flush_chars = ssl_flush_chars, + .chars_in_buffer = ssl_chars_in_buffer, + .flush_buffer = ssl_flush_buffer, + .ioctl = ssl_ioctl, + .throttle = ssl_throttle, + .unthrottle = ssl_unthrottle, + .set_termios = ssl_set_termios, + .stop = ssl_stop, + .start = ssl_start, + .hangup = ssl_hangup }; /* Changed by ssl_init and referenced by ssl_exit, which are both serialized diff -Nru a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c --- a/arch/um/drivers/stdio_console.c Sun Feb 9 21:13:30 2003 +++ b/arch/um/drivers/stdio_console.c Sun Feb 9 21:13:30 2003 @@ -42,28 +42,28 @@ static int console_refcount = 0; static struct chan_ops init_console_ops = { - type: "you shouldn't see this", - init : NULL, - open : NULL, - close : NULL, - read : NULL, - write : NULL, - console_write : generic_write, - window_size : NULL, - free : NULL, - winch: 0, + .type = "you shouldn't see this", + .init = NULL, + .open = NULL, + .close = NULL, + .read = NULL, + .write = NULL, + .console_write = generic_write, + .window_size = NULL, + .free = NULL, + .winch = 0, }; static struct chan init_console_chan = { - list : { }, - primary : 1, - input : 0, - output : 1, - opened : 1, - fd : 1, - pri : INIT_STATIC, - ops : &init_console_ops, - data : NULL + .list = { }, + .primary = 1, + .input = 0, + .output = 1, + .opened = 1, + .fd = 1, + .pri = INIT_STATIC, + .ops = &init_console_ops, + .data = NULL }; void stdio_announce(char *dev_name, int dev) @@ -73,11 +73,11 @@ } static struct chan_opts opts = { - announce: stdio_announce, - xterm_title: "Virtual Console #%d", - raw: 1, - tramp_stack : 0, - in_kernel : 1, + .announce = stdio_announce, + .xterm_title = "Virtual Console #%d", + .raw = 1, + .tramp_stack = 0, + .in_kernel = 1, }; static int con_config(char *str); @@ -85,23 +85,23 @@ static int con_remove(char *str); static struct line_driver driver = { - name : "UML console", - devfs_name : "vc/%d", - major : TTY_MAJOR, - minor_start : 0, - type : TTY_DRIVER_TYPE_CONSOLE, - subtype : SYSTEM_TYPE_CONSOLE, - read_irq : CONSOLE_IRQ, - read_irq_name : "console", - write_irq : CONSOLE_WRITE_IRQ, - write_irq_name : "console-write", - symlink_from : "ttys", - symlink_to : "vc", - mc : { - name : "con", - config : con_config, - get_config : con_get_config, - remove : con_remove, + .name = "UML console", + .devfs_name = "vc/%d", + .major = TTY_MAJOR, + .minor_start = 0, + .type = TTY_DRIVER_TYPE_CONSOLE, + .subtype = SYSTEM_TYPE_CONSOLE, + .read_irq = CONSOLE_IRQ, + .read_irq_name = "console", + .write_irq = CONSOLE_WRITE_IRQ, + .write_irq_name = "console-write", + .symlink_from = "ttys", + .symlink_to = "vc", + .mc = { + .name = "con", + .config = con_config, + .get_config = con_get_config, + .remove = con_remove, }, }; @@ -192,12 +192,12 @@ } static struct tty_driver console_driver = { - refcount : &console_refcount, - open : con_open, - close : con_close, - write : con_write, - chars_in_buffer : chars_in_buffer, - set_termios : set_termios + .refcount = &console_refcount, + .open = con_open, + .close = con_close, + .write = con_write, + .chars_in_buffer = chars_in_buffer, + .set_termios = set_termios }; static kdev_t console_device(struct console *c) diff -Nru a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c --- a/arch/um/drivers/tty.c Sun Feb 9 21:13:31 2003 +++ b/arch/um/drivers/tty.c Sun Feb 9 21:13:31 2003 @@ -32,8 +32,8 @@ if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL); - *data = ((struct tty_chan) { dev : str, - raw : opts->raw }); + *data = ((struct tty_chan) { .dev = str, + .raw = opts->raw }); return(data); } @@ -62,16 +62,16 @@ } struct chan_ops tty_ops = { - type: "tty", - init: tty_chan_init, - open: tty_open, - close: generic_close, - read: generic_read, - write: generic_write, - console_write: tty_console_write, - window_size: generic_window_size, - free: generic_free, - winch: 0, + .type = "tty", + .init = tty_chan_init, + .open = tty_open, + .close = generic_close, + .read = generic_read, + .write = generic_write, + .console_write = tty_console_write, + .window_size = generic_window_size, + .free = generic_free, + .winch = 0, }; /* diff -Nru a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c --- a/arch/um/drivers/ubd_kern.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/drivers/ubd_kern.c Sun Feb 9 21:13:32 2003 @@ -77,9 +77,11 @@ static struct gendisk *fake_gendisk[MAX_DEV]; #ifdef CONFIG_BLK_DEV_UBD_SYNC -#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0 }) +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \ + .cl = 1 }) #else -#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0 }) +#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \ + .cl = 1 }) #endif /* Not protected - changed only in ubd_setup_common and then only to @@ -177,6 +179,8 @@ if(proc_ide_root == NULL) make_proc_ide(); dir = proc_mkdir(dev_name, proc_ide); + if(!dir) return; + ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir); if(!ent) return; ent->nlink = 1; @@ -405,7 +409,8 @@ void kill_io_thread(void) { - if(io_pid != -1) kill(io_pid, SIGKILL); + if(io_pid != -1) + os_kill_process(io_pid, 1); } __uml_exitcall(kill_io_thread); @@ -892,9 +897,9 @@ struct ubd *dev = inode->i_bdev->bd_disk->private_data; int err; struct hd_driveid ubd_id = { - .cyls = 0, - .heads = 128, - .sectors = 32, + .cyls = 0, + .heads = 128, + .sectors = 32, }; switch (cmd) { diff -Nru a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c --- a/arch/um/drivers/xterm.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/drivers/xterm.c Sun Feb 9 21:13:28 2003 @@ -37,13 +37,13 @@ struct xterm_chan *data; if((data = malloc(sizeof(*data))) == NULL) return(NULL); - *data = ((struct xterm_chan) { pid : -1, - helper_pid : -1, - device : device, - title : opts->xterm_title, - raw : opts->raw, - stack : opts->tramp_stack, - direct_rcv : !opts->in_kernel } ); + *data = ((struct xterm_chan) { .pid = -1, + .helper_pid = -1, + .device = device, + .title = opts->xterm_title, + .raw = opts->raw, + .stack = opts->tramp_stack, + .direct_rcv = !opts->in_kernel } ); return(data); } @@ -137,7 +137,7 @@ } if(new < 0){ printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new); - return(new); + goto out; } tcgetattr(new, &data->tt); @@ -145,6 +145,8 @@ data->pid = pid; *dev_out = NULL; + out: + unlink(file); return(new); } @@ -152,9 +154,11 @@ { struct xterm_chan *data = d; - if(data->pid != -1) kill(data->pid, SIGKILL); + if(data->pid != -1) + os_kill_process(data->pid, 1); data->pid = -1; - if(data->helper_pid != -1) kill(data->helper_pid, SIGKILL); + if(data->helper_pid != -1) + os_kill_process(data->helper_pid, 0); data->helper_pid = -1; close(fd); } @@ -172,16 +176,16 @@ } struct chan_ops xterm_ops = { - type: "xterm", - init: xterm_init, - open: xterm_open, - close: xterm_close, - read: generic_read, - write: generic_write, - console_write: xterm_console_write, - window_size: generic_window_size, - free: xterm_free, - winch: 1, + .type = "xterm", + .init = xterm_init, + .open = xterm_open, + .close = xterm_close, + .read = generic_read, + .write = generic_write, + .console_write = xterm_console_write, + .window_size = generic_window_size, + .free = xterm_free, + .winch = 1, }; /* diff -Nru a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c --- a/arch/um/drivers/xterm_kern.c Sun Feb 9 21:13:34 2003 +++ b/arch/um/drivers/xterm_kern.c Sun Feb 9 21:13:34 2003 @@ -39,21 +39,21 @@ data = kmalloc(sizeof(*data), GFP_KERNEL); if(data == NULL){ - printk(KERN_ERR "xterm_fd - failed to allocate semaphore\n"); + printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n"); return(-ENOMEM); } *data = ((struct xterm_wait) - { sem : __SEMAPHORE_INITIALIZER(data->sem, 0), - fd : socket, - pid : -1, - new_fd : -1 }); + { .sem = __SEMAPHORE_INITIALIZER(data->sem, 0), + .fd = socket, + .pid = -1, + .new_fd = -1 }); err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "xterm", data); if(err){ - printk(KERN_ERR "Failed to get IRQ for xterm, err = %d\n", - err); + printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " + "err = %d\n", err); return(err); } down(&data->sem); diff -Nru a/arch/um/dyn.lds.S b/arch/um/dyn.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/um/dyn.lds.S Sun Feb 9 21:13:38 2003 @@ -0,0 +1,167 @@ +OUTPUT_FORMAT(ELF_FORMAT) +OUTPUT_ARCH(ELF_ARCH) +ENTRY(_start) +jiffies = jiffies_64; + +SEARCH_DIR("/usr/local/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + . = START + SIZEOF_HEADERS; + .interp : { *(.interp) } + . = ALIGN(4096); + __binary_start = .; + . = ALIGN(4096); /* Init code and data */ + _stext = .; + __init_begin = .; + .text.init : { *(.text.init) } + + . = ALIGN(4096); + + /* Read-only sections, merged into text segment: */ + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { + KEEP (*(.init)) + } =0x90909090 + .plt : { *(.plt) } + .text : { + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0x90909090 + .fini : { + KEEP (*(.fini)) + } =0x90909090 + + .kstrtab : { *(.kstrtab) } + + #include "asm/common.lds.S" + + .data.init : { *(.data.init) } + + /* Ensure the __preinit_array_start label is properly aligned. We + could instead move the label definition inside the section, but + the linker would then create the section even if it turns out to + be empty, which isn't pretty. */ + . = ALIGN(32 / 8); + .preinit_array : { *(.preinit_array) } + .init_array : { *(.init_array) } + .fini_array : { *(.fini_array) } + .data : { + . = ALIGN(KERNEL_STACK_SIZE); /* init_task */ + *(.data.init_task) + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + .dynamic : { *(.dynamic) } + .ctors : { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : { + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .got : { *(.got.plt) *(.got) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .bss : { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(32 / 8); + . = ALIGN(32 / 8); + } + _end = .; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff -Nru a/arch/um/include/choose-mode.h b/arch/um/include/choose-mode.h --- a/arch/um/include/choose-mode.h Sun Feb 9 21:13:34 2003 +++ b/arch/um/include/choose-mode.h Sun Feb 9 21:13:34 2003 @@ -8,13 +8,13 @@ #include "uml-config.h" -#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS) +#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS) #define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas)) -#elif defined(CONFIG_MODE_SKAS) +#elif defined(UML_CONFIG_MODE_SKAS) #define CHOOSE_MODE(tt, skas) (skas) -#elif defined(CONFIG_MODE_TT) +#elif defined(UML_CONFIG_MODE_TT) #define CHOOSE_MODE(tt, skas) (tt) #endif diff -Nru a/arch/um/include/frame.h b/arch/um/include/frame.h --- a/arch/um/include/frame.h Sun Feb 9 21:13:30 2003 +++ b/arch/um/include/frame.h Sun Feb 9 21:13:30 2003 @@ -15,12 +15,12 @@ int sr_index; int sr_relative; int sp_index; + struct arch_frame_data arch; }; struct sc_frame { struct frame_common common; int sc_index; - struct arch_frame_data arch; }; extern struct sc_frame signal_frame_sc; @@ -31,6 +31,8 @@ struct frame_common common; int sip_index; int si_index; + int ucp_index; + int uc_index; }; extern struct si_frame signal_frame_si; diff -Nru a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h --- a/arch/um/include/irq_user.h Sun Feb 9 21:13:33 2003 +++ b/arch/um/include/irq_user.h Sun Feb 9 21:13:33 2003 @@ -8,7 +8,7 @@ enum { IRQ_READ, IRQ_WRITE }; -extern void sigio_handler(int sig, struct uml_pt_regs *regs); +extern void sigio_handler(int sig, union uml_pt_regs *regs); extern int activate_fd(int irq, int fd, int type, void *dev_id); extern void free_irq_by_irq_and_dev(int irq, void *dev_id); extern void free_irq_by_fd(int fd); diff -Nru a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h --- a/arch/um/include/kern_util.h Sun Feb 9 21:13:31 2003 +++ b/arch/um/include/kern_util.h Sun Feb 9 21:13:31 2003 @@ -47,7 +47,7 @@ extern void add_input_request(int op, void (*proc)(int), void *arg); extern int sys_execve(char *file, char **argv, char **env); extern char *current_cmd(void); -extern void timer_handler(int sig, struct uml_pt_regs *regs); +extern void timer_handler(int sig, union uml_pt_regs *regs); extern int set_signals(int enable); extern void force_sigbus(void); extern int pid_to_processor_id(int pid); @@ -64,7 +64,7 @@ extern void syscall_trace(void); extern int hz(void); extern void idle_timer(void); -extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs); +extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs); extern int external_pid(void *t); extern int pid_to_processor_id(int pid); extern void boot_timer_handler(int sig); @@ -77,10 +77,10 @@ extern int init_parent_proxy(int pid); extern int singlestepping(void *t); extern void check_stack_overflow(void *ptr); -extern void relay_signal(int sig, struct uml_pt_regs *regs); +extern void relay_signal(int sig, union uml_pt_regs *regs); extern void not_implemented(void); extern int user_context(unsigned long sp); -extern void timer_irq(struct uml_pt_regs *regs); +extern void timer_irq(union uml_pt_regs *regs); extern void unprotect_stack(unsigned long stack); extern void do_uml_exitcalls(void); extern int attach_debugger(int idle_pid, int pid, int stop); @@ -101,7 +101,7 @@ extern int clear_user_proc(void *buf, int size); extern int copy_to_user_proc(void *to, void *from, int size); extern int copy_from_user_proc(void *to, void *from, int size); -extern void bus_handler(int sig, struct uml_pt_regs *regs); +extern void bus_handler(int sig, union uml_pt_regs *regs); extern long execute_syscall(void *r); extern int smp_sigio_handler(void); extern void *get_current(void); diff -Nru a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h --- a/arch/um/include/mconsole.h Sun Feb 9 21:13:31 2003 +++ b/arch/um/include/mconsole.h Sun Feb 9 21:13:31 2003 @@ -7,30 +7,35 @@ #ifndef __MCONSOLE_H__ #define __MCONSOLE_H__ +#ifndef __KERNEL__ +#include +#define u32 uint32_t +#endif + #define MCONSOLE_MAGIC (0xcafebabe) #define MCONSOLE_MAX_DATA (512) #define MCONSOLE_VERSION 2 struct mconsole_request { - unsigned long magic; - int version; - int len; + u32 magic; + u32 version; + u32 len; char data[MCONSOLE_MAX_DATA]; }; struct mconsole_reply { - int err; - int more; - int len; + u32 err; + u32 more; + u32 len; char data[MCONSOLE_MAX_DATA]; }; struct mconsole_notify { - unsigned long magic; - int version; + u32 magic; + u32 version; enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG, MCONSOLE_USER_NOTIFY } type; - int len; + u32 len; char data[MCONSOLE_MAX_DATA]; }; diff -Nru a/arch/um/include/mode.h b/arch/um/include/mode.h --- a/arch/um/include/mode.h Sun Feb 9 21:13:33 2003 +++ b/arch/um/include/mode.h Sun Feb 9 21:13:33 2003 @@ -8,11 +8,11 @@ #include "uml-config.h" -#ifdef CONFIG_MODE_TT +#ifdef UML_CONFIG_MODE_TT #include "../kernel/tt/include/mode.h" #endif -#ifdef CONFIG_MODE_SKAS +#ifdef UML_CONFIG_MODE_SKAS #include "../kernel/skas/include/mode.h" #endif diff -Nru a/arch/um/include/os.h b/arch/um/include/os.h --- a/arch/um/include/os.h Sun Feb 9 21:13:29 2003 +++ b/arch/um/include/os.h Sun Feb 9 21:13:29 2003 @@ -25,9 +25,11 @@ unsigned int t : 1; /* O_TRUNC */ unsigned int a : 1; /* O_APPEND */ unsigned int e : 1; /* O_EXCL */ + unsigned int cl : 1; /* FD_CLOEXEC */ }; -#define OPENFLAGS() ((struct openflags) { r : 0, w : 0, c : 0, s : 0 }) +#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \ + .t = 0, .a = 0, .e = 0, .cl = 0 }) static inline struct openflags of_read(struct openflags flags) { @@ -83,9 +85,16 @@ return(flags); } +static inline struct openflags of_cloexec(struct openflags flags) +{ + flags.cl = 1; + return(flags); +} + extern int os_seek_file(int fd, __u64 offset); extern int os_open_file(char *file, struct openflags flags, int mode); -extern int os_read_file(int fd, char *buf, int len); +extern int os_read_file(int fd, void *buf, int len); +extern int os_write_file(int fd, void *buf, int count); extern int os_file_size(char *file, long long *size_out); extern int os_pipe(int *fd, int stream, int close_on_exec); extern int os_set_fd_async(int fd, int owner); @@ -98,7 +107,6 @@ extern int os_connect_socket(char *name); extern int os_file_type(char *file); extern int os_file_mode(char *file, struct openflags *mode_out); -extern int os_write_file(int fd, char *buf, int count); extern unsigned long os_process_pc(int pid); extern int os_process_parent(int pid); diff -Nru a/arch/um/include/signal_kern.h b/arch/um/include/signal_kern.h --- a/arch/um/include/signal_kern.h Sun Feb 9 21:13:35 2003 +++ b/arch/um/include/signal_kern.h Sun Feb 9 21:13:35 2003 @@ -1,15 +1,11 @@ /* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ #ifndef __SIGNAL_KERN_H__ #define __SIGNAL_KERN_H__ -#include "sysdep/ptrace.h" - -extern void signal_deliverer(int sig); -extern int probe_stack(unsigned long sp, int delta); extern int have_signals(void *t); #endif diff -Nru a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/um/include/skas_ptrace.h Sun Feb 9 21:13:35 2003 @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __SKAS_PTRACE_H +#define __SKAS_PTRACE_H + +struct ptrace_faultinfo { + int is_write; + unsigned long addr; +}; + +struct ptrace_ldt { + int func; + void *ptr; + unsigned long bytecount; +}; + +#define PTRACE_FAULTINFO 52 +#define PTRACE_SIGPENDING 53 +#define PTRACE_LDT 54 +#define PTRACE_SWITCH_MM 55 + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -Nru a/arch/um/include/sysdep-i386/frame.h b/arch/um/include/sysdep-i386/frame.h --- a/arch/um/include/sysdep-i386/frame.h Sun Feb 9 21:13:29 2003 +++ b/arch/um/include/sysdep-i386/frame.h Sun Feb 9 21:13:29 2003 @@ -7,7 +7,8 @@ #define __FRAME_I386_H struct arch_frame_data_raw { - unsigned long sc_end; + unsigned long fp_start; + unsigned long sr; }; struct arch_frame_data { diff -Nru a/arch/um/include/sysdep-i386/frame_kern.h b/arch/um/include/sysdep-i386/frame_kern.h --- a/arch/um/include/sysdep-i386/frame_kern.h Sun Feb 9 21:13:29 2003 +++ b/arch/um/include/sysdep-i386/frame_kern.h Sun Feb 9 21:13:29 2003 @@ -16,6 +16,15 @@ return((void *) sp); } +static inline void *sp_to_uc(unsigned long sp) +{ + unsigned long uc; + + uc = sp + signal_frame_si.uc_index - + signal_frame_si.common.sp_index - 4; + return((void *) uc); +} + static inline void *sp_to_rt_sc(unsigned long sp) { unsigned long sc; @@ -42,7 +51,7 @@ mask = sp - signal_frame_si.common.sp_index + signal_frame_si.common.len + - sc_size(&signal_frame_sc.arch) - 4; + sc_size(&signal_frame_si.common.arch) - 4; return((void *) mask); } diff -Nru a/arch/um/include/sysdep-i386/frame_user.h b/arch/um/include/sysdep-i386/frame_user.h --- a/arch/um/include/sysdep-i386/frame_user.h Sun Feb 9 21:13:36 2003 +++ b/arch/um/include/sysdep-i386/frame_user.h Sun Feb 9 21:13:36 2003 @@ -18,26 +18,35 @@ * setup_arch_frame uses that data to figure out what * arch_frame_data.fpstate_size should be. It really has no idea, since it's * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's - * everything from the end of the sgcontext up to the top of the stack. So, + * everything from the end of the sigcontext up to the top of the stack. So, * it masks off the page number to get the offset within the page and subtracts * that from the page size, and that's how big the fpstate struct will be * considered to be. */ static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data, - struct sigcontext *sc) + void *end, unsigned long srp) { - data->sc_end = (unsigned long) sc; - data->sc_end += sizeof(*sc); + unsigned long sr = *((unsigned long *) srp); + + data->fp_start = (unsigned long) end; + if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK)) + data->sr = sr; + else data->sr = 0; } static inline void setup_arch_frame(struct arch_frame_data_raw *in, struct arch_frame_data *out) { - unsigned long fpstate_start = in->sc_end; + unsigned long fpstate_start = in->fp_start; - fpstate_start &= ~PAGE_MASK; - out->fpstate_size = PAGE_SIZE - fpstate_start; + if(in->sr == 0){ + fpstate_start &= ~PAGE_MASK; + out->fpstate_size = PAGE_SIZE - fpstate_start; + } + else { + out->fpstate_size = in->sr - fpstate_start; + } } /* This figures out where on the stack the SA_RESTORER function address diff -Nru a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h --- a/arch/um/include/sysdep-i386/ptrace.h Sun Feb 9 21:13:29 2003 +++ b/arch/um/include/sysdep-i386/ptrace.h Sun Feb 9 21:13:29 2003 @@ -7,72 +7,101 @@ #define __SYSDEP_I386_PTRACE_H #include "uml-config.h" + +#ifdef UML_CONFIG_MODE_TT #include "ptrace-tt.h" +#endif + +#ifdef UML_CONFIG_MODE_SKAS #include "ptrace-skas.h" +#endif + #include "choose-mode.h" -struct uml_pt_regs { - unsigned long args[6]; - long syscall; - int is_user; - union { -#ifdef CONFIG_MODE_TT - void *tt; +union uml_pt_regs { +#ifdef UML_CONFIG_MODE_TT + struct tt_regs { + long syscall; + void *sc; + } tt; #endif -#ifdef CONFIG_MODE_SKAS - struct { - unsigned long regs[HOST_FRAME_SIZE]; - unsigned long fp[HOST_FP_SIZE]; - unsigned long xfp[HOST_XFP_SIZE]; - unsigned long fault_addr; - unsigned long fault_type; - unsigned long trap_type; - } skas; +#ifdef UML_CONFIG_MODE_SKAS + struct skas_regs { + unsigned long regs[HOST_FRAME_SIZE]; + unsigned long fp[HOST_FP_SIZE]; + unsigned long xfp[HOST_XFP_SIZE]; + unsigned long fault_addr; + unsigned long fault_type; + unsigned long trap_type; + long syscall; + int is_user; + } skas; #endif - } mode; }; -#define EMPTY_UML_PT_REGS { \ - syscall : -1, \ - args : { [0 ... 5] = 0 }, \ - is_user : 0 } +#define EMPTY_UML_PT_REGS { } extern int mode_tt; +#define UPT_SC(r) ((r)->tt.sc) #define UPT_IP(r) \ - CHOOSE_MODE(SC_IP((r)->mode.tt), REGS_IP((r)->mode.skas.regs)) + CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs)) #define UPT_SP(r) \ - CHOOSE_MODE(SC_SP((r)->mode.tt), REGS_SP((r)->mode.skas.regs)) + CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs)) #define UPT_EFLAGS(r) \ - CHOOSE_MODE(SC_EFLAGS((r)->mode.tt), REGS_EFLAGS((r)->mode.skas.regs)) + CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs)) #define UPT_EAX(r) \ - CHOOSE_MODE(SC_EAX((r)->mode.tt), REGS_EAX((r)->mode.skas.regs)) + CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs)) #define UPT_EBX(r) \ - CHOOSE_MODE(SC_EBX((r)->mode.tt), REGS_EBX((r)->mode.skas.regs)) + CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs)) #define UPT_ECX(r) \ - CHOOSE_MODE(SC_ECX((r)->mode.tt), REGS_ECX((r)->mode.skas.regs)) + CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs)) #define UPT_EDX(r) \ - CHOOSE_MODE(SC_EDX((r)->mode.tt), REGS_EDX((r)->mode.skas.regs)) + CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs)) #define UPT_ESI(r) \ - CHOOSE_MODE(SC_ESI((r)->mode.tt), REGS_ESI((r)->mode.skas.regs)) + CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs)) #define UPT_EDI(r) \ - CHOOSE_MODE(SC_EDI((r)->mode.tt), REGS_EDI((r)->mode.skas.regs)) + CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs)) #define UPT_EBP(r) \ - CHOOSE_MODE(SC_EBP((r)->mode.tt), REGS_EBP((r)->mode.skas.regs)) -#define UPT_ORIG_EAX(r) ((r)->syscall) + CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs)) +#define UPT_ORIG_EAX(r) \ + CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall) #define UPT_CS(r) \ - CHOOSE_MODE(SC_CS((r)->mode.tt), REGS_CS((r)->mode.skas.regs)) + CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) #define UPT_SS(r) \ - CHOOSE_MODE(SC_SS((r)->mode.tt), REGS_SS((r)->mode.skas.regs)) + CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs)) #define UPT_DS(r) \ - CHOOSE_MODE(SC_DS((r)->mode.tt), REGS_DS((r)->mode.skas.regs)) + CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs)) #define UPT_ES(r) \ - CHOOSE_MODE(SC_ES((r)->mode.tt), REGS_ES((r)->mode.skas.regs)) + CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs)) #define UPT_FS(r) \ - CHOOSE_MODE(SC_FS((r)->mode.tt), REGS_FS((r)->mode.skas.regs)) + CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs)) #define UPT_GS(r) \ - CHOOSE_MODE(SC_GS((r)->mode.tt), REGS_GS((r)->mode.skas.regs)) -#define UPT_SC(r) ((r)->mode.tt) + CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs)) + +#define UPT_SYSCALL_ARG1(r) UPT_EBX(r) +#define UPT_SYSCALL_ARG2(r) UPT_ECX(r) +#define UPT_SYSCALL_ARG3(r) UPT_EDX(r) +#define UPT_SYSCALL_ARG4(r) UPT_ESI(r) +#define UPT_SYSCALL_ARG5(r) UPT_EDI(r) +#define UPT_SYSCALL_ARG6(r) UPT_EBP(r) + +extern int user_context(unsigned long sp); + +#define UPT_IS_USER(r) \ + CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user) + +struct syscall_args { + unsigned long args[6]; +}; + +#define SYSCALL_ARGS(r) ((struct syscall_args) \ + { .args = { UPT_SYSCALL_ARG1(r), \ + UPT_SYSCALL_ARG2(r), \ + UPT_SYSCALL_ARG3(r), \ + UPT_SYSCALL_ARG4(r), \ + UPT_SYSCALL_ARG5(r), \ + UPT_SYSCALL_ARG6(r) } } ) #define UPT_REG(regs, reg) \ ({ unsigned long val; \ @@ -129,28 +158,26 @@ } while (0) #define UPT_SET_SYSCALL_RETURN(r, res) \ - CHOOSE_MODE(SC_SET_SYSCALL_RETURN((r)->mode.tt, (res)), \ - REGS_SET_SYSCALL_RETURN((r)->mode.skas.regs, (res))) + CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \ + REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res))) #define UPT_RESTART_SYSCALL(r) \ - CHOOSE_MODE(SC_RESTART_SYSCALL((r)->mode.tt), \ - REGS_RESTART_SYSCALL((r)->mode.skas.regs)) + CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \ + REGS_RESTART_SYSCALL((r)->skas.regs)) #define UPT_ORIG_SYSCALL(r) UPT_EAX(r) -#define UPT_SYSCALL_NR(r) ((r)->syscall) +#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) #define UPT_SYSCALL_RET(r) UPT_EAX(r) #define UPT_SEGV_IS_FIXABLE(r) \ - CHOOSE_MODE(SC_SEGV_IS_FIXABLE(r->mode.tt), \ - REGS_SEGV_IS_FIXABLE(&r->mode.skas)) + CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ + REGS_SEGV_IS_FIXABLE(&r->skas)) #define UPT_FAULT_ADDR(r) \ - CHOOSE_MODE(SC_FAULT_ADDR(r->mode.tt), \ - REGS_FAULT_ADDR(&r->mode.skas)) + CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas)) #define UPT_FAULT_WRITE(r) \ - CHOOSE_MODE(SC_FAULT_WRITE(r->mode.tt), \ - REGS_FAULT_WRITE(&r->mode.skas)) + CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas)) #endif diff -Nru a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h --- a/arch/um/include/sysdep-i386/sigcontext.h Sun Feb 9 21:13:34 2003 +++ b/arch/um/include/sysdep-i386/sigcontext.h Sun Feb 9 21:13:34 2003 @@ -33,34 +33,6 @@ #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc))) -#ifdef CONFIG_MODE_TT -/* XXX struct sigcontext needs declaring by now */ -static inline void sc_to_regs(struct uml_pt_regs *regs, struct sigcontext *sc, - unsigned long syscall) -{ - regs->syscall = syscall; - regs->args[0] = SC_EBX(sc); - regs->args[1] = SC_ECX(sc); - regs->args[2] = SC_EDX(sc); - regs->args[3] = SC_ESI(sc); - regs->args[4] = SC_EDI(sc); - regs->args[5] = SC_EBP(sc); -} -#endif - -#ifdef CONFIG_MODE_SKAS -static inline void host_to_regs(struct uml_pt_regs *regs) -{ - regs->syscall = UPT_ORIG_EAX(regs); - regs->args[0] = UPT_EBX(regs); - regs->args[1] = UPT_ECX(regs); - regs->args[2] = UPT_EDX(regs); - regs->args[3] = UPT_ESI(regs); - regs->args[4] = UPT_EDI(regs); - regs->args[5] = UPT_EBP(regs); -} -#endif - extern unsigned long *sc_sigmask(void *sc_ptr); extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); diff -Nru a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h --- a/arch/um/include/sysdep-i386/syscalls.h Sun Feb 9 21:13:29 2003 +++ b/arch/um/include/sysdep-i386/syscalls.h Sun Feb 9 21:13:29 2003 @@ -4,10 +4,12 @@ */ #include "asm/unistd.h" +#include "sysdep/ptrace.h" typedef long syscall_handler_t(struct pt_regs); -#define EXECUTE_SYSCALL(syscall, regs) (*sys_call_table[syscall])(*regs); +#define EXECUTE_SYSCALL(syscall, regs) \ + ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) extern syscall_handler_t sys_modify_ldt; extern syscall_handler_t old_mmap_i386; diff -Nru a/arch/um/include/time_user.h b/arch/um/include/time_user.h --- a/arch/um/include/time_user.h Sun Feb 9 21:13:29 2003 +++ b/arch/um/include/time_user.h Sun Feb 9 21:13:29 2003 @@ -11,7 +11,7 @@ extern void set_interval(int timer_type); extern void idle_sleep(int secs); extern void enable_timer(void); -extern void time_lock(void); -extern void time_unlock(void); +extern unsigned long time_lock(void); +extern void time_unlock(unsigned long); #endif diff -Nru a/arch/um/include/umid.h b/arch/um/include/umid.h --- a/arch/um/include/umid.h Sun Feb 9 21:13:30 2003 +++ b/arch/um/include/umid.h Sun Feb 9 21:13:30 2003 @@ -3,7 +3,12 @@ * Licensed under the GPL */ +#ifndef __UMID_H__ +#define __UMID_H__ + extern int umid_file_name(char *name, char *buf, int len); + +#endif /* * Overrides for Emacs so that we follow Linus's tabbing style. diff -Nru a/arch/um/include/uml_uaccess.h b/arch/um/include/uml_uaccess.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/um/include/uml_uaccess.h Sun Feb 9 21:13:37 2003 @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UML_UACCESS_H__ +#define __UML_UACCESS_H__ + +extern int __do_copy_to_user(void *to, const void *from, int n, + void **fault_addr, void **fault_catcher); +extern unsigned long __do_user_copy(void *to, const void *from, int n, + void **fault_addr, void **fault_catcher, + void (*op)(void *to, const void *from, + int n), int *faulted_out); +void __do_copy(void *to, const void *from, int n); + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -Nru a/arch/um/include/user_util.h b/arch/um/include/user_util.h --- a/arch/um/include/user_util.h Sun Feb 9 21:13:29 2003 +++ b/arch/um/include/user_util.h Sun Feb 9 21:13:29 2003 @@ -24,7 +24,7 @@ extern struct cpu_task cpu_tasks[]; struct signal_info { - void (*handler)(int, struct uml_pt_regs *); + void (*handler)(int, union uml_pt_regs *); int is_irq; }; @@ -61,7 +61,6 @@ int clone_flags, int (*tramp)(void *)); extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags); extern int linux_main(int argc, char **argv); -extern void remap_data(void *segment_start, void *segment_end, int w); extern void set_cmdline(char *cmd); extern void input_cb(void (*proc)(void *), void *arg, int arg_len); extern int get_pty(void); @@ -87,7 +86,7 @@ extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); extern void write_sigio_workaround(void); extern void arch_check_bugs(void); -extern int arch_handle_signal(int sig, struct uml_pt_regs *regs); +extern int arch_handle_signal(int sig, union uml_pt_regs *regs); extern int arch_fixup(unsigned long address, void *sc_ptr); extern void forward_pending_sigio(int target); extern int can_do_skas(void); diff -Nru a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile --- a/arch/um/kernel/Makefile Sun Feb 9 21:13:34 2003 +++ b/arch/um/kernel/Makefile Sun Feb 9 21:13:34 2003 @@ -3,15 +3,13 @@ # Licensed under the GPL # -EXTRA_TARGETS := unmap_fin.o - obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \ helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \ process.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \ sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o \ syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \ - time_kern.o tlb.o trap_kern.o trap_user.o um_arch.o \ - umid.o user_util.o + time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \ + umid.o user_syms.o user_util.o obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o obj-$(CONFIG_GPROF) += gprof_syms.o @@ -23,23 +21,13 @@ user-objs-$(CONFIG_TTY_LOG) += tty_log.o -# user_syms.o not included here because Rules.make has its own ideas about -# building anything in export-objs - USER_OBJS := $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \ process.o tempfile.o time.o tty_log.o umid.o user_util.o user_syms.o USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) -UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS)) -UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS)) - DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__ DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__ -export-objs-$(CONFIG_GPROF) += gprof_syms.o -export-objs-$(CONFIG_GCOV) += gmon_syms.o - -export-objs := ksyms.o process_kern.o signal_kern.o $(export-objs-y) CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \ -I/usr/include -I../include @@ -47,13 +35,7 @@ CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS)) $(USER_OBJS) : %.o: %.c - $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< - -$(obj)/unmap.o: $(src)/unmap.c - $(CC) $(UNMAP_CFLAGS) -c -o $@ $< - -$(obj)/unmap_fin.o : $(src)/unmap.o - ld -r -o $@ $< -lc -L/usr/lib + $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< # This has to be separate because it needs be compiled with frame pointers # regardless of how the rest of the kernel is built. diff -Nru a/arch/um/kernel/frame.c b/arch/um/kernel/frame.c --- a/arch/um/kernel/frame.c Sun Feb 9 21:13:30 2003 +++ b/arch/um/kernel/frame.c Sun Feb 9 21:13:30 2003 @@ -78,7 +78,8 @@ /* It has outlived its usefulness, so continue it so it can exit */ if(ptrace(PTRACE_CONT, pid, 0, 0) < 0){ - printf("capture_stack : mmap failed - errno = %d\n", errno); + printf("capture_stack : PTRACE_CONT failed - errno = %d\n", + errno); exit(1); } if(waitpid(pid, &status, 0) < 0){ @@ -110,6 +111,7 @@ unsigned long sig; unsigned long sr; unsigned long sp; + struct arch_frame_data_raw arch; }; #define SA_RESTORER (0x04000000) @@ -173,7 +175,6 @@ struct common_raw common; unsigned long sc; int restorer; - struct arch_frame_data_raw arch; }; /* Changed only during early boot */ @@ -185,7 +186,8 @@ raw_sc->common.sr = frame_restorer(); raw_sc->common.sp = frame_sp(); raw_sc->sc = (unsigned long) ≻ - setup_arch_frame_raw(&raw_sc->arch, &sc); + setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr); + os_stop_process(os_getpid()); kill(getpid(), SIGKILL); } @@ -205,18 +207,25 @@ struct common_raw common; unsigned long sip; unsigned long si; + unsigned long ucp; + unsigned long uc; }; /* Changed only during early boot */ static struct si_frame_raw *raw_si = NULL; -static void si_handler(int sig, siginfo_t *si) +static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext) { raw_si->common.sig = (unsigned long) &sig; raw_si->common.sr = frame_restorer(); raw_si->common.sp = frame_sp(); raw_si->sip = (unsigned long) &si; raw_si->si = (unsigned long) si; + raw_si->ucp = (unsigned long) &ucontext; + raw_si->uc = (unsigned long) ucontext; + setup_arch_frame_raw(&raw_si->common.arch, + ucontext->uc_mcontext.fpregs, raw_si->common.sr); + os_stop_process(os_getpid()); kill(getpid(), SIGKILL); } @@ -292,7 +301,7 @@ &signal_frame_sc.common); signal_frame_sc.sc_index = raw_sc.sc - base; - setup_arch_frame(&raw_sc.arch, &signal_frame_sc.arch); + setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch); /* Ditto for the sigcontext, sigrestorer layout */ raw_sc.restorer = 1; @@ -300,6 +309,7 @@ (void *) top, sigstack, PAGE_SIZE, &signal_frame_sc_sr.common); signal_frame_sc_sr.sc_index = raw_sc.sc - base; + setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch); /* And the siginfo layout */ @@ -308,6 +318,9 @@ &signal_frame_si.common); signal_frame_si.sip_index = raw_si.sip - base; signal_frame_si.si_index = raw_si.si - base; + signal_frame_si.ucp_index = raw_si.ucp - base; + signal_frame_si.uc_index = raw_si.uc - base; + setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch); if((munmap(stack, PAGE_SIZE) < 0) || (munmap(sigstack, PAGE_SIZE) < 0)){ diff -Nru a/arch/um/kernel/frame_kern.c b/arch/um/kernel/frame_kern.c --- a/arch/um/kernel/frame_kern.c Sun Feb 9 21:13:37 2003 +++ b/arch/um/kernel/frame_kern.c Sun Feb 9 21:13:37 2003 @@ -6,6 +6,8 @@ #include "asm/ptrace.h" #include "asm/uaccess.h" #include "asm/signal.h" +#include "asm/uaccess.h" +#include "asm/ucontext.h" #include "frame_kern.h" #include "sigcontext.h" #include "sysdep/ptrace.h" @@ -27,48 +29,62 @@ sizeof(restorer))); } -static int copy_sc_to_user(void *to, struct pt_regs *from) +static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, + struct arch_frame_data *arch) { - return(CHOOSE_MODE(copy_sc_to_user_tt(to, from->regs.mode.tt, - &signal_frame_sc_sr.arch), - copy_sc_to_user_skas(to, &from->regs, + return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), + arch), + copy_sc_to_user_skas(to, fp, &from->regs, current->thread.cr2, current->thread.err))); } +static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set, + unsigned long sp) +{ + int err = 0; + + err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp); + err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags); + err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); + err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, + &signal_frame_si.common.arch); + err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); + return(err); +} + int setup_signal_stack_si(unsigned long stack_top, int sig, unsigned long handler, void (*restorer)(void), struct pt_regs *regs, siginfo_t *info, sigset_t *mask) { - unsigned long start, sc, sigs; - void *sip; - int sig_size = _NSIG_WORDS * sizeof(unsigned long); + unsigned long start; + void *sip, *ucp, *fp; - start = stack_top - signal_frame_si.common.len - - sc_size(&signal_frame_sc.arch) - sig_size; + start = stack_top - signal_frame_si.common.len; sip = (void *) (start + signal_frame_si.si_index); - sc = start + signal_frame_si.common.len; - sigs = sc + sc_size(&signal_frame_sc.arch); + ucp = (void *) (start + signal_frame_si.uc_index); + fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext)); if(restorer == NULL) panic("setup_signal_stack_si - no restorer"); - if(copy_sc_to_user((void *) sc, regs) || - copy_to_user((void *) start, signal_frame_si.common.data, + if(copy_to_user((void *) start, signal_frame_si.common.data, signal_frame_si.common.len) || copy_to_user((void *) (start + signal_frame_si.common.sig_index), &sig, sizeof(sig)) || copy_siginfo_to_user(sip, info) || copy_to_user((void *) (start + signal_frame_si.sip_index), &sip, sizeof(sip)) || - copy_to_user((void *) sigs, mask, sig_size) || + copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) || + copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp, + sizeof(ucp)) || copy_restorer(restorer, start, signal_frame_si.common.sr_index, signal_frame_si.common.sr_relative)) return(1); PT_REGS_IP(regs) = handler; - PT_REGS_SP(regs) = start + signal_frame_sc.common.sp_index; + PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index; return(0); } @@ -96,7 +112,8 @@ if(copy_to_user((void *) start, frame->data, frame->len) || copy_to_user((void *) (start + frame->sig_index), &sig, sizeof(sig)) || - copy_sc_to_user(user_sc, regs) || + copy_sc_to_user(user_sc, NULL, regs, + &signal_frame_sc.common.arch) || copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) || copy_to_user((void *) sigs, &mask->sig[1], sig_size) || copy_restorer(restorer, start, frame->sr_index, frame->sr_relative)) diff -Nru a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c --- a/arch/um/kernel/init_task.c Sun Feb 9 21:13:37 2003 +++ b/arch/um/kernel/init_task.c Sun Feb 9 21:13:37 2003 @@ -3,6 +3,7 @@ * Licensed under the GPL */ +#include "linux/config.h" #include "linux/mm.h" #include "linux/sched.h" #include "linux/init_task.h" @@ -37,17 +38,16 @@ __attribute__((__section__(".data.init_task"))) = { INIT_THREAD_INFO(init_task) }; -struct task_struct *alloc_task_struct(void){ - struct task_struct *task; - - task = (struct task_struct *) __get_free_pages(GFP_KERNEL, 2); - if(task == NULL) return(NULL); - return(task); +struct task_struct *alloc_task_struct(void) +{ + return((struct task_struct *) + __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER)); } void unprotect_stack(unsigned long stack) { - protect_memory(stack, 4 * PAGE_SIZE, 1, 1, 0, 1); + protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, + 1, 1, 0, 1); } void free_task_struct(struct task_struct *task) @@ -55,7 +55,7 @@ /* free_pages decrements the page counter and only actually frees * the pages if they are now not accessed by anything. */ - free_pages((unsigned long) task, 2); + free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER); } /* diff -Nru a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c --- a/arch/um/kernel/irq.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/kernel/irq.c Sun Feb 9 21:13:35 2003 @@ -271,7 +271,7 @@ * SMP cross-CPU interrupts have their own specific * handlers). */ -unsigned int do_IRQ(int irq, struct uml_pt_regs *regs) +unsigned int do_IRQ(int irq, union uml_pt_regs *regs) { /* * 0 return value means that this irq is already being diff -Nru a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c --- a/arch/um/kernel/irq_user.c Sun Feb 9 21:13:31 2003 +++ b/arch/um/kernel/irq_user.c Sun Feb 9 21:13:31 2003 @@ -42,7 +42,7 @@ extern int io_count, intr_count; -void sigio_handler(int sig, struct uml_pt_regs *regs) +void sigio_handler(int sig, union uml_pt_regs *regs) { struct irq_fd *irq_fd, *next; int i, n; @@ -128,15 +128,15 @@ if(type == IRQ_READ) events = POLLIN | POLLPRI; else events = POLLOUT; - *new_fd = ((struct irq_fd) { next : NULL, - id : dev_id, - fd : fd, - type : type, - irq : irq, - pid : pid, - events : events, - current_events: 0, - freed : 0 } ); + *new_fd = ((struct irq_fd) { .next = NULL, + .id = dev_id, + .fd = fd, + .type = type, + .irq = irq, + .pid = pid, + .events = events, + .current_events = 0, + .freed = 0 } ); /* Critical section - locked by a spinlock because this stuff can * be changed from interrupt handlers. The stuff above is done @@ -191,9 +191,9 @@ if(type == IRQ_WRITE) fd = -1; - pollfds[pollfds_num] = ((struct pollfd) { fd : fd, - events : events, - revents : 0 }); + pollfds[pollfds_num] = ((struct pollfd) { .fd = fd, + .events = events, + .revents = 0 }); pollfds_num++; *last_irq_ptr = new_fd; @@ -265,8 +265,8 @@ void free_irq_by_irq_and_dev(int irq, void *dev) { - struct irq_and_dev data = ((struct irq_and_dev) { irq : irq, - dev : dev }); + struct irq_and_dev data = ((struct irq_and_dev) { .irq = irq, + .dev = dev }); free_irq_by_cb(same_irq_and_dev, &data); } diff -Nru a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c --- a/arch/um/kernel/ksyms.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/kernel/ksyms.c Sun Feb 9 21:13:28 2003 @@ -14,6 +14,7 @@ #include "asm/processor.h" #include "asm/unistd.h" #include "asm/pgalloc.h" +#include "asm/pgtable.h" #include "asm/page.h" #include "asm/tlbflush.h" #include "kern_util.h" @@ -42,7 +43,11 @@ EXPORT_SYMBOL(phys_to_page); EXPORT_SYMBOL(high_physmem); EXPORT_SYMBOL(empty_zero_page); +EXPORT_SYMBOL(um_virt_to_phys); +EXPORT_SYMBOL(mode_tt); +EXPORT_SYMBOL(handle_page_fault); +EXPORT_SYMBOL(os_getpid); EXPORT_SYMBOL(os_open_file); EXPORT_SYMBOL(os_read_file); EXPORT_SYMBOL(os_write_file); @@ -75,7 +80,6 @@ extern void FASTCALL( __read_lock_failed(rwlock_t *rw)); EXPORT_SYMBOL_NOVERS(__read_lock_failed); -EXPORT_SYMBOL(smp_num_cpus); #endif #ifdef CONFIG_HIGHMEM diff -Nru a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c --- a/arch/um/kernel/mem.c Sun Feb 9 21:13:31 2003 +++ b/arch/um/kernel/mem.c Sun Feb 9 21:13:31 2003 @@ -27,6 +27,7 @@ #include "init.h" #include "os.h" #include "mode_kern.h" +#include "uml_uaccess.h" /* Changed during early boot */ pgd_t swapper_pg_dir[1024]; @@ -231,11 +232,11 @@ panic("Failed to allocating mem_region"); } - *region = ((struct mem_region) { driver : driver, - start_pfn : pfn, - start : start, - len : len, - fd : fd } ); + *region = ((struct mem_region) { .driver = driver, + .start_pfn = pfn, + .start = start, + .len = len, + .fd = fd } ); regions[i] = region; out: up(®ions_sem); @@ -414,8 +415,28 @@ struct page *arch_validate(struct page *page, int mask, int order) { - return(CHOOSE_MODE_PROC(arch_validate_tt, arch_validate_skas, page, - mask, order)); + unsigned long addr, zero = 0; + int i; + + again: + if(page == NULL) return(page); + if(PageHighMem(page)) return(page); + + addr = (unsigned long) page_address(page); + for(i = 0; i < (1 << order); i++){ + current->thread.fault_addr = (void *) addr; + if(__do_copy_to_user((void *) addr, &zero, + sizeof(zero), + ¤t->thread.fault_addr, + ¤t->thread.fault_catcher)){ + if(!(mask & __GFP_WAIT)) return(NULL); + else break; + } + addr += PAGE_SIZE; + } + if(i == (1 << order)) return(page); + page = alloc_pages(mask, order); + goto again; } DECLARE_MUTEX(vm_reserved_sem); @@ -423,15 +444,15 @@ /* Static structures, linked in to the list in early boot */ static struct vm_reserved head = { - list : LIST_HEAD_INIT(head.list), - start : 0, - end : 0xffffffff + .list = LIST_HEAD_INIT(head.list), + .start = 0, + .end = 0xffffffff }; static struct vm_reserved tail = { - list : LIST_HEAD_INIT(tail.list), - start : 0, - end : 0xffffffff + .list = LIST_HEAD_INIT(tail.list), + .start = 0, + .end = 0xffffffff }; void set_usable_vm(unsigned long start, unsigned long end) @@ -467,9 +488,9 @@ goto out; } *entry = ((struct vm_reserved) - { list : LIST_HEAD_INIT(entry->list), - start : start, - end : end }); + { .list = LIST_HEAD_INIT(entry->list), + .start = start, + .end = end }); list_add(&entry->list, &prev->list); err = 0; out: @@ -539,9 +560,9 @@ */ struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] = - { name : NULL, - fd : -1, - size : 0 } }; + { .name = NULL, + .fd = -1, + .size = 0 } }; int num_iomem_regions = 0; @@ -551,9 +572,9 @@ return; size = (size + PAGE_SIZE - 1) & PAGE_MASK; iomem_regions[num_iomem_regions++] = - ((struct iomem) { name : name, - fd : fd, - size : size } ); + ((struct iomem) { .name = name, + .fd = fd, + .size = size } ); } int setup_iomem(void) diff -Nru a/arch/um/kernel/process.c b/arch/um/kernel/process.c --- a/arch/um/kernel/process.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/kernel/process.c Sun Feb 9 21:13:35 2003 @@ -37,17 +37,18 @@ #include "uml-config.h" #include "choose-mode.h" #include "mode.h" -#ifdef CONFIG_MODE_SKAS -#include "skas_ptrace.h" +#ifdef UML_CONFIG_MODE_SKAS #include "skas.h" +#include "skas_ptrace.h" #endif void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) { - int flags = 0; + int flags = 0, pages; if(sig_stack != NULL){ - set_sigstack(sig_stack, 2 * page_size()); + pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2; + set_sigstack(sig_stack, pages * page_size()); flags = SA_ONSTACK; } if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1); @@ -251,32 +252,32 @@ int can_do_skas(void) { -#ifdef CONFIG_MODE_SKAS +#ifdef UML_CONFIG_MODE_SKAS struct ptrace_faultinfo fi; void *stack; int pid, n, ret = 1; - printk("Checking for the skas3 patch in the host..."); + printf("Checking for the skas3 patch in the host..."); pid = start_ptraced_child(&stack); n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); if(n < 0){ if(errno == EIO) - printk("not found\n"); - else printk("No (unexpected errno - %d)\n", errno); + printf("not found\n"); + else printf("No (unexpected errno - %d)\n", errno); ret = 0; } - else printk("found\n"); + else printf("found\n"); init_registers(pid); stop_ptraced_child(pid, stack, 1); - printk("Checking for /proc/mm..."); + printf("Checking for /proc/mm..."); if(access("/proc/mm", W_OK)){ - printk("not found\n"); + printf("not found\n"); ret = 0; } - else printk("found\n"); + else printf("found\n"); return(ret); #else diff -Nru a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c --- a/arch/um/kernel/process_kern.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/kernel/process_kern.c Sun Feb 9 21:13:32 2003 @@ -169,8 +169,12 @@ void initial_thread_cb(void (*proc)(void *), void *arg) { + int save_kmalloc_ok = kmalloc_ok; + + kmalloc_ok = 0; CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, arg); + kmalloc_ok = save_kmalloc_ok; } unsigned long stack_sp(unsigned long page) @@ -306,7 +310,11 @@ int user_context(unsigned long sp) { - return((sp & (PAGE_MASK << 1)) != current->thread.kernel_stack); + unsigned long stack; + + stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER); + stack += 2 * PAGE_SIZE; + return(stack != current->thread.kernel_stack); } extern void remove_umid_dir(void); diff -Nru a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c --- a/arch/um/kernel/ptrace.c Sun Feb 9 21:13:29 2003 +++ b/arch/um/kernel/ptrace.c Sun Feb 9 21:13:29 2003 @@ -9,7 +9,9 @@ #include "linux/smp_lock.h" #include "linux/security.h" #include "linux/ptrace.h" +#ifdef CONFIG_PROC_MM #include "linux/proc_mm.h" +#endif #include "asm/ptrace.h" #include "asm/uaccess.h" #include "kern_util.h" diff -Nru a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c --- a/arch/um/kernel/sigio_user.c Sun Feb 9 21:13:36 2003 +++ b/arch/um/kernel/sigio_user.c Sun Feb 9 21:13:36 2003 @@ -52,7 +52,7 @@ { struct sigaction old, new; struct termios tt; - struct openpty_arg pty = { master : -1, slave : -1 }; + struct openpty_arg pty = { .master = -1, .slave = -1 }; int master, slave, flags; initial_thread_cb(openpty_cb, &pty); @@ -111,6 +111,7 @@ printk("Checking that host ptys support output SIGIO..."); + memset(buf, 0, sizeof(buf)); while(write(master, buf, sizeof(buf)) > 0) ; if(errno != EAGAIN) panic("check_sigio : write failed, errno = %d\n", errno); @@ -170,15 +171,15 @@ * synchronizes with it. */ struct pollfds current_poll = { - poll : NULL, - size : 0, - used : 0 + .poll = NULL, + .size = 0, + .used = 0 }; struct pollfds next_poll = { - poll : NULL, - size : 0, - used : 0 + .poll = NULL, + .size = 0, + .used = 0 }; static int write_sigio_thread(void *unused) @@ -267,7 +268,8 @@ return; fail: sigio_lock(); - if(write_sigio_pid != -1) kill(write_sigio_pid, SIGKILL); + if(write_sigio_pid != -1) + os_kill_process(write_sigio_pid, 1); write_sigio_pid = -1; close(sigio_private[0]); close(sigio_private[1]); @@ -298,9 +300,9 @@ if(read) events = POLLIN; else events = POLLOUT; - next_poll.poll[n - 1] = ((struct pollfd) { fd : fd, - events : events, - revents : 0 }); + next_poll.poll[n - 1] = ((struct pollfd) { .fd = fd, + .events = events, + .revents = 0 }); update_thread(); out: sigio_unlock(); @@ -348,12 +350,12 @@ printk("setup_initial_poll : failed to allocate poll\n"); return(-1); } - *p = ((struct pollfd) { fd : fd, - events : POLLIN, - revents : 0 }); - current_poll = ((struct pollfds) { poll : p, - used : 1, - size : 1 }); + *p = ((struct pollfd) { .fd = fd, + .events = POLLIN, + .revents = 0 }); + current_poll = ((struct pollfds) { .poll = p, + .used = 1, + .size = 1 }); return(0); } @@ -394,7 +396,7 @@ return; out_kill: - kill(write_sigio_pid, SIGKILL); + os_kill_process(write_sigio_pid, 1); write_sigio_pid = -1; out_close2: close(sigio_private[0]); @@ -420,7 +422,8 @@ static void sigio_cleanup(void) { - if(write_sigio_pid != -1) kill(write_sigio_pid, SIGKILL); + if(write_sigio_pid != -1) + os_kill_process(write_sigio_pid, 1); } __uml_exitcall(sigio_cleanup); diff -Nru a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c --- a/arch/um/kernel/signal_kern.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/kernel/signal_kern.c Sun Feb 9 21:13:32 2003 @@ -18,6 +18,7 @@ #include "asm/uaccess.h" #include "asm/unistd.h" #include "user_util.h" +#include "asm/ucontext.h" #include "kern_util.h" #include "signal_kern.h" #include "signal_user.h" @@ -29,18 +30,6 @@ EXPORT_SYMBOL(block_signals); EXPORT_SYMBOL(unblock_signals); -int probe_stack(unsigned long sp, int delta) -{ - int n; - - if((get_user(n, (int *) sp) != 0) || - (put_user(n, (int *) sp) != 0) || - (get_user(n, (int *) (sp - delta)) != 0) || - (put_user(n, (int *) (sp - delta)) != 0)) - return(-EFAULT); - return(0); -} - static void force_segv(int sig) { if(sig == SIGSEGV){ @@ -106,12 +95,12 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); sigaddset(¤t->blocked, signr); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } sp = PT_REGS_SP(regs); @@ -197,11 +186,11 @@ sigset_t saveset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); while (1) { current->state = TASK_INTERRUPTIBLE; @@ -223,11 +212,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); while (1) { current->state = TASK_INTERRUPTIBLE; @@ -237,45 +226,48 @@ } } -static int copy_sc_from_user(struct pt_regs *to, void *from) +static int copy_sc_from_user(struct pt_regs *to, void *from, + struct arch_frame_data *arch) { int ret; - ret = CHOOSE_MODE(copy_sc_from_user_tt(to->regs.mode.tt, from, - &signal_frame_sc.arch), + ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch), copy_sc_from_user_skas(&to->regs, from)); return(ret); } int sys_sigreturn(struct pt_regs regs) { - void *sc = sp_to_sc(PT_REGS_SP(®s)); - void *mask = sp_to_mask(PT_REGS_SP(®s)); + void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs)); + void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs)); int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); copy_from_user(¤t->blocked.sig[0], sc_sigmask(sc), sizeof(current->blocked.sig[0])); copy_from_user(¤t->blocked.sig[1], mask, sig_size); sigdelsetmask(¤t->blocked, ~_BLOCKABLE); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); - copy_sc_from_user(¤t->thread.regs, sc); + spin_unlock_irq(¤t->sighand->siglock); + copy_sc_from_user(¤t->thread.regs, sc, + &signal_frame_sc.common.arch); return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); } int sys_rt_sigreturn(struct pt_regs regs) { - void *sc = sp_to_rt_sc(PT_REGS_SP(®s)); - void *mask = sp_to_rt_mask(PT_REGS_SP(®s)); + struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs)); + void *fp; int sig_size = _NSIG_WORDS * sizeof(unsigned long); - spin_lock_irq(¤t->sig->siglock); - copy_from_user(¤t->blocked, mask, sig_size); + spin_lock_irq(¤t->sighand->siglock); + copy_from_user(¤t->blocked, &uc->uc_sigmask, sig_size); sigdelsetmask(¤t->blocked, ~_BLOCKABLE); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); - copy_sc_from_user(¤t->thread.regs, sc); + spin_unlock_irq(¤t->sighand->siglock); + fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext)); + copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext, + &signal_frame_si.common.arch); return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); } diff -Nru a/arch/um/kernel/skas/include/mode.h b/arch/um/kernel/skas/include/mode.h --- a/arch/um/kernel/skas/include/mode.h Sun Feb 9 21:13:32 2003 +++ b/arch/um/kernel/skas/include/mode.h Sun Feb 9 21:13:32 2003 @@ -12,10 +12,11 @@ extern int have_fpx_regs; extern void user_time_init_skas(void); -extern int copy_sc_from_user_skas(struct uml_pt_regs *regs, void *from_ptr); -extern int copy_sc_to_user_skas(void *to_ptr, struct uml_pt_regs *regs, +extern int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr); +extern int copy_sc_to_user_skas(void *to_ptr, void *fp, + union uml_pt_regs *regs, unsigned long fault_addr, int fault_type); -extern void sig_handler_common_skas(int sig, struct sigcontext *sc); +extern void sig_handler_common_skas(int sig, void *sc_ptr); extern void halt_skas(void); extern void reboot_skas(void); extern void kill_off_processes_skas(void); diff -Nru a/arch/um/kernel/skas/include/mode_kern.h b/arch/um/kernel/skas/include/mode_kern.h --- a/arch/um/kernel/skas/include/mode_kern.h Sun Feb 9 21:13:32 2003 +++ b/arch/um/kernel/skas/include/mode_kern.h Sun Feb 9 21:13:32 2003 @@ -21,6 +21,8 @@ extern void exit_thread_skas(void); extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); extern void init_idle_skas(void); +extern void flush_tlb_kernel_range_skas(unsigned long start, + unsigned long end); extern void flush_tlb_kernel_vm_skas(void); extern void __flush_tlb_one_skas(unsigned long addr); extern void flush_tlb_range_skas(struct vm_area_struct *vma, @@ -32,11 +34,10 @@ extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, unsigned long *task_size_out); extern int start_uml_skas(void); -extern struct page *arch_validate_skas(struct page *page, int mask, int order); extern int external_pid_skas(struct task_struct *task); extern int thread_pid_skas(struct task_struct *task); -#define kmem_end_skas (host_task_size) +#define kmem_end_skas (host_task_size - 1024 * 1024) #endif diff -Nru a/arch/um/kernel/skas/include/ptrace-skas.h b/arch/um/kernel/skas/include/ptrace-skas.h --- a/arch/um/kernel/skas/include/ptrace-skas.h Sun Feb 9 21:13:29 2003 +++ b/arch/um/kernel/skas/include/ptrace-skas.h Sun Feb 9 21:13:29 2003 @@ -8,7 +8,7 @@ #include "uml-config.h" -#ifdef CONFIG_MODE_SKAS +#ifdef UML_CONFIG_MODE_SKAS #include "skas_ptregs.h" diff -Nru a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h --- a/arch/um/kernel/skas/include/skas.h Sun Feb 9 21:13:30 2003 +++ b/arch/um/kernel/skas/include/skas.h Sun Feb 9 21:13:30 2003 @@ -17,21 +17,21 @@ extern int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr); extern int user_thread(unsigned long stack, int flags); -extern void userspace(struct uml_pt_regs *regs); +extern void userspace(union uml_pt_regs *regs); extern void new_thread_proc(void *stack, void (*handler)(int sig)); extern void remove_sigstack(void); extern void new_thread_handler(int sig); -extern void handle_syscall(struct uml_pt_regs *regs); +extern void handle_syscall(union uml_pt_regs *regs); extern void map(int fd, unsigned long virt, unsigned long phys, unsigned long len, int r, int w, int x); extern int unmap(int fd, void *addr, int len); extern int protect(int fd, unsigned long addr, unsigned long len, int r, int w, int x, int must_succeed); -extern void user_signal(int sig, struct uml_pt_regs *regs); +extern void user_signal(int sig, union uml_pt_regs *regs); extern int singlestepping_skas(void); extern int new_mm(int from); -extern void save_registers(struct uml_pt_regs *regs); -extern void restore_registers(struct uml_pt_regs *regs); +extern void save_registers(union uml_pt_regs *regs); +extern void restore_registers(union uml_pt_regs *regs); extern void start_userspace(void); extern void init_registers(int pid); diff -Nru a/arch/um/kernel/skas/include/skas_ptrace.h b/arch/um/kernel/skas/include/skas_ptrace.h --- a/arch/um/kernel/skas/include/skas_ptrace.h Sun Feb 9 21:13:35 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __SKAS_PTRACE_H -#define __SKAS_PTRACE_H - -struct ptrace_faultinfo { - int is_write; - unsigned long addr; -}; - -struct ptrace_ldt { - int func; - void *ptr; - unsigned long bytecount; -}; - -#define PTRACE_FAULTINFO 52 -#define PTRACE_SIGPENDING 53 -#define PTRACE_LDT 54 -#define PTRACE_SWITCH_MM 55 - -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -Nru a/arch/um/kernel/skas/include/uaccess.h b/arch/um/kernel/skas/include/uaccess.h --- a/arch/um/kernel/skas/include/uaccess.h Sun Feb 9 21:13:31 2003 +++ b/arch/um/kernel/skas/include/uaccess.h Sun Feb 9 21:13:31 2003 @@ -27,9 +27,6 @@ return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); } -extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt, - pte_t *pte_out); - static inline unsigned long maybe_map(unsigned long virt, int is_write) { pte_t pte; diff -Nru a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c --- a/arch/um/kernel/skas/mem.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/kernel/skas/mem.c Sun Feb 9 21:13:35 2003 @@ -18,11 +18,6 @@ return(((unsigned long) set_task_sizes_skas) & ~0xffffff); } -struct page *arch_validate_skas(struct page *page, int mask, int order) -{ - return(page); -} - /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff -Nru a/arch/um/kernel/skas/mem_user.c b/arch/um/kernel/skas/mem_user.c --- a/arch/um/kernel/skas/mem_user.c Sun Feb 9 21:13:30 2003 +++ b/arch/um/kernel/skas/mem_user.c Sun Feb 9 21:13:30 2003 @@ -33,7 +33,7 @@ .fd = region->fd, .offset = phys_offset(phys) } } } ); - n = os_write_file(fd, (char *) &map, sizeof(map)); + n = os_write_file(fd, &map, sizeof(map)); if(n != sizeof(map)) printk("map : /proc/mm map failed, errno = %d\n", errno); } @@ -48,7 +48,7 @@ { .munmap = { .addr = (unsigned long) addr, .len = len } } } ); - n = os_write_file(fd, (char *) &unmap, sizeof(unmap)); + n = os_write_file(fd, &unmap, sizeof(unmap)); if((n != 0) && (n != sizeof(unmap))) return(-errno); return(0); @@ -70,7 +70,7 @@ .len = len, .prot = prot } } } ); - n = os_write_file(fd, (char *) &protect, sizeof(protect)); + n = os_write_file(fd, &protect, sizeof(protect)); if((n != 0) && (n != sizeof(protect))){ if(must_succeed) panic("protect failed, errno = %d", errno); diff -Nru a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c --- a/arch/um/kernel/skas/process.c Sun Feb 9 21:13:36 2003 +++ b/arch/um/kernel/skas/process.c Sun Feb 9 21:13:36 2003 @@ -20,10 +20,10 @@ #include "user_util.h" #include "kern_util.h" #include "skas.h" -#include "skas_ptrace.h" #include "sysdep/sigcontext.h" #include "os.h" #include "proc_mm.h" +#include "skas_ptrace.h" unsigned long exec_regs[FRAME_SIZE]; unsigned long exec_fp_regs[HOST_FP_SIZE]; @@ -39,14 +39,15 @@ if(err) panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n", errno); + segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL); } -static void handle_trap(int pid, struct uml_pt_regs *regs) +static void handle_trap(int pid, union uml_pt_regs *regs) { int err, syscall_nr, status; - syscall_nr = PT_SYSCALL_NR(regs->mode.skas.regs); + syscall_nr = PT_SYSCALL_NR(regs->skas.regs); if(syscall_nr < 1){ relay_signal(SIGTRAP, regs); return; @@ -79,6 +80,7 @@ enable_timer(); ptrace(PTRACE_TRACEME, 0, 0, 0); os_stop_process(os_getpid()); + return(0); } void start_userspace(void) @@ -115,7 +117,7 @@ userspace_pid = pid; } -void userspace(struct uml_pt_regs *regs) +void userspace(union uml_pt_regs *regs) { int err, status, op; @@ -131,7 +133,7 @@ panic("userspace - waitpid failed, errno = %d\n", errno); - regs->is_user = 1; + regs->skas.is_user = 1; save_registers(regs); if(WIFSTOPPED(status)){ @@ -191,28 +193,28 @@ longjmp(*fork_buf, 1); } -static int move_registers(int int_op, int fp_op, struct uml_pt_regs *regs, +static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs, unsigned long *fp_regs) { - if(ptrace(int_op, userspace_pid, 0, regs->mode.skas.regs) < 0) + if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0) return(-errno); if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0) return(-errno); return(0); } -void save_registers(struct uml_pt_regs *regs) +void save_registers(union uml_pt_regs *regs) { unsigned long *fp_regs; int err, fp_op; if(have_fpx_regs){ fp_op = PTRACE_GETFPXREGS; - fp_regs = regs->mode.skas.xfp; + fp_regs = regs->skas.xfp; } else { fp_op = PTRACE_GETFPREGS; - fp_regs = regs->mode.skas.fp; + fp_regs = regs->skas.fp; } err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs); @@ -221,18 +223,18 @@ err); } -void restore_registers(struct uml_pt_regs *regs) +void restore_registers(union uml_pt_regs *regs) { unsigned long *fp_regs; int err, fp_op; if(have_fpx_regs){ fp_op = PTRACE_SETFPXREGS; - fp_regs = regs->mode.skas.xfp; + fp_regs = regs->skas.xfp; } else { fp_op = PTRACE_SETFPREGS; - fp_regs = regs->mode.skas.fp; + fp_regs = regs->skas.fp; } err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs); @@ -272,10 +274,14 @@ (*cb_proc)(cb_arg); longjmp(*cb_back, 1); } - else if(n == 3) + else if(n == 3){ + kmalloc_ok = 0; return(0); - else if(n == 4) + } + else if(n == 4){ + kmalloc_ok = 0; return(1); + } longjmp(**switch_buf, 1); } @@ -296,8 +302,11 @@ cb_proc = proc; cb_arg = arg; cb_back = &here; + + block_signals(); if(setjmp(here) == 0) longjmp(initial_jmpbuf, 2); + unblock_signals(); cb_proc = NULL; cb_arg = NULL; @@ -328,7 +337,7 @@ copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS, .u = { .copy_segments = from } } ); - n = os_write_file(fd, (char *) ©, sizeof(copy)); + n = os_write_file(fd, ©, sizeof(copy)); if(n != sizeof(copy)) printk("new_mm : /proc/mm copy_segments failed, " "errno = %d\n", errno); diff -Nru a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c --- a/arch/um/kernel/skas/process_kern.c Sun Feb 9 21:13:30 2003 +++ b/arch/um/kernel/skas/process_kern.c Sun Feb 9 21:13:30 2003 @@ -68,8 +68,7 @@ n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); if(n == 1) userspace(¤t->thread.regs.regs); - else if(n == 2) - do_exit(0); + else do_exit(0); } void new_thread_proc(void *stack, void (*handler)(int sig)) @@ -109,21 +108,21 @@ void (*handler)(int); if(current->thread.forking){ - memcpy(&p->thread.regs.regs.mode.skas, - ¤t->thread.regs.regs.mode.skas, - sizeof(p->thread.regs.regs.mode.skas)); - REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.mode.skas.regs, 0); - if(sp != 0) REGS_SP(p->thread.regs.regs.mode.skas.regs) = sp; + memcpy(&p->thread.regs.regs.skas, + ¤t->thread.regs.regs.skas, + sizeof(p->thread.regs.regs.skas)); + REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0); + if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp; handler = fork_handler; } else { - memcpy(p->thread.regs.regs.mode.skas.regs, exec_regs, - sizeof(p->thread.regs.regs.mode.skas.regs)); - memcpy(p->thread.regs.regs.mode.skas.fp, exec_fp_regs, - sizeof(p->thread.regs.regs.mode.skas.fp)); - memcpy(p->thread.regs.regs.mode.skas.xfp, exec_fpx_regs, - sizeof(p->thread.regs.regs.mode.skas.xfp)); + memcpy(p->thread.regs.regs.skas.regs, exec_regs, + sizeof(p->thread.regs.regs.skas.regs)); + memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs, + sizeof(p->thread.regs.regs.skas.fp)); + memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs, + sizeof(p->thread.regs.regs.skas.xfp)); p->thread.request.u.thread = current->thread.request.u.thread; handler = new_thread_handler; } diff -Nru a/arch/um/kernel/skas/sys-i386/sigcontext.c b/arch/um/kernel/skas/sys-i386/sigcontext.c --- a/arch/um/kernel/skas/sys-i386/sigcontext.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/kernel/skas/sys-i386/sigcontext.c Sun Feb 9 21:13:28 2003 @@ -15,7 +15,7 @@ extern int userspace_pid; -int copy_sc_from_user_skas(struct uml_pt_regs *regs, void *from_ptr) +int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr) { struct sigcontext sc, *from = from_ptr; unsigned long fpregs[FP_FRAME_SIZE]; @@ -26,26 +26,26 @@ if(err) return(err); - regs->mode.skas.regs[GS] = sc.gs; - regs->mode.skas.regs[FS] = sc.fs; - regs->mode.skas.regs[ES] = sc.es; - regs->mode.skas.regs[DS] = sc.ds; - regs->mode.skas.regs[EDI] = sc.edi; - regs->mode.skas.regs[ESI] = sc.esi; - regs->mode.skas.regs[EBP] = sc.ebp; - regs->mode.skas.regs[UESP] = sc.esp; - regs->mode.skas.regs[EBX] = sc.ebx; - regs->mode.skas.regs[EDX] = sc.edx; - regs->mode.skas.regs[ECX] = sc.ecx; - regs->mode.skas.regs[EAX] = sc.eax; - regs->mode.skas.regs[EIP] = sc.eip; - regs->mode.skas.regs[CS] = sc.cs; - regs->mode.skas.regs[EFL] = sc.eflags; - regs->mode.skas.regs[UESP] = sc.esp_at_signal; - regs->mode.skas.regs[SS] = sc.ss; - regs->mode.skas.fault_addr = sc.cr2; - regs->mode.skas.fault_type = FAULT_WRITE(sc.err); - regs->mode.skas.trap_type = sc.trapno; + regs->skas.regs[GS] = sc.gs; + regs->skas.regs[FS] = sc.fs; + regs->skas.regs[ES] = sc.es; + regs->skas.regs[DS] = sc.ds; + regs->skas.regs[EDI] = sc.edi; + regs->skas.regs[ESI] = sc.esi; + regs->skas.regs[EBP] = sc.ebp; + regs->skas.regs[UESP] = sc.esp; + regs->skas.regs[EBX] = sc.ebx; + regs->skas.regs[EDX] = sc.edx; + regs->skas.regs[ECX] = sc.ecx; + regs->skas.regs[EAX] = sc.eax; + regs->skas.regs[EIP] = sc.eip; + regs->skas.regs[CS] = sc.cs; + regs->skas.regs[EFL] = sc.eflags; + regs->skas.regs[UESP] = sc.esp_at_signal; + regs->skas.regs[SS] = sc.ss; + regs->skas.fault_addr = sc.cr2; + regs->skas.fault_type = FAULT_WRITE(sc.err); + regs->skas.trap_type = sc.trapno; err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs); if(err < 0){ @@ -57,7 +57,7 @@ return(0); } -int copy_sc_to_user_skas(void *to_ptr, struct uml_pt_regs *regs, +int copy_sc_to_user_skas(void *to_ptr, void *fp, union uml_pt_regs *regs, unsigned long fault_addr, int fault_type) { struct sigcontext sc, *to = to_ptr; @@ -65,26 +65,26 @@ unsigned long fpregs[FP_FRAME_SIZE]; int err; - sc.gs = regs->mode.skas.regs[GS]; - sc.fs = regs->mode.skas.regs[FS]; - sc.es = regs->mode.skas.regs[ES]; - sc.ds = regs->mode.skas.regs[DS]; - sc.edi = regs->mode.skas.regs[EDI]; - sc.esi = regs->mode.skas.regs[ESI]; - sc.ebp = regs->mode.skas.regs[EBP]; - sc.esp = regs->mode.skas.regs[UESP]; - sc.ebx = regs->mode.skas.regs[EBX]; - sc.edx = regs->mode.skas.regs[EDX]; - sc.ecx = regs->mode.skas.regs[ECX]; - sc.eax = regs->mode.skas.regs[EAX]; - sc.eip = regs->mode.skas.regs[EIP]; - sc.cs = regs->mode.skas.regs[CS]; - sc.eflags = regs->mode.skas.regs[EFL]; - sc.esp_at_signal = regs->mode.skas.regs[UESP]; - sc.ss = regs->mode.skas.regs[SS]; + sc.gs = regs->skas.regs[GS]; + sc.fs = regs->skas.regs[FS]; + sc.es = regs->skas.regs[ES]; + sc.ds = regs->skas.regs[DS]; + sc.edi = regs->skas.regs[EDI]; + sc.esi = regs->skas.regs[ESI]; + sc.ebp = regs->skas.regs[EBP]; + sc.esp = regs->skas.regs[UESP]; + sc.ebx = regs->skas.regs[EBX]; + sc.edx = regs->skas.regs[EDX]; + sc.ecx = regs->skas.regs[ECX]; + sc.eax = regs->skas.regs[EAX]; + sc.eip = regs->skas.regs[EIP]; + sc.cs = regs->skas.regs[CS]; + sc.eflags = regs->skas.regs[EFL]; + sc.esp_at_signal = regs->skas.regs[UESP]; + sc.ss = regs->skas.regs[SS]; sc.cr2 = fault_addr; sc.err = TO_SC_ERR(fault_type); - sc.trapno = regs->mode.skas.trap_type; + sc.trapno = regs->skas.trap_type; err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs); if(err < 0){ @@ -92,7 +92,8 @@ "errno = %d\n", errno); return(1); } - to_fp = (struct _fpstate *)((unsigned long) to + sizeof(*to)); + to_fp = (struct _fpstate *) + (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to))); sc.fpstate = to_fp; if(err) diff -Nru a/arch/um/kernel/skas/syscall_kern.c b/arch/um/kernel/skas/syscall_kern.c --- a/arch/um/kernel/skas/syscall_kern.c Sun Feb 9 21:13:33 2003 +++ b/arch/um/kernel/skas/syscall_kern.c Sun Feb 9 21:13:33 2003 @@ -21,7 +21,7 @@ current->thread.nsyscalls++; nsyscalls++; - syscall = regs->regs.syscall; + syscall = UPT_SYSCALL_NR(®s->regs); if((syscall >= NR_syscalls) || (syscall < 0)) res = -ENOSYS; diff -Nru a/arch/um/kernel/skas/syscall_user.c b/arch/um/kernel/skas/syscall_user.c --- a/arch/um/kernel/skas/syscall_user.c Sun Feb 9 21:13:36 2003 +++ b/arch/um/kernel/skas/syscall_user.c Sun Feb 9 21:13:36 2003 @@ -15,18 +15,17 @@ #define ERESTARTNOINTR 513 #define ERESTARTNOHAND 514 -void handle_syscall(struct uml_pt_regs *regs) +void handle_syscall(union uml_pt_regs *regs) { long result; int index; - host_to_regs(regs); index = record_syscall_start(UPT_SYSCALL_NR(regs)); syscall_trace(); result = execute_syscall(regs); - REGS_SET_SYSCALL_RETURN(regs->mode.skas.regs, result); + REGS_SET_SYSCALL_RETURN(regs->skas.regs, result); if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || (result == -ERESTARTNOINTR)) do_signal(result); diff -Nru a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c --- a/arch/um/kernel/skas/tlb.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/kernel/skas/tlb.c Sun Feb 9 21:13:32 2003 @@ -67,7 +67,7 @@ } } -static void flush_kernel_vm_range(unsigned long start, unsigned long end) +void flush_tlb_kernel_range_skas(unsigned long start, unsigned long end) { struct mm_struct *mm; pgd_t *pgd; @@ -99,7 +99,6 @@ protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1); } addr += PAGE_SIZE; - } else { if(pmd_newpage(*pmd)){ @@ -116,27 +115,26 @@ void flush_tlb_kernel_vm_skas(void) { - flush_kernel_vm_range(start_vm, end_vm); + flush_tlb_kernel_range_skas(start_vm, end_vm); } void __flush_tlb_one_skas(unsigned long addr) { - flush_kernel_vm_range(addr, addr + PAGE_SIZE); + flush_tlb_kernel_range_skas(addr, addr + PAGE_SIZE); } void flush_tlb_range_skas(struct vm_area_struct *vma, unsigned long start, unsigned long end) { if(vma->vm_mm == NULL) - flush_kernel_vm_range(start, end); + flush_tlb_kernel_range_skas(start, end); else fix_range(vma->vm_mm, start, end, 0); } void flush_tlb_mm_skas(struct mm_struct *mm) { - if(mm == NULL) - flush_tlb_kernel_vm_skas(); - else fix_range(mm, 0, host_task_size, 0); + flush_tlb_kernel_vm_skas(); + fix_range(mm, 0, host_task_size, 0); } void force_flush_all_skas(void) diff -Nru a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c --- a/arch/um/kernel/skas/trap_user.c Sun Feb 9 21:13:31 2003 +++ b/arch/um/kernel/skas/trap_user.c Sun Feb 9 21:13:31 2003 @@ -13,41 +13,40 @@ #include "task.h" #include "sigcontext.h" -void sig_handler_common_skas(int sig, struct sigcontext *sc) +void sig_handler_common_skas(int sig, void *sc_ptr) { - struct uml_pt_regs save_regs, *r; + struct sigcontext *sc = sc_ptr; + struct skas_regs *r; struct signal_info *info; int save_errno = errno; - r = (struct uml_pt_regs *) TASK_REGS(get_current()); - save_regs = *r; + r = &TASK_REGS(get_current())->skas; r->is_user = 0; - r->mode.skas.fault_addr = SC_FAULT_ADDR(sc); - r->mode.skas.fault_type = SC_FAULT_TYPE(sc); - r->mode.skas.trap_type = SC_TRAP_TYPE(sc); + r->fault_addr = SC_FAULT_ADDR(sc); + r->fault_type = SC_FAULT_TYPE(sc); + r->trap_type = SC_TRAP_TYPE(sc); change_sig(SIGUSR1, 1); info = &sig_info[sig]; if(!info->is_irq) unblock_signals(); - (*info->handler)(sig, r); + (*info->handler)(sig, (union uml_pt_regs *) r); - *r = save_regs; errno = save_errno; } extern int missed_ticks[]; -void user_signal(int sig, struct uml_pt_regs *regs) +void user_signal(int sig, union uml_pt_regs *regs) { struct signal_info *info; if(sig == SIGVTALRM) missed_ticks[cpu()]++; - regs->is_user = 1; - regs->mode.skas.fault_addr = 0; - regs->mode.skas.fault_type = 0; - regs->mode.skas.trap_type = 0; + regs->skas.is_user = 1; + regs->skas.fault_addr = 0; + regs->skas.fault_type = 0; + regs->skas.trap_type = 0; info = &sig_info[sig]; (*info->handler)(sig, regs); diff -Nru a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c --- a/arch/um/kernel/smp.c Sun Feb 9 21:13:29 2003 +++ b/arch/um/kernel/smp.c Sun Feb 9 21:13:29 2003 @@ -13,6 +13,7 @@ #include "linux/sched.h" #include "linux/threads.h" #include "linux/interrupt.h" +#include "linux/err.h" #include "asm/smp.h" #include "asm/processor.h" #include "asm/spinlock.h" @@ -140,7 +141,7 @@ current->thread.request.u.thread.proc = idle_proc; current->thread.request.u.thread.arg = (void *) cpu; - new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL); + new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL); if(IS_ERR(new_task)) panic("do_fork failed in idle_thread"); cpu_tasks[cpu] = ((struct cpu_task) @@ -186,7 +187,7 @@ } } -void __devinit smp_prepare_boot_cpu(void) +void smp_prepare_boot_cpu(void) { set_bit(smp_processor_id(), &cpu_online_map); } diff -Nru a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c --- a/arch/um/kernel/sys_call_table.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/kernel/sys_call_table.c Sun Feb 9 21:13:35 2003 @@ -481,8 +481,6 @@ [ __NR_io_getevents ] = sys_io_getevents, [ __NR_io_submit ] = sys_io_submit, [ __NR_io_cancel ] = sys_io_cancel, - [ __NR_alloc_hugepages ] = sys_ni_syscall, - [ __NR_free_hugepages ] = sys_ni_syscall, [ __NR_exit_group ] = sys_exit_group, [ __NR_lookup_dcookie ] = sys_lookup_dcookie, [ __NR_epoll_create ] = sys_epoll_create, diff -Nru a/arch/um/kernel/tempfile.c b/arch/um/kernel/tempfile.c --- a/arch/um/kernel/tempfile.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/kernel/tempfile.c Sun Feb 9 21:13:32 2003 @@ -23,20 +23,19 @@ if(tempdir != NULL) return; /* We've already been called */ for(i = 0; dirs[i]; i++){ dir = getenv(dirs[i]); - if(dir != NULL) break; + if((dir != NULL) && (*dir != '\0')) + break; } - if(dir == NULL) dir = "/tmp"; - else if(*dir == '\0') dir = NULL; - if(dir != NULL) { - tempdir = malloc(strlen(dir) + 2); - if(tempdir == NULL){ - fprintf(stderr, "Failed to malloc tempdir, " - "errno = %d\n", errno); - return; - } - strcpy(tempdir, dir); - strcat(tempdir, "/"); + if((dir == NULL) || (*dir == '\0')) + dir = "/tmp"; + tempdir = malloc(strlen(dir) + 2); + if(tempdir == NULL){ + fprintf(stderr, "Failed to malloc tempdir, " + "errno = %d\n", errno); + return; } + strcpy(tempdir, dir); + strcat(tempdir, "/"); } int make_tempfile(const char *template, char **out_tempname, int do_unlink) diff -Nru a/arch/um/kernel/time.c b/arch/um/kernel/time.c --- a/arch/um/kernel/time.c Sun Feb 9 21:13:29 2003 +++ b/arch/um/kernel/time.c Sun Feb 9 21:13:29 2003 @@ -86,20 +86,23 @@ void do_gettimeofday(struct timeval *tv) { - time_lock(); + unsigned long flags; + + flags = time_lock(); gettimeofday(tv, NULL); timeradd(tv, &local_offset, tv); - time_unlock(); + time_unlock(flags); } void do_settimeofday(struct timeval *tv) { struct timeval now; + unsigned long flags; - time_lock(); + flags = time_lock(); gettimeofday(&now, NULL); timersub(tv, &now, &local_offset); - time_unlock(); + time_unlock(flags); } void idle_sleep(int secs) @@ -108,7 +111,7 @@ ts.tv_sec = secs; ts.tv_nsec = 0; - nanosleep(&ts, &ts); + nanosleep(&ts, NULL); } /* diff -Nru a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c --- a/arch/um/kernel/time_kern.c Sun Feb 9 21:13:33 2003 +++ b/arch/um/kernel/time_kern.c Sun Feb 9 21:13:33 2003 @@ -7,6 +7,7 @@ #include "linux/unistd.h" #include "linux/stddef.h" #include "linux/spinlock.h" +#include "linux/time.h" #include "linux/sched.h" #include "linux/interrupt.h" #include "linux/init.h" @@ -21,8 +22,6 @@ u64 jiffies_64; -extern rwlock_t xtime_lock; - int hz(void) { return(HZ); @@ -37,7 +36,7 @@ */ int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS]; -void timer_irq(struct uml_pt_regs *regs) +void timer_irq(union uml_pt_regs *regs) { int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu]; @@ -50,16 +49,18 @@ { struct pt_regs regs; - regs.regs.is_user = 0; + CHOOSE_MODE((void) + (UPT_SC(®s.regs) = (struct sigcontext *) (&sig + 1)), + (void) (regs.regs.skas.is_user = 0)); do_timer(®s); } void um_timer(int irq, void *dev, struct pt_regs *regs) { do_timer(regs); - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); timer(); - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } long um_time(int * tloc) @@ -118,7 +119,7 @@ for(i=0;imm); } +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt, + flush_tlb_kernel_range_skas, start, end); +} + void flush_tlb_kernel_vm(void) { CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas()); diff -Nru a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c --- a/arch/um/kernel/trap_kern.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/kernel/trap_kern.c Sun Feb 9 21:13:28 2003 @@ -109,7 +109,8 @@ flush_tlb_kernel_vm(); return(0); } - if(current->mm == NULL) panic("Segfault with no mm"); + if(current->mm == NULL) + panic("Segfault with no mm"); err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); catcher = current->thread.fault_catcher; @@ -164,14 +165,15 @@ force_sig_info(SIGSEGV, &si, current); } -void relay_signal(int sig, struct uml_pt_regs *regs) +void relay_signal(int sig, union uml_pt_regs *regs) { if(arch_handle_signal(sig, regs)) return; - if(!regs->is_user) panic("Kernel mode signal %d", sig); + if(!UPT_IS_USER(regs)) + panic("Kernel mode signal %d", sig); force_sig(sig, current); } -void bus_handler(int sig, struct uml_pt_regs *regs) +void bus_handler(int sig, union uml_pt_regs *regs) { if(current->thread.fault_catcher != NULL) do_longjmp(current->thread.fault_catcher, 1); diff -Nru a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c --- a/arch/um/kernel/trap_user.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/kernel/trap_user.c Sun Feb 9 21:13:32 2003 @@ -48,11 +48,11 @@ int is_user; } segfault_record[1024]; -void segv_handler(int sig, struct uml_pt_regs *regs) +void segv_handler(int sig, union uml_pt_regs *regs) { int index, max; - if(regs->is_user && !UPT_SEGV_IS_FIXABLE(regs)){ + if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){ bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs)); return; @@ -65,35 +65,35 @@ segfault_record[index].pid = os_getpid(); segfault_record[index].is_write = UPT_FAULT_WRITE(regs); segfault_record[index].sp = UPT_SP(regs); - segfault_record[index].is_user = regs->is_user; + segfault_record[index].is_user = UPT_IS_USER(regs); segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs), - regs->is_user, regs); + UPT_IS_USER(regs), regs); } -void usr2_handler(int sig, struct uml_pt_regs *regs) +void usr2_handler(int sig, union uml_pt_regs *regs) { CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0); } struct signal_info sig_info[] = { - [ SIGTRAP ] { handler : relay_signal, - is_irq : 0 }, - [ SIGFPE ] { handler : relay_signal, - is_irq : 0 }, - [ SIGILL ] { handler : relay_signal, - is_irq : 0 }, - [ SIGBUS ] { handler : bus_handler, - is_irq : 0 }, - [ SIGSEGV] { handler : segv_handler, - is_irq : 0 }, - [ SIGIO ] { handler : sigio_handler, - is_irq : 1 }, - [ SIGVTALRM ] { handler : timer_handler, - is_irq : 1 }, - [ SIGALRM ] { handler : timer_handler, - is_irq : 1 }, - [ SIGUSR2 ] { handler : usr2_handler, - is_irq : 0 }, + [ SIGTRAP ] { .handler = relay_signal, + .is_irq = 0 }, + [ SIGFPE ] { .handler = relay_signal, + .is_irq = 0 }, + [ SIGILL ] { .handler = relay_signal, + .is_irq = 0 }, + [ SIGBUS ] { .handler = bus_handler, + .is_irq = 0 }, + [ SIGSEGV] { .handler = segv_handler, + .is_irq = 0 }, + [ SIGIO ] { .handler = sigio_handler, + .is_irq = 1 }, + [ SIGVTALRM ] { .handler = timer_handler, + .is_irq = 1 }, + [ SIGALRM ] { .handler = timer_handler, + .is_irq = 1 }, + [ SIGUSR2 ] { .handler = usr2_handler, + .is_irq = 0 }, }; void sig_handler(int sig, struct sigcontext sc) diff -Nru a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile --- a/arch/um/kernel/tt/Makefile Sun Feb 9 21:13:32 2003 +++ b/arch/um/kernel/tt/Makefile Sun Feb 9 21:13:32 2003 @@ -3,18 +3,29 @@ # Licensed under the GPL # -obj-y = exec_kern.o exec_user.o gdb.o gdb_kern.o ksyms.o mem.o process_kern.o \ +EXTRA_TARGETS := unmap_fin.o + +obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \ uaccess_user.o sys-$(SUBARCH)/ -obj-$(CONFIG_PT_PROXY) += ptproxy/ - -export-objs = ksyms.o +obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/ USER_OBJS := $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) +UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS)) +UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS)) + $(USER_OBJS) : %.o: %.c $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< + +$(O_TARGET) : $(obj)/unmap_fin.o + +$(obj)/unmap.o: $(src)/unmap.c + $(CC) $(UNMAP_CFLAGS) -c -o $@ $< + +$(obj)/unmap_fin.o : $(src)/unmap.o + ld -r -o $@ $< -lc -L/usr/lib clean : diff -Nru a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c --- a/arch/um/kernel/tt/gdb.c Sun Feb 9 21:13:29 2003 +++ b/arch/um/kernel/tt/gdb.c Sun Feb 9 21:13:29 2003 @@ -44,7 +44,7 @@ return(ptrace(PTRACE_CONT, pid, 0, 0)); } -#ifdef CONFIG_PT_PROXY +#ifdef UML_CONFIG_PT_PROXY int debugger_signal(int status, pid_t pid) { @@ -62,11 +62,11 @@ } static struct chan_opts opts = { - announce : gdb_announce, - xterm_title : "UML kernel debugger", - raw : 0, - tramp_stack : 0, - in_kernel : 0, + .announce = gdb_announce, + .xterm_title = "UML kernel debugger", + .raw = 0, + .tramp_stack = 0, + .in_kernel = 0, }; /* Accessed by the tracing thread, which automatically serializes access */ @@ -74,16 +74,16 @@ static int xterm_fd; extern void *xterm_init(char *, int, struct chan_opts *); -extern int xterm_open(int, int, int, void *); +extern int xterm_open(int, int, int, void *, char **); extern void xterm_close(int, void *); int open_gdb_chan(void) { - char stack[UM_KERN_PAGE_SIZE]; + char stack[UM_KERN_PAGE_SIZE], *dummy; opts.tramp_stack = (unsigned long) stack; xterm_data = xterm_init("", 0, &opts); - xterm_fd = xterm_open(1, 1, 1, xterm_data); + xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy); return(xterm_fd); } diff -Nru a/arch/um/kernel/tt/gdb_kern.c b/arch/um/kernel/tt/gdb_kern.c --- a/arch/um/kernel/tt/gdb_kern.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/kernel/tt/gdb_kern.c Sun Feb 9 21:13:35 2003 @@ -13,9 +13,9 @@ extern int gdb_remove(char *unused); static struct mc_device gdb_mc = { - name: "gdb", - config: gdb_config, - remove: gdb_remove, + .name = "gdb", + .config = gdb_config, + .remove = gdb_remove, }; int gdb_mc_init(void) diff -Nru a/arch/um/kernel/tt/include/mode.h b/arch/um/kernel/tt/include/mode.h --- a/arch/um/kernel/tt/include/mode.h Sun Feb 9 21:13:33 2003 +++ b/arch/um/kernel/tt/include/mode.h Sun Feb 9 21:13:33 2003 @@ -13,9 +13,10 @@ extern int tracer(int (*init_proc)(void *), void *sp); extern void user_time_init_tt(void); extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data); -extern int copy_sc_to_user_tt(void *to_ptr, void *from_ptr, void *data); -extern void sig_handler_common_tt(int sig, struct sigcontext *sc); -extern void syscall_handler_tt(int sig, struct uml_pt_regs *regs); +extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, + void *data); +extern void sig_handler_common_tt(int sig, void *sc); +extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); extern void reboot_tt(void); extern void halt_tt(void); extern int is_tracer_winch(int pid, int fd, void *data); diff -Nru a/arch/um/kernel/tt/include/mode_kern.h b/arch/um/kernel/tt/include/mode_kern.h --- a/arch/um/kernel/tt/include/mode_kern.h Sun Feb 9 21:13:30 2003 +++ b/arch/um/kernel/tt/include/mode_kern.h Sun Feb 9 21:13:30 2003 @@ -22,6 +22,7 @@ extern void exit_thread_tt(void); extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); extern void init_idle_tt(void); +extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); extern void flush_tlb_kernel_vm_tt(void); extern void __flush_tlb_one_tt(unsigned long addr); extern void flush_tlb_range_tt(struct vm_area_struct *vma, @@ -33,7 +34,6 @@ extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, unsigned long *task_size_out); extern int start_uml_tt(void); -extern struct page *arch_validate_tt(struct page *page, int mask, int order); extern int external_pid_tt(struct task_struct *task); extern int thread_pid_tt(struct task_struct *task); diff -Nru a/arch/um/kernel/tt/include/ptrace-tt.h b/arch/um/kernel/tt/include/ptrace-tt.h --- a/arch/um/kernel/tt/include/ptrace-tt.h Sun Feb 9 21:13:36 2003 +++ b/arch/um/kernel/tt/include/ptrace-tt.h Sun Feb 9 21:13:36 2003 @@ -8,7 +8,7 @@ #include "uml-config.h" -#ifdef CONFIG_MODE_TT +#ifdef UML_CONFIG_MODE_TT #include "sysdep/sc.h" #endif diff -Nru a/arch/um/kernel/tt/include/tt.h b/arch/um/kernel/tt/include/tt.h --- a/arch/um/kernel/tt/include/tt.h Sun Feb 9 21:13:28 2003 +++ b/arch/um/kernel/tt/include/tt.h Sun Feb 9 21:13:28 2003 @@ -26,10 +26,11 @@ extern int is_tracing(void *task); extern int singlestepping_tt(void *t); extern void clear_singlestep(void *t); -extern void syscall_handler(int sig, struct uml_pt_regs *regs); +extern void syscall_handler(int sig, union uml_pt_regs *regs); extern void exit_kernel(int pid, void *task); extern int do_syscall(void *task, int pid); extern int is_valid_pid(int pid); +extern void remap_data(void *segment_start, void *segment_end, int w); #endif diff -Nru a/arch/um/kernel/tt/include/uaccess.h b/arch/um/kernel/tt/include/uaccess.h --- a/arch/um/kernel/tt/include/uaccess.h Sun Feb 9 21:13:33 2003 +++ b/arch/um/kernel/tt/include/uaccess.h Sun Feb 9 21:13:33 2003 @@ -12,6 +12,7 @@ #include "asm/errno.h" #include "asm/current.h" #include "asm/a.out.h" +#include "uml_uaccess.h" #define ABOVE_KMEM (16 * 1024 * 1024) @@ -50,9 +51,6 @@ ¤t->thread.fault_addr, ¤t->thread.fault_catcher) : n); } - -extern int __do_copy_to_user(void *to, const void *from, int n, - void **fault_addr, void **fault_catcher); static inline int copy_to_user_tt(void *to, const void *from, int n) { diff -Nru a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c --- a/arch/um/kernel/tt/mem.c Sun Feb 9 21:13:31 2003 +++ b/arch/um/kernel/tt/mem.c Sun Feb 9 21:13:31 2003 @@ -39,32 +39,6 @@ return(START); } -struct page *arch_validate_tt(struct page *page, int mask, int order) -{ - unsigned long addr, zero = 0; - int i; - - again: - if(page == NULL) return(page); - if(PageHighMem(page)) return(page); - - addr = (unsigned long) page_address(page); - for(i = 0; i < (1 << order); i++){ - current->thread.fault_addr = (void *) addr; - if(__do_copy_to_user((void *) addr, &zero, - sizeof(zero), - ¤t->thread.fault_addr, - ¤t->thread.fault_catcher)){ - if(!(mask & __GFP_WAIT)) return(NULL); - else break; - } - addr += PAGE_SIZE; - } - if(i == (1 << order)) return(page); - page = alloc_pages(mask, order); - goto again; -} - /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff -Nru a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/um/kernel/tt/mem_user.c Sun Feb 9 21:13:37 2003 @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include +#include +#include "tt.h" +#include "mem_user.h" +#include "user_util.h" + +void remap_data(void *segment_start, void *segment_end, int w) +{ + void *addr; + unsigned long size; + int data, prot; + + if(w) prot = PROT_WRITE; + else prot = 0; + prot |= PROT_READ | PROT_EXEC; + size = (unsigned long) segment_end - + (unsigned long) segment_start; + data = create_mem_file(size); + if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ, + MAP_SHARED, data, 0)) == MAP_FAILED){ + perror("mapping new data segment"); + exit(1); + } + memcpy(addr, segment_start, size); + if(switcheroo(data, prot, addr, segment_start, + size) < 0){ + printf("switcheroo failed\n"); + exit(1); + } +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -Nru a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c --- a/arch/um/kernel/tt/process_kern.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/kernel/tt/process_kern.c Sun Feb 9 21:13:35 2003 @@ -6,6 +6,7 @@ #include "linux/sched.h" #include "linux/signal.h" #include "linux/kernel.h" +#include "linux/interrupt.h" #include "asm/system.h" #include "asm/pgalloc.h" #include "asm/ptrace.h" @@ -111,7 +112,7 @@ close(current->thread.mode.tt.switch_pipe[1]); } -extern void schedule_tail(struct task_struct *prev); +void schedule_tail(task_t *prev); static void new_thread_handler(int sig) { @@ -120,13 +121,13 @@ fn = current->thread.request.u.thread.proc; arg = current->thread.request.u.thread.arg; - current->thread.regs.regs.mode.tt = (void *) (&sig + 1); + UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1); suspend_new_thread(current->thread.mode.tt.switch_pipe[0]); block_signals(); init_new_thread_signals(1); #ifdef CONFIG_SMP - schedule_tail(NULL); + schedule_tail(current->thread.prev_sched); #endif enable_timer(); free_page(current->thread.temp_stack); @@ -160,7 +161,7 @@ void finish_fork_handler(int sig) { - current->thread.regs.regs.mode.tt = (void *) (&sig + 1); + UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1); suspend_new_thread(current->thread.mode.tt.switch_pipe[0]); #ifdef CONFIG_SMP @@ -168,6 +169,7 @@ #endif enable_timer(); change_sig(SIGVTALRM, 1); + local_irq_enable(); force_flush_all(); if(current->mm != current->parent->mm) protect_memory(uml_reserved, high_physmem - uml_reserved, 1, @@ -187,6 +189,7 @@ { int sig = sigusr1; + local_irq_disable(); init_new_thread_stack(stack, finish_fork_handler); kill(os_getpid(), sig); @@ -232,10 +235,10 @@ } if(current->thread.forking){ - sc_to_sc(p->thread.regs.regs.mode.tt, - current->thread.regs.regs.mode.tt); - SC_SET_SYSCALL_RETURN(p->thread.regs.regs.mode.tt, 0); - if(sp != 0) SC_SP(p->thread.regs.regs.mode.tt) = sp; + sc_to_sc(UPT_SC(&p->thread.regs.regs), + UPT_SC(¤t->thread.regs.regs)); + SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0); + if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp; } p->thread.mode.tt.extern_pid = new_pid; @@ -367,11 +370,14 @@ static void mprotect_kernel_mem(int w) { unsigned long start, end; + int pages; if(!jail || (current == &init_task)) return; + pages = (1 << CONFIG_KERNEL_STACK_ORDER); + start = (unsigned long) current->thread_info + PAGE_SIZE; - end = (unsigned long) current->thread_info + PAGE_SIZE * 4; + end = (unsigned long) current + PAGE_SIZE * pages; protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1); protect_memory(end, high_physmem - end, 1, w, 1, 1); @@ -470,8 +476,10 @@ int start_uml_tt(void) { void *sp; + int pages; - sp = (void *) init_task.thread.kernel_stack + 2 * PAGE_SIZE - + pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2; + sp = (void *) init_task.thread.kernel_stack + pages * PAGE_SIZE - sizeof(unsigned long); return(tracer(start_kernel_proc, sp)); } diff -Nru a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c --- a/arch/um/kernel/tt/ptproxy/proxy.c Sun Feb 9 21:13:33 2003 +++ b/arch/um/kernel/tt/ptproxy/proxy.c Sun Feb 9 21:13:33 2003 @@ -129,14 +129,14 @@ int init_parent_proxy(int pid) { - parent = ((debugger_state) { pid : pid, - wait_options : 0, - wait_status_ptr : NULL, - waiting : 0, - real_wait : 0, - expecting_child : 0, - handle_trace : parent_syscall, - debugee : NULL } ); + parent = ((debugger_state) { .pid = pid, + .wait_options = 0, + .wait_status_ptr = NULL, + .waiting = 0, + .real_wait = 0, + .expecting_child = 0, + .handle_trace = parent_syscall, + .debugee = NULL } ); return(0); } diff -Nru a/arch/um/kernel/tt/sys-i386/sigcontext.c b/arch/um/kernel/tt/sys-i386/sigcontext.c --- a/arch/um/kernel/tt/sys-i386/sigcontext.c Sun Feb 9 21:13:36 2003 +++ b/arch/um/kernel/tt/sys-i386/sigcontext.c Sun Feb 9 21:13:36 2003 @@ -29,14 +29,15 @@ return(err); } -int copy_sc_to_user_tt(void *to_ptr, void *from_ptr, void *data) +int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data) { struct arch_frame_data *arch = data; struct sigcontext *to = to_ptr, *from = from_ptr; struct _fpstate *to_fp, *from_fp; int err; - to_fp = (struct _fpstate *)((unsigned long) to + sizeof(*to)); + to_fp = (struct _fpstate *) + (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to))); from_fp = from->fpstate; err = copy_to_user_proc(to, from, sizeof(*to)); if(from_fp != NULL){ diff -Nru a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c --- a/arch/um/kernel/tt/syscall_kern.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/kernel/tt/syscall_kern.c Sun Feb 9 21:13:28 2003 @@ -20,29 +20,32 @@ static int check_readlink(struct pt_regs *regs) { - return(check_area((void *) regs->regs.args[1], regs->regs.args[2])); + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), + UPT_SYSCALL_ARG2(®s->regs))); } static int check_utime(struct pt_regs *regs) { - return(check_area((void *) regs->regs.args[1], + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), sizeof(struct utimbuf))); } static int check_oldstat(struct pt_regs *regs) { - return(check_area((void *) regs->regs.args[1], + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), sizeof(struct __old_kernel_stat))); } static int check_stat(struct pt_regs *regs) { - return(check_area((void *) regs->regs.args[1], sizeof(struct stat))); + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), + sizeof(struct stat))); } static int check_stat64(struct pt_regs *regs) { - return(check_area((void *) regs->regs.args[1], sizeof(struct stat64))); + return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), + sizeof(struct stat64))); } struct bogus { @@ -90,7 +93,7 @@ static int check_bogosity(struct pt_regs *regs) { - struct bogus *bogon = &this_is_bogus[regs->regs.syscall]; + struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(®s->regs)]; if(!bogon->kernel_ds) return(0); if(bogon->check_params && (*bogon->check_params)(regs)) @@ -109,7 +112,7 @@ current->thread.nsyscalls++; nsyscalls++; - syscall = regs->regs.syscall; + syscall = UPT_SYSCALL_NR(®s->regs); if((syscall >= NR_syscalls) || (syscall < 0)) res = -ENOSYS; diff -Nru a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c --- a/arch/um/kernel/tt/syscall_user.c Sun Feb 9 21:13:33 2003 +++ b/arch/um/kernel/tt/syscall_user.c Sun Feb 9 21:13:33 2003 @@ -22,15 +22,14 @@ #define ERESTARTNOINTR 513 #define ERESTARTNOHAND 514 -void syscall_handler_tt(int sig, struct uml_pt_regs *regs) +void syscall_handler_tt(int sig, union uml_pt_regs *regs) { void *sc; long result; int index, syscall; - syscall = regs->syscall; - sc = regs->mode.tt; - sc_to_regs(regs, sc, syscall); + syscall = UPT_SYSCALL_NR(regs); + sc = UPT_SC(regs); SC_START_SYSCALL(sc); index = record_syscall_start(syscall); @@ -40,7 +39,7 @@ /* regs->sc may have changed while the system call ran (there may * have been an interrupt or segfault), so it needs to be refreshed. */ - regs->mode.tt = sc; + UPT_SC(regs) = sc; SC_SET_SYSCALL_RETURN(sc, result); if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || @@ -54,7 +53,7 @@ int do_syscall(void *task, int pid) { unsigned long proc_regs[FRAME_SIZE]; - struct uml_pt_regs *regs; + union uml_pt_regs *regs; int syscall; if(ptrace_getregs(pid, proc_regs) < 0) diff -Nru a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c --- a/arch/um/kernel/tt/tlb.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/kernel/tt/tlb.c Sun Feb 9 21:13:28 2003 @@ -132,7 +132,7 @@ if(updated && update_seq) atomic_inc(&vmchange_seq); } -void flush_tlb_kernel_range(unsigned long start, unsigned long end) +void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end) { flush_kernel_vm_range(start, end, 1); } diff -Nru a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c --- a/arch/um/kernel/tt/tracer.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/kernel/tt/tracer.c Sun Feb 9 21:13:28 2003 @@ -120,16 +120,6 @@ return((*proc)(NULL)); } -static void last_ditch_exit(int sig) -{ - kmalloc_ok = 0; - signal(SIGINT, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGHUP, SIG_DFL); - uml_cleanup(); - exit(1); -} - static void sleeping_process_signal(int pid, int sig) { switch(sig){ @@ -214,9 +204,6 @@ signal(SIGSEGV, (sighandler_t) tracer_segv); signal(SIGUSR1, signal_usr1); - set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); - set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); - set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); if(debug_trace){ printf("Tracing thread pausing to be attached\n"); stop(); diff -Nru a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c --- a/arch/um/kernel/tt/trap_user.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/kernel/tt/trap_user.c Sun Feb 9 21:13:32 2003 @@ -14,26 +14,27 @@ #include "task.h" #include "tt.h" -void sig_handler_common_tt(int sig, struct sigcontext *sc) +void sig_handler_common_tt(int sig, void *sc_ptr) { - struct uml_pt_regs save_regs, *r; + struct sigcontext *sc = sc_ptr; + struct tt_regs save_regs, *r; struct signal_info *info; int save_errno = errno, is_user; unprotect_kernel_mem(); - r = (struct uml_pt_regs *) TASK_REGS(get_current()); + r = &TASK_REGS(get_current())->tt; save_regs = *r; is_user = user_context(SC_SP(sc)); - r->is_user = is_user; - r->mode.tt = sc; - if(sig != SIGUSR2) r->syscall = -1; + r->sc = sc; + if(sig != SIGUSR2) + r->syscall = -1; change_sig(SIGUSR1, 1); info = &sig_info[sig]; if(!info->is_irq) unblock_signals(); - (*info->handler)(sig, r); + (*info->handler)(sig, (union uml_pt_regs *) r); if(is_user){ interrupt_end(); diff -Nru a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c --- a/arch/um/kernel/tt/uaccess_user.c Sun Feb 9 21:13:30 2003 +++ b/arch/um/kernel/tt/uaccess_user.c Sun Feb 9 21:13:30 2003 @@ -7,34 +7,7 @@ #include #include #include "user_util.h" - -static unsigned long __do_user_copy(void *to, const void *from, int n, - void **fault_addr, void **fault_catcher, - void (*op)(void *to, const void *from, - int n), int *faulted_out) -{ - unsigned long *faddrp = (unsigned long *) fault_addr, ret; - - jmp_buf jbuf; - *fault_catcher = &jbuf; - if(setjmp(jbuf) == 0){ - (*op)(to, from, n); - ret = 0; - *faulted_out = 0; - } - else { - ret = *faddrp; - *faulted_out = 1; - } - *fault_addr = NULL; - *fault_catcher = NULL; - return ret; -} - -static void __do_copy(void *to, const void *from, int n) -{ - memcpy(to, from, n); -} +#include "uml_uaccess.h" int __do_copy_from_user(void *to, const void *from, int n, void **fault_addr, void **fault_catcher) @@ -46,19 +19,6 @@ __do_copy, &faulted); if(!faulted) return(0); else return(n - (fault - (unsigned long) from)); -} - - -int __do_copy_to_user(void *to, const void *from, int n, - void **fault_addr, void **fault_catcher) -{ - unsigned long fault; - int faulted; - - fault = __do_user_copy(to, from, n, fault_addr, fault_catcher, - __do_copy, &faulted); - if(!faulted) return(0); - else return(n - (fault - (unsigned long) to)); } static void __do_strncpy(void *dst, const void *src, int count) diff -Nru a/arch/um/kernel/tt/unmap.c b/arch/um/kernel/tt/unmap.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/um/kernel/tt/unmap.c Sun Feb 9 21:13:34 2003 @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include "user.h" + +int switcheroo(int fd, int prot, void *from, void *to, int size) +{ + if(munmap(to, size) < 0){ + return(-1); + } + if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){ + return(-1); + } + if(munmap(from, size) < 0){ + return(-1); + } + return(0); +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -Nru a/arch/um/kernel/uaccess_user.c b/arch/um/kernel/uaccess_user.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/um/kernel/uaccess_user.c Sun Feb 9 21:13:38 2003 @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include + +/* These are here rather than tt/uaccess.c because skas mode needs them in + * order to do SIGBUS recovery when a tmpfs mount runs out of room. + */ + +unsigned long __do_user_copy(void *to, const void *from, int n, + void **fault_addr, void **fault_catcher, + void (*op)(void *to, const void *from, + int n), int *faulted_out) +{ + unsigned long *faddrp = (unsigned long *) fault_addr, ret; + + jmp_buf jbuf; + *fault_catcher = &jbuf; + if(setjmp(jbuf) == 0){ + (*op)(to, from, n); + ret = 0; + *faulted_out = 0; + } + else { + ret = *faddrp; + *faulted_out = 1; + } + *fault_addr = NULL; + *fault_catcher = NULL; + return ret; +} + +void __do_copy(void *to, const void *from, int n) +{ + memcpy(to, from, n); +} + + +int __do_copy_to_user(void *to, const void *from, int n, + void **fault_addr, void **fault_catcher) +{ + unsigned long fault; + int faulted; + + fault = __do_user_copy(to, from, n, fault_addr, fault_catcher, + __do_copy, &faulted); + if(!faulted) return(0); + else return(n - (fault - (unsigned long) to)); +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -Nru a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c --- a/arch/um/kernel/um_arch.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/kernel/um_arch.c Sun Feb 9 21:13:35 2003 @@ -85,10 +85,10 @@ } struct seq_operations cpuinfo_op = { - start: c_start, - next: c_next, - stop: c_stop, - show: show_cpuinfo, + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, }; pte_t * __bad_pagetable(void) @@ -110,12 +110,14 @@ unsigned long end_vm; int ncpus = 1; +#ifdef CONFIG_MODE_TT /* Pointer set in linux_main, the array itself is private to each thread, * and changed at address space creation time so this poses no concurrency * problems. */ static char *argv1_begin = NULL; static char *argv1_end = NULL; +#endif /* Set in early boot */ static int have_root __initdata = 0; @@ -123,6 +125,7 @@ void set_cmdline(char *cmd) { +#ifdef CONFIG_MODE_TT char *umid, *ptr; if(CHOOSE_MODE(honeypot, 0)) return; @@ -139,6 +142,7 @@ snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd); memset(argv1_begin + strlen(argv1_begin), '\0', argv1_end - argv1_begin - strlen(argv1_begin)); +#endif } static char *usage_string = @@ -199,23 +203,28 @@ return(0); } -__uml_setup("mode=tt", mode_tt_setup, -"mode=tt\n" -" When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n" -" forces UML to run in tt (tracing thread) mode. It is not the default\n" -" because it's slower and less secure than skas mode.\n\n" -); - #else #ifdef CONFIG_MODE_SKAS #define DEFAULT_TT 0 +static int __init mode_tt_setup(char *line, int *add) +{ + printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); + return(0); +} + #else #ifdef CONFIG_MODE_TT #define DEFAULT_TT 1 +static int __init mode_tt_setup(char *line, int *add) +{ + printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); + return(0); +} + #else #error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled @@ -224,6 +233,13 @@ #endif #endif +__uml_setup("mode=tt", mode_tt_setup, +"mode=tt\n" +" When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n" +" forces UML to run in tt (tracing thread) mode. It is not the default\n" +" because it's slower and less secure than skas mode.\n\n" +); + int mode_tt = DEFAULT_TT; static int __init Usage(char *line, int *add) @@ -307,8 +323,10 @@ setup_machinename(system_utsname.machine); +#ifdef CONFIG_MODE_TT argv1_begin = argv[1]; argv1_end = &argv[1][strlen(argv[1])]; +#endif set_usable_vm(uml_physmem, get_kmem_end()); @@ -317,6 +335,11 @@ if(physmem_size > max_physmem){ highmem = physmem_size - max_physmem; physmem_size -= highmem; +#ifndef CONFIG_HIGHMEM + highmem = 0; + printf("CONFIG_HIGHMEM not enabled - physical memory shrunk " + "to %ld bytes\n", physmem_size); +#endif } high_physmem = uml_physmem + physmem_size; @@ -361,9 +384,9 @@ } static struct notifier_block panic_exit_notifier = { - notifier_call : panic_exit, - next : NULL, - priority : 0 + .notifier_call = panic_exit, + .next = NULL, + .priority = 0 }; void __init setup_arch(char **cmdline_p) diff -Nru a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c --- a/arch/um/kernel/umid.c Sun Feb 9 21:13:36 2003 +++ b/arch/um/kernel/umid.c Sun Feb 9 21:13:36 2003 @@ -35,7 +35,7 @@ static int make_umid(void); -static int __init set_umid(char *name, int *add) +static int __init set_umid(char *name, int is_random) { if(umid_inited){ printk("Unique machine name can't be set twice\n"); @@ -48,12 +48,17 @@ strncpy(umid, name, UMID_LEN - 1); umid[UMID_LEN - 1] = '\0'; - umid_is_random = 0; + umid_is_random = is_random; umid_inited = 1; return 0; } -__uml_setup("umid=", set_umid, +static int __init set_umid_arg(char *name, int *add) +{ + return(set_umid(name, 0)); +} + +__uml_setup("umid=", set_umid_arg, "umid=\n" " This is used to assign a unique identity to this UML machine and\n" " is used for naming the pid file and management console socket.\n\n" @@ -186,7 +191,6 @@ } if(!dead) return(1); return(actually_do_remove(dir)); - return(0); } static int __init set_uml_dir(char *name, int *add) @@ -254,7 +258,7 @@ strcat(tmp, "XXXXXX"); fd = mkstemp(tmp); if(fd < 0){ - printk("set_umid - mkstemp failed, errno = %d\n", + printk("make_umid - mkstemp failed, errno = %d\n", errno); return(1); } @@ -265,7 +269,7 @@ * for directories. */ unlink(tmp); - strcpy(umid, &tmp[strlen(uml_dir)]); + set_umid(&tmp[strlen(uml_dir)], 1); } sprintf(tmp, "%s%s", uml_dir, umid); diff -Nru a/arch/um/kernel/unmap.c b/arch/um/kernel/unmap.c --- a/arch/um/kernel/unmap.c Sun Feb 9 21:13:34 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include "user.h" - -int switcheroo(int fd, int prot, void *from, void *to, int size) -{ - if(munmap(to, size) < 0){ - return(-1); - } - if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){ - return(-1); - } - if(munmap(from, size) < 0){ - return(-1); - } - return(0); -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -Nru a/arch/um/kernel/user_syms.c b/arch/um/kernel/user_syms.c --- a/arch/um/kernel/user_syms.c Sun Feb 9 21:13:36 2003 +++ b/arch/um/kernel/user_syms.c Sun Feb 9 21:13:36 2003 @@ -10,10 +10,7 @@ #include #include "user_util.h" #include "mem_user.h" - -/* XXX All the __CONFIG_* stuff is broken because this file can't include - * config.h - */ +#include "uml-config.h" /* Had to steal this from linux/module.h because that file can't be included * since this includes various user-level headers. @@ -36,7 +33,7 @@ #define EXPORT_SYMBOL(var) error config_must_be_included_before_module #define EXPORT_SYMBOL_NOVERS(var) error config_must_be_included_before_module -#elif !defined(__CONFIG_MODULES__) +#elif !defined(UML_CONFIG_MODULES) #define __EXPORT_SYMBOL(sym,str) #define EXPORT_SYMBOL(var) @@ -51,7 +48,7 @@ __attribute__((section("__ksymtab"))) = \ { (unsigned long)&sym, __kstrtab_##sym } -#if defined(__MODVERSIONS__) || !defined(__CONFIG_MODVERSIONS__) +#if defined(__MODVERSIONS__) || !defined(UML_CONFIG_MODVERSIONS) #define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) #else #define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var))) diff -Nru a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c --- a/arch/um/kernel/user_util.c Sun Feb 9 21:13:29 2003 +++ b/arch/um/kernel/user_util.c Sun Feb 9 21:13:29 2003 @@ -29,6 +29,7 @@ #include "mem_user.h" #include "init.h" #include "helper.h" +#include "uml-config.h" #define COMMAND_LINE_SIZE _POSIX_ARG_MAX @@ -46,31 +47,6 @@ strcat(cmd_line, arg); } -void remap_data(void *segment_start, void *segment_end, int w) -{ - void *addr; - unsigned long size; - int data, prot; - - if(w) prot = PROT_WRITE; - else prot = 0; - prot |= PROT_READ | PROT_EXEC; - size = (unsigned long) segment_end - - (unsigned long) segment_start; - data = create_mem_file(size); - if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ, - MAP_SHARED, data, 0)) < 0){ - perror("mapping new data segment"); - exit(1); - } - memcpy(addr, segment_start, size); - if(switcheroo(data, prot, addr, segment_start, - size) < 0){ - printf("switcheroo failed\n"); - exit(1); - } -} - void stop(void) { while(1) sleep(1000000); @@ -88,12 +64,15 @@ { unsigned long guard = address + page_size(); unsigned long stack = guard + page_size(); - int prot = 0; + int prot = 0, pages; +#ifdef notdef if(mprotect((void *) stack, page_size(), prot) < 0) panic("protecting guard page failed, errno = %d", errno); +#endif + pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2; prot = PROT_READ | PROT_WRITE | PROT_EXEC; - if(mprotect((void *) stack, 2 * page_size(), prot) < 0) + if(mprotect((void *) stack, pages * page_size(), prot) < 0) panic("protecting stack failed, errno = %d", errno); } diff -Nru a/arch/um/main.c b/arch/um/main.c --- a/arch/um/main.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/main.c Sun Feb 9 21:13:35 2003 @@ -15,10 +15,12 @@ #include "user_util.h" #include "kern_util.h" #include "mem_user.h" +#include "signal_user.h" #include "user.h" #include "init.h" #include "mode.h" #include "choose-mode.h" +#include "uml-config.h" /* Set in set_stklim, which is called from main and __wrap_malloc. * __wrap_malloc only calls it if main hasn't started. @@ -32,11 +34,6 @@ #define STACKSIZE (8 * 1024 * 1024) #define THREAD_NAME_LEN (256) -/* Never changed */ -static char padding[THREAD_NAME_LEN] = { - [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0' -}; - static void set_stklim(void) { struct rlimit lim; @@ -66,26 +63,43 @@ } } +static void last_ditch_exit(int sig) +{ + CHOOSE_MODE(kmalloc_ok = 0, (void) 0); + signal(SIGINT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGHUP, SIG_DFL); + uml_cleanup(); + exit(1); +} + extern int uml_exitcode; int main(int argc, char **argv, char **envp) { + char **new_argv; sigset_t mask; int ret, i; - char **new_argv; - /* Enable all signals - in some environments, we can enter with - * some signals blocked + /* Enable all signals except SIGIO - in some environments, we can + * enter with some signals blocked */ sigemptyset(&mask); + sigaddset(&mask, SIGIO); if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){ perror("sigprocmask"); exit(1); } +#ifdef UML_CONFIG_MODE_TT /* Allocate memory for thread command lines */ if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){ + + char padding[THREAD_NAME_LEN] = { + [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0' + }; + new_argv = malloc((argc + 2) * sizeof(char*)); if(!new_argv) { perror("Allocating extended argv"); @@ -103,6 +117,7 @@ perror("execing with extended args"); exit(1); } +#endif linux_prog = argv[0]; @@ -120,6 +135,10 @@ } new_argv[argc] = NULL; + set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); + set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); + set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); + do_uml_initcalls(); ret = linux_main(argc, argv); @@ -141,8 +160,10 @@ void *__wrap_malloc(int size) { - if(CAN_KMALLOC()) return(um_kmalloc(size)); - else return(__real_malloc(size)); + if(CAN_KMALLOC()) + return(um_kmalloc(size)); + else + return(__real_malloc(size)); } void *__wrap_calloc(int n, int size) diff -Nru a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c --- a/arch/um/os-Linux/drivers/ethertap_kern.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/os-Linux/drivers/ethertap_kern.c Sun Feb 9 21:13:28 2003 @@ -28,11 +28,11 @@ pri = dev->priv; epri = (struct ethertap_data *) pri->user; *epri = ((struct ethertap_data) - { dev_name : init->dev_name, - gate_addr : init->gate_addr, - data_fd : -1, - control_fd : -1, - dev : dev }); + { .dev_name = init->dev_name, + .gate_addr = init->gate_addr, + .data_fd = -1, + .control_fd = -1, + .dev = dev }); printk("ethertap backend - %s", epri->dev_name); if(epri->gate_addr != NULL) @@ -69,10 +69,10 @@ } struct net_kern_info ethertap_kern_info = { - init: etap_init, - protocol: eth_protocol, - read: etap_read, - write: etap_write, + .init = etap_init, + .protocol = eth_protocol, + .read = etap_read, + .write = etap_write, }; int ethertap_setup(char *str, char **mac_out, void *data) @@ -80,8 +80,8 @@ struct ethertap_init *init = data; *init = ((struct ethertap_init) - { dev_name : NULL, - gate_addr : NULL }); + { .dev_name = NULL, + .gate_addr = NULL }); if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out, &init->gate_addr)) return(0); @@ -94,12 +94,12 @@ } static struct transport ethertap_transport = { - list : LIST_HEAD_INIT(ethertap_transport.list), - name : "ethertap", - setup : ethertap_setup, - user : ðertap_user_info, - kern : ðertap_kern_info, - private_size : sizeof(struct ethertap_data), + .list = LIST_HEAD_INIT(ethertap_transport.list), + .name = "ethertap", + .setup = ethertap_setup, + .user = ðertap_user_info, + .kern = ðertap_kern_info, + .private_size = sizeof(struct ethertap_data), }; static int register_ethertap(void) diff -Nru a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c --- a/arch/um/os-Linux/drivers/ethertap_user.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/os-Linux/drivers/ethertap_user.c Sun Feb 9 21:13:32 2003 @@ -216,14 +216,14 @@ } struct net_user_info ethertap_user_info = { - init: etap_user_init, - open: etap_open, - close: etap_close, - remove: NULL, - set_mtu: etap_set_mtu, - add_address: etap_add_addr, - delete_address: etap_del_addr, - max_packet: MAX_PACKET - ETH_HEADER_ETHERTAP + .init = etap_user_init, + .open = etap_open, + .close = etap_close, + .remove = NULL, + .set_mtu = etap_set_mtu, + .add_address = etap_add_addr, + .delete_address = etap_del_addr, + .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP }; /* diff -Nru a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c --- a/arch/um/os-Linux/drivers/tuntap_kern.c Sun Feb 9 21:13:33 2003 +++ b/arch/um/os-Linux/drivers/tuntap_kern.c Sun Feb 9 21:13:33 2003 @@ -28,11 +28,11 @@ pri = dev->priv; tpri = (struct tuntap_data *) pri->user; *tpri = ((struct tuntap_data) - { dev_name : init->dev_name, - fixed_config : (init->dev_name != NULL), - gate_addr : init->gate_addr, - fd : -1, - dev : dev }); + { .dev_name = init->dev_name, + .fixed_config = (init->dev_name != NULL), + .gate_addr = init->gate_addr, + .fd = -1, + .dev = dev }); printk("TUN/TAP backend - "); if(tpri->gate_addr != NULL) printk("IP = %s", tpri->gate_addr); @@ -55,10 +55,10 @@ } struct net_kern_info tuntap_kern_info = { - init: tuntap_init, - protocol: eth_protocol, - read: tuntap_read, - write: tuntap_write, + .init = tuntap_init, + .protocol = eth_protocol, + .read = tuntap_read, + .write = tuntap_write, }; int tuntap_setup(char *str, char **mac_out, void *data) @@ -66,8 +66,8 @@ struct tuntap_init *init = data; *init = ((struct tuntap_init) - { dev_name : NULL, - gate_addr : NULL }); + { .dev_name = NULL, + .gate_addr = NULL }); if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out, &init->gate_addr)) return(0); @@ -76,13 +76,13 @@ } static struct transport tuntap_transport = { - list : LIST_HEAD_INIT(tuntap_transport.list), - name : "tuntap", - setup : tuntap_setup, - user : &tuntap_user_info, - kern : &tuntap_kern_info, - private_size : sizeof(struct tuntap_data), - setup_size : sizeof(struct tuntap_init), + .list = LIST_HEAD_INIT(tuntap_transport.list), + .name = "tuntap", + .setup = tuntap_setup, + .user = &tuntap_user_info, + .kern = &tuntap_kern_info, + .private_size = sizeof(struct tuntap_data), + .setup_size = sizeof(struct tuntap_init), }; static int register_tuntap(void) diff -Nru a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c --- a/arch/um/os-Linux/drivers/tuntap_user.c Sun Feb 9 21:13:37 2003 +++ b/arch/um/os-Linux/drivers/tuntap_user.c Sun Feb 9 21:13:37 2003 @@ -201,14 +201,14 @@ } struct net_user_info tuntap_user_info = { - init: tuntap_user_init, - open: tuntap_open, - close: tuntap_close, - remove: NULL, - set_mtu: tuntap_set_mtu, - add_address: tuntap_add_addr, - delete_address: tuntap_del_addr, - max_packet: MAX_PACKET + .init = tuntap_user_init, + .open = tuntap_open, + .close = tuntap_close, + .remove = NULL, + .set_mtu = tuntap_set_mtu, + .add_address = tuntap_add_addr, + .delete_address = tuntap_del_addr, + .max_packet = MAX_PACKET }; /* diff -Nru a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c --- a/arch/um/os-Linux/file.c Sun Feb 9 21:13:37 2003 +++ b/arch/um/os-Linux/file.c Sun Feb 9 21:13:37 2003 @@ -28,8 +28,8 @@ else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK); else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV); else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV); - else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO); - else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK); + else if(S_ISFIFO(buf.st_mode)) return(OS_TYPE_FIFO); + else if(S_ISSOCK(buf.st_mode)) return(OS_TYPE_SOCK); else return(OS_TYPE_FILE); } @@ -64,6 +64,15 @@ fd = open64(file, f, mode); if(fd < 0) return(-errno); + + if(flags.cl){ + if(fcntl(fd, F_SETFD, 1)){ + close(fd); + return(-errno); + } + } + + return(fd); return(fd); } @@ -100,7 +109,7 @@ return(0); } -int os_read_file(int fd, char *buf, int len) +int os_read_file(int fd, void *buf, int len) { int n; @@ -118,7 +127,7 @@ return(n); } -int os_write_file(int fd, char *buf, int count) +int os_write_file(int fd, void *buf, int count) { int n; @@ -276,8 +285,8 @@ msg.msg_name = NULL; msg.msg_namelen = 0; - iov = ((struct iovec) { iov_base : helper_pid_out, - iov_len : sizeof(*helper_pid_out) }); + iov = ((struct iovec) { .iov_base = helper_pid_out, + .iov_len = sizeof(*helper_pid_out) }); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = buf; diff -Nru a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c --- a/arch/um/os-Linux/process.c Sun Feb 9 21:13:29 2003 +++ b/arch/um/os-Linux/process.c Sun Feb 9 21:13:29 2003 @@ -106,7 +106,7 @@ loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, fd, off); - if(loc < 0) + if(loc == MAP_FAILED) return(-errno); return(0); } diff -Nru a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile --- a/arch/um/sys-i386/Makefile Sun Feb 9 21:13:29 2003 +++ b/arch/um/sys-i386/Makefile Sun Feb 9 21:13:29 2003 @@ -3,15 +3,13 @@ obj-$(CONFIG_HIGHMEM) += highmem.o -export-objs = ksyms.o - USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) -SYMLINKS = semaphore.c extable.c highmem.c module.c +SYMLINKS = semaphore.c highmem.c module.c +SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f) semaphore.c-dir = kernel -extable.c-dir = mm highmem.c-dir = mm module.c-dir = kernel @@ -23,7 +21,7 @@ $(USER_OBJS) : %.o: %.c $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< -$(foreach f,$(SYMLINKS),$(src)/$f): +$(SYMLINKS): $(call make_link,$@) clean: diff -Nru a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c --- a/arch/um/sys-i386/bugs.c Sun Feb 9 21:13:35 2003 +++ b/arch/um/sys-i386/bugs.c Sun Feb 9 21:13:35 2003 @@ -117,7 +117,7 @@ if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it; } -int arch_handle_signal(int sig, struct uml_pt_regs *regs) +int arch_handle_signal(int sig, union uml_pt_regs *regs) { unsigned long ip; diff -Nru a/arch/um/sys-i386/extable.c b/arch/um/sys-i386/extable.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/um/sys-i386/extable.c Sun Feb 9 21:13:38 2003 @@ -0,0 +1,30 @@ +/* + * linux/arch/i386/mm/extable.c + */ + +#include +#include +#include +#include + +/* Simple binary search */ +const struct exception_table_entry * +search_extable(const struct exception_table_entry *first, + const struct exception_table_entry *last, + unsigned long value) +{ + while (first <= last) { + const struct exception_table_entry *mid; + long diff; + + mid = (last - first) / 2 + first; + diff = mid->insn - value; + if (diff == 0) + return mid; + else if (diff < 0) + first = mid+1; + else + last = mid-1; + } + return NULL; +} diff -Nru a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c --- a/arch/um/sys-i386/fault.c Sun Feb 9 21:13:32 2003 +++ b/arch/um/sys-i386/fault.c Sun Feb 9 21:13:32 2003 @@ -14,7 +14,7 @@ struct sigcontext *sc = sc_ptr; unsigned long fixup; - fixup = search_exception_table(address); + fixup = search_exception_tables(address); if(fixup != 0){ sc->eip = fixup; return(1); diff -Nru a/arch/um/sys-i386/sigcontext.c b/arch/um/sys-i386/sigcontext.c --- a/arch/um/sys-i386/sigcontext.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/sys-i386/sigcontext.c Sun Feb 9 21:13:28 2003 @@ -21,7 +21,7 @@ void sc_to_sc(void *to_ptr, void *from_ptr) { struct sigcontext *to = to_ptr, *from = from_ptr; - int size = sizeof(*to) + signal_frame_sc.arch.fpstate_size; + int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size; memcpy(to, from, size); if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1); diff -Nru a/arch/um/sys-i386/util/mk_thread_kern.c b/arch/um/sys-i386/util/mk_thread_kern.c --- a/arch/um/sys-i386/util/mk_thread_kern.c Sun Feb 9 21:13:28 2003 +++ b/arch/um/sys-i386/util/mk_thread_kern.c Sun Feb 9 21:13:28 2003 @@ -1,3 +1,4 @@ +#include "linux/config.h" #include "linux/stddef.h" #include "linux/sched.h" @@ -12,7 +13,9 @@ { print_head(); print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs)); +#ifdef CONFIG_MODE_TT print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid)); +#endif print_tail(); return(0); } diff -Nru a/arch/um/uml.lds.S b/arch/um/uml.lds.S --- a/arch/um/uml.lds.S Sun Feb 9 21:13:31 2003 +++ b/arch/um/uml.lds.S Sun Feb 9 21:13:31 2003 @@ -11,15 +11,17 @@ . = ALIGN(4096); __binary_start = .; +#ifdef MODE_TT .thread_private : { __start_thread_private = .; errno = .; . += 4; - arch/um/kernel/unmap_fin.o (.data) + arch/um/kernel/tt/unmap_fin.o (.data) __end_thread_private = .; } . = ALIGN(4096); - .remap : { arch/um/kernel/unmap_fin.o (.text) } + .remap : { arch/um/kernel/tt/unmap_fin.o (.text) } +#endif . = ALIGN(4096); /* Init code and data */ _stext = .; @@ -34,80 +36,12 @@ *(.gnu.linkonce.t*) } - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; + #include "asm/common.lds.S" - RODATA - - .fini : { *(.fini) } =0x9090 - _etext = .; - PROVIDE (etext = .); - - . = ALIGN(4096); - PROVIDE (_sdata = .); - - .unprotected : { *(.unprotected) } - . = ALIGN(4096); - PROVIDE (_unprotected_end = .); - - . = ALIGN(4096); - __uml_setup_start = .; - .uml.setup.init : { *(.uml.setup.init) } - __uml_setup_end = .; - - __uml_help_start = .; - .uml.help.init : { *(.uml.help.init) } - __uml_help_end = .; - - __uml_postsetup_start = .; - .uml.postsetup.init : { *(.uml.postsetup.init) } - __uml_postsetup_end = .; - - __setup_start = .; - .init.setup : { *(.init.setup) } - __setup_end = .; - - __start___param = .; - __param : { *(__param) } - __stop___param = .; - - __per_cpu_start = . ; - .data.percpu : { *(.data.percpu) } - __per_cpu_end = . ; - - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - __uml_initcall_start = .; - .uml.initcall.init : { *(.uml.initcall.init) } - __uml_initcall_end = .; - __init_end = .; - __exitcall_begin = .; - .exitcall : { *(.exitcall.exit) } - __exitcall_end = .; - __uml_exitcall_begin = .; - .uml.exitcall : { *(.uml.exitcall.exit) } - __uml_exitcall_end = .; - - . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : { *(.init.ramfs) } - __initramfs_end = .; - .data.init : { *(.data.init) } .data : { - . = ALIGN(16384); /* init_task */ + . = ALIGN(KERNEL_STACK_SIZE); /* init_task */ *(.data.init_task) *(.data) *(.gnu.linkonce.d*) diff -Nru a/arch/um/util/mk_task_kern.c b/arch/um/util/mk_task_kern.c --- a/arch/um/util/mk_task_kern.c Sun Feb 9 21:13:29 2003 +++ b/arch/um/util/mk_task_kern.c Sun Feb 9 21:13:29 2003 @@ -9,7 +9,7 @@ int main(int argc, char **argv) { print_head(); - print_ptr("TASK_REGS", "struct uml_pt_regs", + print_ptr("TASK_REGS", "union uml_pt_regs", offsetof(struct task_struct, thread.regs)); print("TASK_PID", "int", offsetof(struct task_struct, pid)); print_tail(); diff -Nru a/arch/um/vmlinux.lds.S b/arch/um/vmlinux.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/um/vmlinux.lds.S Sun Feb 9 21:13:37 2003 @@ -0,0 +1,11 @@ +#include + +OUTPUT_FORMAT(ELF_FORMAT) +OUTPUT_ARCH(ELF_ARCH) +ENTRY(_start) +jiffies = jiffies_64; + +SECTIONS +{ +#include "asm/common.lds.S" +} diff -Nru a/arch/v850/Kconfig b/arch/v850/Kconfig --- a/arch/v850/Kconfig Sun Feb 9 21:13:31 2003 +++ b/arch/v850/Kconfig Sun Feb 9 21:13:31 2003 @@ -351,7 +351,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/v850/Makefile b/arch/v850/Makefile --- a/arch/v850/Makefile Sun Feb 9 21:13:37 2003 +++ b/arch/v850/Makefile Sun Feb 9 21:13:37 2003 @@ -31,7 +31,7 @@ OBJCOPY_FLAGS_BLOB := -I binary -O elf32-little -B v850e -HEAD := $(arch_dir)/kernel/head.o $(arch_dir)/kernel/init_task.o +head-y := $(arch_dir)/kernel/head.o $(arch_dir)/kernel/init_task.o core-y += $(arch_dir)/kernel/ libs-y += $(arch_dir)/lib/ diff -Nru a/arch/v850/kernel/Makefile b/arch/v850/kernel/Makefile --- a/arch/v850/kernel/Makefile Sun Feb 9 21:13:37 2003 +++ b/arch/v850/kernel/Makefile Sun Feb 9 21:13:37 2003 @@ -13,8 +13,6 @@ obj-y += intv.o entry.o process.o syscalls.o time.o semaphore.o setup.o \ signal.o irq.o mach.o ptrace.o bug.o -export-objs += v850_ksyms.o rte_mb_a_pci.o - obj-$(CONFIG_MODULES) += module.o v850_ksyms.o # chip-specific code obj-$(CONFIG_V850E_MA1) += ma.o nb85e_utils.o nb85e_timer_d.o diff -Nru a/arch/v850/kernel/mach.h b/arch/v850/kernel/mach.h --- a/arch/v850/kernel/mach.h Sun Feb 9 21:13:37 2003 +++ b/arch/v850/kernel/mach.h Sun Feb 9 21:13:37 2003 @@ -45,7 +45,7 @@ extern void (*mach_tick) (void); /* The following establishes aliases for various mach_ functions to the - name by which the rest of the kernal calls them. These statements + name by which the rest of the kernel calls them. These statements should only have an effect in the file that defines the actual functions. */ #define MACH_ALIAS(to, from) \ asm (".global " macrology_stringify (C_SYMBOL_NAME (to)) ";" \ diff -Nru a/arch/v850/kernel/rte_mb_a_pci.c b/arch/v850/kernel/rte_mb_a_pci.c --- a/arch/v850/kernel/rte_mb_a_pci.c Sun Feb 9 21:13:30 2003 +++ b/arch/v850/kernel/rte_mb_a_pci.c Sun Feb 9 21:13:30 2003 @@ -689,7 +689,7 @@ free_dma_mapping (mapping); } -/* Make physical memory consistant for a single streaming mode DMA +/* Make physical memory consistent for a single streaming mode DMA translation after a transfer. If you perform a pci_map_single() but wish to interrogate the @@ -731,7 +731,7 @@ BUG (); } -/* Make physical memory consistant for a set of streaming mode DMA +/* Make physical memory consistent for a set of streaming mode DMA translations after a transfer. The same as pci_dma_sync_single but for a scatter-gather list, same rules and usage. */ diff -Nru a/arch/v850/kernel/signal.c b/arch/v850/kernel/signal.c --- a/arch/v850/kernel/signal.c Sun Feb 9 21:13:37 2003 +++ b/arch/v850/kernel/signal.c Sun Feb 9 21:13:37 2003 @@ -50,11 +50,11 @@ sigset_t saveset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->gpr[GPR_RVAL] = -EINTR; while (1) { @@ -78,11 +78,11 @@ if (copy_from_user(&newset, unewset, sizeof(newset))) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs->gpr[GPR_RVAL] = -EINTR; while (1) { @@ -188,10 +188,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(regs, &frame->sc, &rval)) goto badframe; @@ -216,10 +216,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval)) goto badframe; @@ -472,11 +472,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c --- a/arch/v850/kernel/time.c Sun Feb 9 21:13:33 2003 +++ b/arch/v850/kernel/time.c Sun Feb 9 21:13:33 2003 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -107,8 +108,6 @@ #endif /* 0 */ } -extern rwlock_t xtime_lock; - /* * This version of gettimeofday has near microsecond resolution. */ @@ -120,21 +119,24 @@ #endif unsigned long flags; unsigned long usec, sec; + unsigned long seq; + + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); - read_lock_irqsave (&xtime_lock, flags); #if 0 - usec = mach_gettimeoffset ? mach_gettimeoffset () : 0; + usec = mach_gettimeoffset ? mach_gettimeoffset () : 0; #else - usec = 0; + usec = 0; #endif #if 0 /* DAVIDM later if possible */ - lost = lost_ticks; - if (lost) - usec += lost * (1000000/HZ); + lost = lost_ticks; + if (lost) + usec += lost * (1000000/HZ); #endif - sec = xtime.tv_sec; - usec += xtime.tv_nsec / 1000; - read_unlock_irqrestore (&xtime_lock, flags); + sec = xtime.tv_sec; + usec += xtime.tv_nsec / 1000; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; @@ -147,7 +149,7 @@ void do_settimeofday (struct timeval *tv) { - write_lock_irq (&xtime_lock); + write_seqlock_irq (&xtime_lock); /* This is revolting. We need to set the xtime.tv_nsec * correctly. However, the value in this location is @@ -172,7 +174,7 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq (&xtime_lock); + write_sequnlock_irq (&xtime_lock); } static int timer_dev_id; diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig --- a/arch/x86_64/Kconfig Sun Feb 9 21:13:35 2003 +++ b/arch/x86_64/Kconfig Sun Feb 9 21:13:35 2003 @@ -427,7 +427,7 @@ 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.o. Saying M or N here is dangerous because + will be called binfmt_elf. Saying M or N here is dangerous because some crucial programs on your system might be in ELF format. config BINFMT_MISC @@ -452,7 +452,7 @@ use this part of the kernel. You may say M here for module support and later load the module when - you have use for it; the module is called binfmt_misc.o. If you + you have use for it; the module is called binfmt_misc. If you don't know what to answer at this point, say Y. config IA32_EMULATION @@ -518,7 +518,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide.o. + will be called ide. For further information, please read . @@ -545,7 +545,7 @@ 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 will be called scsi_mod.o. If you want to compile it as + The module will be called scsi_mod. If you want to compile it as a module, say M here and read and . However, do not compile this as a module if your root file system (the one containing the directory /) @@ -615,7 +615,7 @@ and load that module after the PnP configuration is finished. To do this, say M here and read as well as ; the module will be - called soundcore.o. + called soundcore. I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. diff -Nru a/arch/x86_64/Makefile b/arch/x86_64/Makefile --- a/arch/x86_64/Makefile Sun Feb 9 21:13:35 2003 +++ b/arch/x86_64/Makefile Sun Feb 9 21:13:35 2003 @@ -48,7 +48,7 @@ CFLAGS += -finline-limit=2000 #CFLAGS += -g -HEAD := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o +head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o libs-y += arch/x86_64/lib/ core-y += arch/x86_64/kernel/ arch/x86_64/mm/ diff -Nru a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile --- a/arch/x86_64/ia32/Makefile Sun Feb 9 21:13:30 2003 +++ b/arch/x86_64/ia32/Makefile Sun Feb 9 21:13:30 2003 @@ -2,8 +2,6 @@ # Makefile for the ia32 kernel emulation subsystem. # -export-objs := ia32_ioctl.o sys_ia32.o - obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \ ia32_signal.o \ ia32_binfmt.o fpu32.o socket32.o ptrace32.o ipc32.o syscall32.o 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 Sun Feb 9 21:13:36 2003 +++ b/arch/x86_64/ia32/ia32_signal.c Sun Feb 9 21:13:36 2003 @@ -83,11 +83,11 @@ sigset_t saveset; mask &= _BLOCKABLE; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); regs.rax = -EINTR; while (1) { @@ -243,10 +243,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (ia32_restore_sigcontext(®s, &frame->sc, &eax)) goto badframe; @@ -270,10 +270,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (ia32_restore_sigcontext(®s, &frame->uc.uc_mcontext, &eax)) goto badframe; diff -Nru a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile --- a/arch/x86_64/kernel/Makefile Sun Feb 9 21:13:34 2003 +++ b/arch/x86_64/kernel/Makefile Sun Feb 9 21:13:34 2003 @@ -4,8 +4,6 @@ EXTRA_TARGETS := head.o head64.o init_task.o EXTRA_AFLAGS := -traditional -export-objs := x8664_ksyms.o pci-gart.o pci-dma.o - obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \ pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \ diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c --- a/arch/x86_64/kernel/apic.c Sun Feb 9 21:13:29 2003 +++ b/arch/x86_64/kernel/apic.c Sun Feb 9 21:13:29 2003 @@ -895,7 +895,7 @@ * value into /proc/profile. */ -inline void smp_local_timer_interrupt(struct pt_regs *regs) +void smp_local_timer_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); diff -Nru a/arch/x86_64/kernel/mtrr/Makefile b/arch/x86_64/kernel/mtrr/Makefile --- a/arch/x86_64/kernel/mtrr/Makefile Sun Feb 9 21:13:32 2003 +++ b/arch/x86_64/kernel/mtrr/Makefile Sun Feb 9 21:13:32 2003 @@ -7,8 +7,6 @@ obj-y += cyrix.o obj-y += centaur.o -export-objs := main.o - $(obj)/main.c: $(obj)/mtrr.h @ln -sf ../../../i386/kernel/cpu/mtrr/main.c $(obj)/main.c $(obj)/if.c: $(obj)/mtrr.h diff -Nru a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c --- a/arch/x86_64/kernel/signal.c Sun Feb 9 21:13:34 2003 +++ b/arch/x86_64/kernel/signal.c Sun Feb 9 21:13:34 2003 @@ -52,11 +52,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); #if DEBUG_SIG printk("rt_sigsuspend savset(%lx) newset(%lx) regs(%p) rip(%lx)\n", saveset, newset, ®s, regs.rip); @@ -155,10 +155,10 @@ } sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(®s, &frame->uc.uc_mcontext, &eax)) { goto badframe; @@ -401,11 +401,11 @@ ka->sa.sa_handler = SIG_DFL; if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); sigaddset(¤t->blocked,sig); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c --- a/arch/x86_64/kernel/time.c Sun Feb 9 21:13:34 2003 +++ b/arch/x86_64/kernel/time.c Sun Feb 9 21:13:34 2003 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -27,9 +28,12 @@ u64 jiffies_64; -extern rwlock_t xtime_lock; spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; +extern int using_apic_timer; +extern void smp_local_timer_interrupt(struct pt_regs * regs); + + unsigned int cpu_khz; /* TSC clocks / usec, not used here */ unsigned long hpet_period; /* fsecs / HPET clock */ unsigned long hpet_tick; /* HPET clocks / interrupt */ @@ -70,21 +74,22 @@ void do_gettimeofday(struct timeval *tv) { - unsigned long flags, t; + unsigned long flags, t, seq; unsigned int sec, usec; - read_lock_irqsave(&xtime_lock, flags); - spin_lock(&time_offset_lock); - - sec = xtime.tv_sec; - usec = xtime.tv_nsec / 1000; - - t = (jiffies - wall_jiffies) * (1000000L / HZ) + do_gettimeoffset(); - if (t > timeoffset) timeoffset = t; - usec += timeoffset; + spin_lock_irqsave(&time_offset_lock, flags); + do { + seq = read_seqbegin(&xtime_lock); + + sec = xtime.tv_sec; + usec = xtime.tv_nsec / 1000; + + t = (jiffies - wall_jiffies) * (1000000L / HZ) + do_gettimeoffset(); + if (t > timeoffset) timeoffset = t; + usec += timeoffset; - spin_unlock(&time_offset_lock); - read_unlock_irqrestore(&xtime_lock, flags); + } while (read_seqretry(&xtime_lock, seq)); + spin_unlock_irqrestore(&time_offset_lock, flags); tv->tv_sec = sec + usec / 1000000; tv->tv_usec = usec % 1000000; @@ -98,7 +103,7 @@ void do_settimeofday(struct timeval *tv) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); vxtime_lock(); tv->tv_usec -= do_gettimeoffset() + @@ -118,7 +123,7 @@ time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } /* @@ -201,7 +206,7 @@ * variables, because both do_timer() and us change them -arca+vojtech */ - write_lock(&xtime_lock); + write_seqlock(&xtime_lock); vxtime_lock(); { @@ -214,6 +219,7 @@ 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; } /* @@ -250,7 +256,7 @@ } vxtime_unlock(); - write_unlock(&xtime_lock); + write_sequnlock(&xtime_lock); } unsigned long get_cmos_time(void) diff -Nru a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile --- a/arch/x86_64/lib/Makefile Sun Feb 9 21:13:29 2003 +++ b/arch/x86_64/lib/Makefile Sun Feb 9 21:13:29 2003 @@ -3,8 +3,6 @@ # L_TARGET := lib.a -export-objs := io.o csum-wrappers.o csum-partial.o - CFLAGS_csum-partial.o := -funroll-loops obj-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \ diff -Nru a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile --- a/arch/x86_64/mm/Makefile Sun Feb 9 21:13:34 2003 +++ b/arch/x86_64/mm/Makefile Sun Feb 9 21:13:34 2003 @@ -2,7 +2,5 @@ # Makefile for the linux i386-specific parts of the memory manager. # -export-objs := pageattr.o - obj-y := init.o fault.o ioremap.o extable.o pageattr.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o diff -Nru a/arch/x86_64/mm/hugetlbpage.c b/arch/x86_64/mm/hugetlbpage.c --- a/arch/x86_64/mm/hugetlbpage.c Sun Feb 9 21:13:32 2003 +++ b/arch/x86_64/mm/hugetlbpage.c Sun Feb 9 21:13:32 2003 @@ -25,7 +25,6 @@ int htlbpage_max; static long htlbzone_pages; -struct vm_operations_struct hugetlb_vm_ops; static LIST_HEAD(htlbpage_freelist); static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED; @@ -134,6 +133,7 @@ page = pte_page(pte); if (pages) { page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT); + get_page(page); pages[i] = page; } if (vmas) @@ -204,6 +204,7 @@ 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; @@ -227,6 +228,8 @@ + (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; @@ -238,6 +241,9 @@ 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); } @@ -263,11 +269,6 @@ page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER); if (page == NULL) break; - map = page; - for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) { - SetPageReserved(map); - map++; - } spin_lock(&htlbpage_lock); list_add(&page->list, &htlbpage_freelist); htlbpagemem++; @@ -286,8 +287,9 @@ spin_unlock(&htlbpage_lock); map = page; for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) { - map->flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced | - 1 << PG_dirty | 1 << PG_active | 1 << PG_reserved | + map->flags &= ~(1 << PG_locked | 1 << PG_error | + 1 << PG_referenced | + 1 << PG_dirty | 1 << PG_active | 1 << PG_private | 1<< PG_writeback); set_page_count(map, 0); map++; @@ -346,7 +348,8 @@ HPAGE_SIZE/1024); } -static struct page * hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int unused) +static struct page * +hugetlb_nopage(struct vm_area_struct *vma, unsigned long address, int unused) { BUG(); return NULL; diff -Nru a/crypto/Makefile b/crypto/Makefile --- a/crypto/Makefile Sun Feb 9 21:13:36 2003 +++ b/crypto/Makefile Sun Feb 9 21:13:36 2003 @@ -2,8 +2,6 @@ # Cryptographic API # -export-objs := api.o hmac.o - autoload-crypto-$(CONFIG_KMOD) = autoload.o proc-crypto-$(CONFIG_PROC_FS) = proc.o diff -Nru a/crypto/cipher.c b/crypto/cipher.c --- a/crypto/cipher.c Sun Feb 9 21:13:32 2003 +++ b/crypto/cipher.c Sun Feb 9 21:13:32 2003 @@ -4,6 +4,7 @@ * Cipher operations. * * Copyright (c) 2002 James Morris + * Generic scatterwalk code by Adam J. Richter . * * 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 @@ -16,12 +17,22 @@ #include #include #include +#include #include #include #include "internal.h" typedef void (cryptfn_t)(void *, u8 *, const u8 *); -typedef void (procfn_t)(struct crypto_tfm *, u8 *, cryptfn_t, int enc); +typedef void (procfn_t)(struct crypto_tfm *, u8 *, u8*, cryptfn_t, int enc); + +struct scatter_walk { + struct scatterlist *sg; + struct page *page; + void *data; + unsigned int len_this_page; + unsigned int len_this_segment; + unsigned int offset; +}; static inline void xor_64(u8 *a, const u8 *b) { @@ -37,165 +48,191 @@ ((u32 *)a)[3] ^= ((u32 *)b)[3]; } -static inline unsigned int sglen(struct scatterlist *sg, unsigned int nsg) + +/* Define sg_next is an inline routine now in case we want to change + scatterlist to a linked list later. */ +static inline struct scatterlist *sg_next(struct scatterlist *sg) { - unsigned int i, n; - - for (i = 0, n = 0; i < nsg; i++) - n += sg[i].length; - - return n; + return sg + 1; } -/* - * Do not call this unless the total length of all of the fragments - * has been verified as multiple of the block size. - */ -static unsigned int copy_chunks(struct crypto_tfm *tfm, u8 *buf, - struct scatterlist *sg, unsigned int sgidx, - unsigned int rlen, unsigned int *last, int in) -{ - unsigned int i, copied, coff, j, aligned; - unsigned int bsize = crypto_tfm_alg_blocksize(tfm); - - for (i = sgidx, j = copied = 0, aligned = 0 ; copied < bsize; i++) { - unsigned int len = sg[i].length; - unsigned int clen; - char *p; - - if (copied) { - coff = 0; - clen = min(len, bsize - copied); - - if (len == bsize - copied) - aligned = 1; /* last + right aligned */ - - } else { - coff = len - rlen; - clen = rlen; - } +void *which_buf(struct scatter_walk *walk, unsigned int nbytes, void *scratch) +{ + if (nbytes <= walk->len_this_page && + (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <= + PAGE_CACHE_SIZE) + return walk->data; + else + return scratch; +} - p = crypto_kmap(sg[i].page) + sg[i].offset + coff; - - if (in) - memcpy(&buf[copied], p, clen); +static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out) +{ + if (out) + memcpy(sgdata, buf, nbytes); + else + memcpy(buf, sgdata, nbytes); +} + +static void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg) +{ + unsigned int rest_of_page; + + walk->sg = sg; + + walk->page = sg->page; + walk->len_this_segment = sg->length; + + rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1)); + walk->len_this_page = min(sg->length, rest_of_page); + walk->offset = sg->offset; +} + +static void scatterwalk_map(struct scatter_walk *walk, int out) +{ + walk->data = crypto_kmap(walk->page, out) + walk->offset; +} + +static void scatter_page_done(struct scatter_walk *walk, int out, + unsigned int more) +{ + /* walk->data may be pointing the first byte of the next page; + however, we know we transfered at least one byte. So, + walk->data - 1 will be a virutual address in the mapped page. */ + + if (out) + flush_dcache_page(walk->page); + + if (more) { + walk->len_this_segment -= walk->len_this_page; + + if (walk->len_this_segment) { + walk->page++; + walk->len_this_page = min(walk->len_this_segment, + (unsigned)PAGE_CACHE_SIZE); + walk->offset = 0; + } else - memcpy(p, &buf[copied], clen); - - crypto_kunmap(p); - *last = aligned ? 0 : clen; - copied += clen; + scatterwalk_start(walk, sg_next(walk->sg)); } - - return i - sgidx - 2 + aligned; } -static inline unsigned int gather_chunks(struct crypto_tfm *tfm, u8 *buf, - struct scatterlist *sg, - unsigned int sgidx, unsigned int rlen, - unsigned int *last) +static void scatter_done(struct scatter_walk *walk, int out, int more) { - return copy_chunks(tfm, buf, sg, sgidx, rlen, last, 1); + crypto_kunmap(walk->data, out); + if (walk->len_this_page == 0 || !more) + scatter_page_done(walk, out, more); } -static inline unsigned int scatter_chunks(struct crypto_tfm *tfm, u8 *buf, - struct scatterlist *sg, - unsigned int sgidx, unsigned int rlen, - unsigned int *last) +/* + * Do not call this unless the total length of all of the fragments + * has been verified as multiple of the block size. + */ +static int copy_chunks(void *buf, struct scatter_walk *walk, + size_t nbytes, int out) { - return copy_chunks(tfm, buf, sg, sgidx, rlen, last, 0); + if (buf != walk->data) { + while (nbytes > walk->len_this_page) { + memcpy_dir(buf, walk->data, walk->len_this_page, out); + buf += walk->len_this_page; + nbytes -= walk->len_this_page; + + crypto_kunmap(walk->data, out); + scatter_page_done(walk, out, 1); + scatterwalk_map(walk, out); + } + + memcpy_dir(buf, walk->data, nbytes, out); + } + + walk->offset += nbytes; + walk->len_this_page -= nbytes; + walk->len_this_segment -= nbytes; + return 0; } /* - * Generic encrypt/decrypt wrapper for ciphers. - * - * If we find a a remnant at the end of a frag, we have to encrypt or - * decrypt across possibly multiple page boundaries via a temporary - * block, then continue processing with a chunk offset until the end - * of a frag is block aligned. - * - * The code is further complicated by having to remap a page after - * processing a block then yielding. The data will be offset from the - * start of page at the scatterlist offset, the chunking offset (coff) - * and the block offset (boff). + * Generic encrypt/decrypt wrapper for ciphers, handles operations across + * multiple page boundaries by using temporary blocks. In user context, + * the kernel is given a chance to schedule us once per block. */ -static int crypt(struct crypto_tfm *tfm, struct scatterlist *sg, - unsigned int nsg, cryptfn_t crfn, procfn_t prfn, int enc) -{ - unsigned int i, coff; - unsigned int bsize = crypto_tfm_alg_blocksize(tfm); - u8 tmp[bsize]; +static int crypt(struct crypto_tfm *tfm, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, cryptfn_t crfn, procfn_t prfn, int enc) +{ + struct scatter_walk walk_in, walk_out; + const unsigned int bsize = crypto_tfm_alg_blocksize(tfm); + u8 tmp_src[nbytes > src->length ? bsize : 0]; + u8 tmp_dst[nbytes > dst->length ? bsize : 0]; - if (sglen(sg, nsg) % bsize) { + if (!nbytes) + return 0; + + if (nbytes % bsize) { tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN; return -EINVAL; } - for (i = 0, coff = 0; i < nsg; i++) { - unsigned int n = 0, boff = 0; - unsigned int len = sg[i].length - coff; - char *p = crypto_kmap(sg[i].page) + sg[i].offset + coff; - - while (len) { - if (len < bsize) { - crypto_kunmap(p); - n = gather_chunks(tfm, tmp, sg, i, len, &coff); - prfn(tfm, tmp, crfn, enc); - scatter_chunks(tfm, tmp, sg, i, len, &coff); - crypto_yield(tfm); - goto unmapped; - } else { - prfn(tfm, p, crfn, enc); - crypto_kunmap(p); - crypto_yield(tfm); - - /* remap and point to recalculated offset */ - boff += bsize; - p = crypto_kmap(sg[i].page) - + sg[i].offset + coff + boff; - - len -= bsize; - - /* End of frag with no remnant? */ - if (coff && len == 0) - coff = 0; - } - } - crypto_kunmap(p); -unmapped: - i += n; + scatterwalk_start(&walk_in, src); + scatterwalk_start(&walk_out, dst); + + for(;;) { + u8 *src_p, *dst_p; + + scatterwalk_map(&walk_in, 0); + scatterwalk_map(&walk_out, 1); + src_p = which_buf(&walk_in, bsize, tmp_src); + dst_p = which_buf(&walk_out, bsize, tmp_dst); + + nbytes -= bsize; + copy_chunks(src_p, &walk_in, bsize, 0); + + prfn(tfm, dst_p, src_p, crfn, enc); + + scatter_done(&walk_in, 0, nbytes); + + copy_chunks(dst_p, &walk_out, bsize, 1); + scatter_done(&walk_out, 1, nbytes); + + if (!nbytes) + return 0; + + crypto_yield(tfm); } - return 0; } static void cbc_process(struct crypto_tfm *tfm, - u8 *block, cryptfn_t fn, int enc) + u8 *dst, u8 *src, cryptfn_t fn, int enc) { /* Null encryption */ if (!tfm->crt_cipher.cit_iv) return; if (enc) { - tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, block); - fn(tfm->crt_ctx, block, tfm->crt_cipher.cit_iv); - memcpy(tfm->crt_cipher.cit_iv, block, + tfm->crt_u.cipher.cit_xor_block(tfm->crt_cipher.cit_iv, src); + fn(tfm->crt_ctx, dst, tfm->crt_cipher.cit_iv); + memcpy(tfm->crt_cipher.cit_iv, dst, crypto_tfm_alg_blocksize(tfm)); } else { - u8 buf[crypto_tfm_alg_blocksize(tfm)]; + const int need_stack = (src == dst); + u8 stack[need_stack ? crypto_tfm_alg_blocksize(tfm) : 0]; + u8 *buf = need_stack ? stack : dst; - fn(tfm->crt_ctx, buf, block); + fn(tfm->crt_ctx, buf, src); tfm->crt_u.cipher.cit_xor_block(buf, tfm->crt_cipher.cit_iv); - memcpy(tfm->crt_cipher.cit_iv, block, + memcpy(tfm->crt_cipher.cit_iv, src, crypto_tfm_alg_blocksize(tfm)); - memcpy(block, buf, crypto_tfm_alg_blocksize(tfm)); + if (buf != dst) + memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm)); } } -static void ecb_process(struct crypto_tfm *tfm, u8 *block, +static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src, cryptfn_t fn, int enc) { - fn(tfm->crt_ctx, block, block); + fn(tfm->crt_ctx, dst, src); } static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) @@ -211,35 +248,44 @@ } static int ecb_encrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes) { - return crypt(tfm, sg, nsg, + return crypt(tfm, dst, src, nbytes, tfm->__crt_alg->cra_cipher.cia_encrypt, ecb_process, 1); } static int ecb_decrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { - return crypt(tfm, sg, nsg, + return crypt(tfm, dst, src, nbytes, tfm->__crt_alg->cra_cipher.cia_decrypt, ecb_process, 1); } static int cbc_encrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { - return crypt(tfm, sg, nsg, + return crypt(tfm, dst, src, nbytes, tfm->__crt_alg->cra_cipher.cia_encrypt, cbc_process, 1); } static int cbc_decrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { - return crypt(tfm, sg, nsg, + return crypt(tfm, dst, src, nbytes, tfm->__crt_alg->cra_cipher.cia_decrypt, cbc_process, 0); } static int nocrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { return -ENOSYS; } diff -Nru a/crypto/digest.c b/crypto/digest.c --- a/crypto/digest.c Sun Feb 9 21:13:28 2003 +++ b/crypto/digest.c Sun Feb 9 21:13:28 2003 @@ -28,10 +28,10 @@ unsigned int i; for (i = 0; i < nsg; i++) { - char *p = crypto_kmap(sg[i].page) + sg[i].offset; + char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset; tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx, p, sg[i].length); - crypto_kunmap(p); + crypto_kunmap(p, 0); crypto_yield(tfm); } } @@ -49,10 +49,10 @@ tfm->crt_digest.dit_init(tfm); for (i = 0; i < nsg; i++) { - char *p = crypto_kmap(sg[i].page) + sg[i].offset; + char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset; tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx, p, sg[i].length); - crypto_kunmap(p); + crypto_kunmap(p, 0); crypto_yield(tfm); } crypto_digest_final(tfm, out); diff -Nru a/crypto/internal.h b/crypto/internal.h --- a/crypto/internal.h Sun Feb 9 21:13:28 2003 +++ b/crypto/internal.h Sun Feb 9 21:13:28 2003 @@ -16,17 +16,29 @@ #include #include #include +#include -static inline void *crypto_kmap(struct page *page) +static enum km_type km_types[] = { + KM_USER0, + KM_USER1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, +}; + +static inline enum km_type crypto_kmap_type(int out) +{ + return km_types[(in_softirq() ? 2 : 0) + out]; +} + + +static inline void *crypto_kmap(struct page *page, int out) { - return kmap_atomic(page, in_softirq() ? - KM_CRYPTO_SOFTIRQ : KM_CRYPTO_USER); + return kmap_atomic(page, crypto_kmap_type(out)); } -static inline void crypto_kunmap(void *vaddr) +static inline void crypto_kunmap(void *vaddr, int out) { - kunmap_atomic(vaddr, in_softirq() ? - KM_CRYPTO_SOFTIRQ : KM_CRYPTO_USER); + kunmap_atomic(vaddr, crypto_kmap_type(out)); } static inline void crypto_yield(struct crypto_tfm *tfm) diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c --- a/crypto/tcrypt.c Sun Feb 9 21:13:35 2003 +++ b/crypto/tcrypt.c Sun Feb 9 21:13:35 2003 @@ -703,7 +703,7 @@ sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, len); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -746,7 +746,7 @@ sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 8; - ret = crypto_cipher_encrypt(tfm, sg, 2); + ret = crypto_cipher_encrypt(tfm, sg, sg, 16); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -814,7 +814,7 @@ sg[2].offset = ((long) p & ~PAGE_MASK); sg[2].length = 8; - ret = crypto_cipher_encrypt(tfm, sg, 3); + ret = crypto_cipher_encrypt(tfm, sg, sg, 32); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); @@ -890,7 +890,7 @@ sg[3].offset = ((long) p & ~PAGE_MASK); sg[3].length = 18; - ret = crypto_cipher_encrypt(tfm, sg, 4); + ret = crypto_cipher_encrypt(tfm, sg, sg, 24); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); @@ -979,7 +979,7 @@ sg[4].offset = ((long) p & ~PAGE_MASK); sg[4].length = 8; - ret = crypto_cipher_encrypt(tfm, sg, 5); + ret = crypto_cipher_encrypt(tfm, sg, sg, 16); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); @@ -1078,7 +1078,7 @@ sg[7].offset = ((long) p & ~PAGE_MASK); sg[7].length = 1; - ret = crypto_cipher_encrypt(tfm, sg, 8); + ret = crypto_cipher_encrypt(tfm, sg, sg, 8); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1120,7 +1120,7 @@ sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("des_decrypt() failed flags=%x\n", tfm->crt_flags); @@ -1163,7 +1163,7 @@ sg[1].offset = ((long) p & ~PAGE_MASK); sg[1].length = 8; - ret = crypto_cipher_decrypt(tfm, sg, 2); + ret = crypto_cipher_decrypt(tfm, sg, sg, 16); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1220,7 +1220,7 @@ sg[2].offset = ((long) p & ~PAGE_MASK); sg[2].length = 1; - ret = crypto_cipher_decrypt(tfm, sg, 3); + ret = crypto_cipher_decrypt(tfm, sg, sg, 16); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); @@ -1290,7 +1290,7 @@ crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, len); if (ret) { printk("des_cbc_encrypt() failed flags=%x\n", tfm->crt_flags); @@ -1349,7 +1349,7 @@ crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_encrypt(tfm, sg, 2); + ret = crypto_cipher_encrypt(tfm, sg, sg, 24); if (ret) { printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1398,7 +1398,7 @@ crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_blocksize(tfm)); - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, len); if (ret) { printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); @@ -1450,7 +1450,7 @@ crypto_cipher_set_iv(tfm, des_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_decrypt(tfm, sg, 2); + ret = crypto_cipher_decrypt(tfm, sg, sg, 8); if (ret) { printk("des_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1518,7 +1518,7 @@ sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, len); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1561,7 +1561,7 @@ sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = len; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, len); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1624,7 +1624,7 @@ sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = bf_tv[i].plen; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1666,7 +1666,7 @@ sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = bf_tv[i].plen; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1719,7 +1719,7 @@ crypto_cipher_set_iv(tfm, bf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_encrypt() failed flags=%x\n", tfm->crt_flags); @@ -1764,7 +1764,7 @@ crypto_cipher_set_iv(tfm, bf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); @@ -1829,7 +1829,7 @@ sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = tf_tv[i].plen; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1871,7 +1871,7 @@ sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = tf_tv[i].plen; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -1924,7 +1924,7 @@ crypto_cipher_set_iv(tfm, tf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_encrypt() failed flags=%x\n", tfm->crt_flags); @@ -1970,7 +1970,7 @@ crypto_cipher_set_iv(tfm, tf_tv[i].iv, crypto_tfm_alg_ivsize(tfm)); - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("blowfish_cbc_decrypt() failed flags=%x\n", tfm->crt_flags); @@ -2030,7 +2030,7 @@ sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = sizeof(serp_tv[i].plaintext); - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -2070,7 +2070,7 @@ sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = sizeof(serp_tv[i].plaintext); - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -2133,7 +2133,7 @@ sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = aes_tv[i].plen; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("encrypt() failed flags=%x\n", tfm->crt_flags); goto out; @@ -2175,7 +2175,7 @@ sg[0].page = virt_to_page(p); sg[0].offset = ((long) p & ~PAGE_MASK); sg[0].length = aes_tv[i].plen; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, sg[0].length); if (ret) { printk("decrypt() failed flags=%x\n", tfm->crt_flags); goto out; diff -Nru a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c --- a/drivers/acorn/char/pcf8583.c Sun Feb 9 21:13:36 2003 +++ b/drivers/acorn/char/pcf8583.c Sun Feb 9 21:13:36 2003 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "pcf8583.h" diff -Nru a/drivers/acorn/scsi/Makefile b/drivers/acorn/scsi/Makefile --- a/drivers/acorn/scsi/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/acorn/scsi/Makefile Sun Feb 9 21:13:28 2003 @@ -2,7 +2,6 @@ # Makefile for drivers/acorn/scsi # -export-objs := fas216.o queue.o msgqueue.o acornscsi_mod-objs := acornscsi.o acornscsi-io.o obj-$(CONFIG_SCSI_ACORNSCSI_3) += acornscsi_mod.o queue.o msgqueue.o diff -Nru a/drivers/acorn/scsi/acornscsi.c b/drivers/acorn/scsi/acornscsi.c --- a/drivers/acorn/scsi/acornscsi.c Sun Feb 9 21:13:32 2003 +++ b/drivers/acorn/scsi/acornscsi.c Sun Feb 9 21:13:32 2003 @@ -3110,7 +3110,8 @@ .remove = __devexit_p(acornscsi_remove), .id_table = acornscsi_cids, .drv = { - .name = "acornscsi", + .devclass = &shost_devclass, + .name = "acornscsi", }, }; diff -Nru a/drivers/acorn/scsi/arxescsi.c b/drivers/acorn/scsi/arxescsi.c --- a/drivers/acorn/scsi/arxescsi.c Sun Feb 9 21:13:32 2003 +++ b/drivers/acorn/scsi/arxescsi.c Sun Feb 9 21:13:32 2003 @@ -40,33 +40,18 @@ #include "fas216.h" struct arxescsi_info { - FAS216_Info info; - - /* other info... */ - unsigned int cstatus; /* card status register */ - unsigned int dmaarea; /* Pseudo DMA area */ + FAS216_Info info; + struct expansion_card *ec; }; -#define CSTATUS_IRQ (1 << 0) -#define CSTATUS_DRQ (1 << 0) +#define DMADATA_OFFSET (0x200) -#ifndef CAN_QUEUE -#define CAN_QUEUE 1 -#endif - -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 1 -#endif +#define DMASTAT_OFFSET (0x600) +#define DMASTAT_DRQ (1 << 0) -/* Hmm - this should go somewhere else */ -#define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE) +#define CSTATUS_IRQ (1 << 0) -/* - * Version - */ -#define VER_MAJOR 0 -#define VER_MINOR 1 -#define VER_PATCH 1 +#define VERSION "1.10 (23/01/2003 2.5.57)" /* * Function: int arxescsi_dma_setup(host, SCpnt, direction, min_type) @@ -87,44 +72,7 @@ return fasdma_pseudo; } - - -/* Faster transfer routines, written by SH to speed up the loops */ - -static inline unsigned char getb(unsigned int address, unsigned int reg) -{ - unsigned char value; - - __asm__ __volatile__( - "ldrb %0, [%1, %2, lsl #5]" - : "=r" (value) - : "r" (address), "r" (reg) ); - return value; -} - -static inline unsigned int getw(unsigned int address, unsigned int reg) -{ - unsigned int value; - - __asm__ __volatile__( - "ldr %0, [%1, %2, lsl #5]\n\t" - "mov %0, %0, lsl #16\n\t" - "mov %0, %0, lsr #16" - : "=r" (value) - : "r" (address), "r" (reg) ); - return value; -} - -static inline void putw(unsigned int address, unsigned int reg, unsigned long value) -{ - __asm__ __volatile__( - "mov %0, %0, lsl #16\n\t" - "str %0, [%1, %2, lsl #5]" - : - : "r" (value), "r" (address), "r" (reg) ); -} - -void arxescsi_pseudo_dma_write(unsigned char *addr, unsigned int io) +static void arxescsi_pseudo_dma_write(unsigned char *addr, unsigned char *base) { __asm__ __volatile__( " stmdb sp!, {r0-r12}\n" @@ -149,7 +97,7 @@ " bne .loop_1\n" " ldmia sp!, {r0-r12}\n" : - : "r" (addr), "r" (io) ); + : "r" (addr), "r" (base)); } /* @@ -160,40 +108,41 @@ * direction - DMA on to/off of card * transfer - minimum number of bytes we expect to transfer */ -void arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, - fasdmadir_t direction, int transfer) +static void +arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, + fasdmadir_t direction, int transfer) { struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata; - unsigned int length, io, error=0; + unsigned int length, error = 0; + unsigned char *base = info->info.scsi.io_base; unsigned char *addr; length = SCp->this_residual; addr = SCp->ptr; - io = __ioaddr(host->io_port); if (direction == DMA_OUT) { unsigned int word; while (length > 256) { - if (getb(io, 4) & STAT_INT) { - error=1; + if (readb(base + 0x80) & STAT_INT) { + error = 1; break; } - arxescsi_pseudo_dma_write(addr, io); + arxescsi_pseudo_dma_write(addr, base); addr += 256; length -= 256; } if (!error) while (length > 0) { - if (getb(io, 4) & STAT_INT) + if (readb(base + 0x80) & STAT_INT) break; - if (!(getb(io, 48) & CSTATUS_IRQ)) + if (!(readb(base + DMASTAT_OFFSET) & DMASTAT_DRQ)) continue; word = *addr | *(addr + 1) << 8; - putw(io, 16, word); + writew(word, base + DMADATA_OFFSET); if (length > 1) { addr += 2; length -= 2; @@ -206,15 +155,15 @@ else { if (transfer && (transfer & 255)) { while (length >= 256) { - if (getb(io, 4) & STAT_INT) { - error=1; + if (readb(base + 0x80) & STAT_INT) { + error = 1; break; } - if (!(getb(io, 48) & CSTATUS_IRQ)) + if (!(readb(base + DMASTAT_OFFSET) & DMASTAT_DRQ)) continue; - insw(info->dmaarea, addr, 256 >> 1); + readsw(base + DMADATA_OFFSET, addr, 256 >> 1); addr += 256; length -= 256; } @@ -224,13 +173,13 @@ while (length > 0) { unsigned long word; - if (getb(io, 4) & STAT_INT) + if (readb(base + 0x80) & STAT_INT) break; - if (!(getb(io, 48) & CSTATUS_IRQ)) + if (!(readb(base + DMASTAT_OFFSET) & DMASTAT_DRQ)) continue; - word = getw(io, 16); + word = readw(base + DMADATA_OFFSET); *addr++ = word; if (--length > 0) { *addr++ = word >> 8; @@ -259,15 +208,14 @@ * Params : host - driver host structure to return info for. * Returns : pointer to a static buffer containing null terminated string. */ -const char *arxescsi_info(struct Scsi_Host *host) +static const char *arxescsi_info(struct Scsi_Host *host) { struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata; - static char string[100], *p; + static char string[150]; - p = string; - p += sprintf(p, "%s ", host->hostt->name); - p += fas216_info(&info->info, p); - p += sprintf(p, "v%d.%d.%d", VER_MAJOR, VER_MINOR, VER_PATCH); + sprintf(string, "%s (%s) in slot %d v%s", + host->hostt->name, info->info.scsi.type, info->ec->slot_no, + VERSION); return string; } @@ -286,8 +234,9 @@ * inout - 0 for reading, 1 for writing. * Returns : length of data written to buffer. */ -int arxescsi_proc_info(char *buffer, char **start, off_t offset, - int length, int host_no, int inout) +static int +arxescsi_proc_info(char *buffer, char **start, off_t offset, int length, + int host_no, int inout) { int pos, begin; struct Scsi_Host *host; @@ -303,9 +252,7 @@ return -EINVAL; begin = 0; - pos = sprintf(buffer, - "ARXE 16-bit SCSI driver version %d.%d.%d\n", - VER_MAJOR, VER_MINOR, VER_PATCH); + pos = sprintf(buffer, "ARXE 16-bit SCSI driver v%s\n", VERSION); pos += fas216_print_host(&info->info, buffer + pos); pos += fas216_print_stats(&info->info, buffer + pos); @@ -343,7 +290,7 @@ .can_queue = 0, .this_id = 7, .sg_tablesize = SG_ALL, - .cmd_per_lun = CMD_PER_LUN, + .cmd_per_lun = 1, .use_clustering = DISABLE_CLUSTERING, .proc_name = "arxescsi", }; @@ -352,21 +299,41 @@ arxescsi_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; - struct arxescsi_info *info; - int ret = -ENOMEM; + struct arxescsi_info *info; + unsigned long resbase, reslen; + unsigned char *base; + int ret; - host = scsi_register(&arxescsi_template, sizeof(struct arxescsi_info)); - if (!host) + resbase = ecard_resource_start(ec, ECARD_RES_MEMC); + reslen = ecard_resource_len(ec, ECARD_RES_MEMC); + + if (!request_mem_region(resbase, reslen, "arxescsi")) { + ret = -EBUSY; goto out; + } - host->io_port = ecard_address(ec, ECARD_MEMC, 0) + 0x0800; + base = ioremap(resbase, reslen); + if (!base) { + ret = -ENOMEM; + goto out_region; + } + + host = scsi_register(&arxescsi_template, sizeof(struct arxescsi_info)); + if (!host) { + ret = -ENOMEM; + goto out_unmap; + } + + host->base = (unsigned long)base; host->irq = NO_IRQ; host->dma_channel = NO_DMA; info = (struct arxescsi_info *)host->hostdata; - info->info.scsi.io_port = host->io_port; + info->ec = ec; + + info->info.scsi.io_base = base + 0x2000; info->info.scsi.irq = host->irq; - info->info.scsi.io_shift = 3; + info->info.scsi.io_shift = 5; info->info.ifcfg.clockrate = 24; /* MHz */ info->info.ifcfg.select_timeout = 255; info->info.ifcfg.asyncperiod = 200; /* ns */ @@ -374,39 +341,29 @@ info->info.ifcfg.cntl3 = CNTL3_FASTSCSI | CNTL3_FASTCLK; info->info.ifcfg.disconnect_ok = 0; info->info.ifcfg.wide_max_size = 0; + info->info.ifcfg.capabilities = FASCAP_PSEUDODMA; info->info.dma.setup = arxescsi_dma_setup; info->info.dma.pseudo = arxescsi_dma_pseudo; info->info.dma.stop = arxescsi_dma_stop; - info->dmaarea = host->io_port + 128; - info->cstatus = host->io_port + 384; - ec->irqaddr = (unsigned char *)BUS_ADDR(host->io_port); + ec->irqaddr = base; ec->irqmask = CSTATUS_IRQ; - if (!request_region(host->io_port, 120, "arxescsi-fas")) { - ret = -EBUSY; - goto out_free; - } - - if (!request_region(host->io_port + 128, 384, "arxescsi-dma")) { - ret = -EBUSY; - goto out_release; - } - - printk("scsi%d: Has no interrupts - using polling mode\n", - host->host_no); + ret = fas216_init(host); + if (ret) + goto out_unregister; - fas216_init(host); - - ret = scsi_add_host(host, &ec->dev); + ret = fas216_add(host, &ec->dev); if (ret == 0) goto out; - release_region(host->io_port + 128, 384); - out_release: - release_region(host->io_port, 120); - out_free: + fas216_release(host); + out_unregister: scsi_unregister(host); + out_unmap: + iounmap(base); + out_region: + release_mem_region(resbase, reslen); out: return ret; } @@ -414,13 +371,19 @@ static void __devexit arxescsi_remove(struct expansion_card *ec) { struct Scsi_Host *host = ecard_get_drvdata(ec); + unsigned long resbase, reslen; ecard_set_drvdata(ec, NULL); - scsi_remove_host(host); - fas216_release(host); + fas216_remove(host); + + iounmap((void *)host->base); + + resbase = ecard_resource_start(ec, ECARD_RES_MEMC); + reslen = ecard_resource_len(ec, ECARD_RES_MEMC); - release_region(host->io_port + 128, 384); - release_region(host->io_port, 120); + release_mem_region(resbase, reslen); + + fas216_release(host); scsi_unregister(host); } @@ -434,7 +397,8 @@ .remove = __devexit_p(arxescsi_remove), .id_table = arxescsi_cids, .drv = { - .name = "arxescsi", + .devclass = &shost_devclass, + .name = "arxescsi", }, }; diff -Nru a/drivers/acorn/scsi/cumana_1.c b/drivers/acorn/scsi/cumana_1.c --- a/drivers/acorn/scsi/cumana_1.c Sun Feb 9 21:13:29 2003 +++ b/drivers/acorn/scsi/cumana_1.c Sun Feb 9 21:13:29 2003 @@ -334,7 +334,8 @@ .remove = __devexit_p(cumanascsi1_remove), .id_table = cumanascsi1_cids, .drv = { - .name = "cumanascsi1", + .devclass = &shost_devclass, + .name = "cumanascsi1", }, }; diff -Nru a/drivers/acorn/scsi/cumana_2.c b/drivers/acorn/scsi/cumana_2.c --- a/drivers/acorn/scsi/cumana_2.c Sun Feb 9 21:13:34 2003 +++ b/drivers/acorn/scsi/cumana_2.c Sun Feb 9 21:13:34 2003 @@ -41,12 +41,12 @@ #include -#define CUMANASCSI2_STATUS (0) +#define CUMANASCSI2_STATUS (0x0000) #define STATUS_INT (1 << 0) #define STATUS_DRQ (1 << 1) #define STATUS_LATCHED (1 << 3) -#define CUMANASCSI2_ALATCH (5) +#define CUMANASCSI2_ALATCH (0x0014) #define ALATCH_ENA_INT (3) #define ALATCH_DIS_INT (2) #define ALATCH_ENA_TERM (5) @@ -58,11 +58,10 @@ #define ALATCH_DMA_OUT (15) #define ALATCH_DMA_IN (14) -#define CUMANASCSI2_PSEUDODMA (0x80) +#define CUMANASCSI2_PSEUDODMA (0x0200) -#define CUMANASCSI2_FAS216_OFFSET (0xc0) -#define CUMANASCSI2_FAS216_SHIFT 0 -#define CUMANASCSI2_FAS216_SIZE (16) +#define CUMANASCSI2_FAS216_OFFSET (0x0300) +#define CUMANASCSI2_FAS216_SHIFT 2 /* * Version @@ -77,13 +76,14 @@ #define NR_SG 256 struct cumanascsi2_info { - FAS216_Info info; + FAS216_Info info; + struct expansion_card *ec; - unsigned int status; /* card status register */ - unsigned int alatch; /* Control register */ - unsigned int terms; /* Terminator state */ - unsigned int dmaarea; /* Pseudo DMA area */ - struct scatterlist sg[NR_SG]; /* Scatter DMA list */ + void *status; /* card status register */ + void *alatch; /* Control register */ + unsigned int terms; /* Terminator state */ + void *dmaarea; /* Pseudo DMA area */ + struct scatterlist sg[NR_SG]; /* Scatter DMA list */ }; #define CSTATUS_IRQ (1 << 0) @@ -97,8 +97,7 @@ static void cumanascsi_2_irqenable(struct expansion_card *ec, int irqnr) { - unsigned int port = (unsigned int)ec->irq_data; - outb(ALATCH_ENA_INT, port); + writeb(ALATCH_ENA_INT, ec->irq_data); } /* Prototype: void cumanascsi_2_irqdisable(ec, irqnr) @@ -109,8 +108,7 @@ static void cumanascsi_2_irqdisable(struct expansion_card *ec, int irqnr) { - unsigned int port = (unsigned int)ec->irq_data; - outb(ALATCH_DIS_INT, port); + writeb(ALATCH_DIS_INT, ec->irq_data); } static const expansioncard_ops_t cumanascsi_2_ops = { @@ -130,10 +128,10 @@ if (on_off) { info->terms = 1; - outb (ALATCH_ENA_TERM, info->alatch); + writeb(ALATCH_ENA_TERM, info->alatch); } else { info->terms = 0; - outb (ALATCH_DIS_TERM, info->alatch); + writeb(ALATCH_DIS_TERM, info->alatch); } } @@ -146,9 +144,9 @@ static void cumanascsi_2_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct Scsi_Host *host = (struct Scsi_Host *)dev_id; + struct cumanascsi2_info *info = dev_id; - fas216_intr(host); + fas216_intr(&info->info); } /* Prototype: fasdmatype_t cumanascsi_2_dma_setup(host, SCpnt, direction, min_type) @@ -167,7 +165,7 @@ struct device *dev = scsi_get_device(host); int dmach = host->dma_channel; - outb(ALATCH_DIS_DMA, info->alatch); + writeb(ALATCH_DIS_DMA, info->alatch); if (dmach != NO_DMA && (min_type == fasdma_real_all || SCp->this_residual >= 512)) { @@ -188,11 +186,11 @@ disable_dma(dmach); set_dma_sg(dmach, info->sg, bufs + 1); - outb(alatch_dir, info->alatch); + writeb(alatch_dir, info->alatch); set_dma_mode(dmach, dma_dir); enable_dma(dmach); - outb(ALATCH_ENA_DMA, info->alatch); - outb(ALATCH_DIS_BIT32, info->alatch); + writeb(ALATCH_ENA_DMA, info->alatch); + writeb(ALATCH_DIS_BIT32, info->alatch); return fasdma_real_all; } @@ -226,7 +224,7 @@ #if 0 while (length > 1) { unsigned long word; - unsigned int status = inb(info->status); + unsigned int status = readb(info->status); if (status & STATUS_INT) goto end; @@ -235,7 +233,7 @@ continue; word = *addr | *(addr + 1) << 8; - outw (info->dmaarea); + writew(word, info->dmaarea); addr += 2; length -= 2; } @@ -245,15 +243,15 @@ else { if (transfer && (transfer & 255)) { while (length >= 256) { - unsigned int status = inb(info->status); + unsigned int status = readb(info->status); if (status & STATUS_INT) - goto end; + return; if (!(status & STATUS_DRQ)) continue; - insw(info->dmaarea, addr, 256 >> 1); + readsw(info->dmaarea, addr, 256 >> 1); addr += 256; length -= 256; } @@ -261,15 +259,15 @@ while (length > 0) { unsigned long word; - unsigned int status = inb(info->status); + unsigned int status = readb(info->status); if (status & STATUS_INT) - goto end; + return; if (!(status & STATUS_DRQ)) continue; - word = inw (info->dmaarea); + word = readw(info->dmaarea); *addr++ = word; if (--length > 0) { *addr++ = word >> 8; @@ -277,8 +275,6 @@ } } } - -end: } /* Prototype: int cumanascsi_2_dma_stop(host, SCpnt) @@ -291,7 +287,7 @@ { struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; if (host->dma_channel != NO_DMA) { - outb(ALATCH_DIS_DMA, info->alatch); + writeb(ALATCH_DIS_DMA, info->alatch); disable_dma(host->dma_channel); } } @@ -304,13 +300,11 @@ const char *cumanascsi_2_info(struct Scsi_Host *host) { struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; - static char string[100], *p; + static char string[150]; - p = string; - p += sprintf(p, "%s ", host->hostt->name); - p += fas216_info(&info->info, p); - p += sprintf(p, "v%s terminators o%s", - VERSION, info->terms ? "n" : "ff"); + sprintf(string, "%s (%s) in slot %d v%s terminators o%s", + host->hostt->name, info->info.scsi.type, info->ec->slot_no, + VERSION, info->terms ? "n" : "ff"); return string; } @@ -377,10 +371,7 @@ info = (struct cumanascsi2_info *)host->hostdata; begin = 0; - pos = sprintf(buffer, - "Cumana SCSI II driver version v%s\n", - VERSION); - + pos = sprintf(buffer, "Cumana SCSI II driver v%s\n", VERSION); pos += fas216_print_host(&info->info, buffer + pos); pos += sprintf(buffer + pos, "Term : o%s\n", info->terms ? "n" : "ff"); @@ -440,38 +431,52 @@ cumanascsi2_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; - struct cumanascsi2_info *info; - int ret = -ENOMEM; + struct cumanascsi2_info *info; + unsigned long resbase, reslen; + unsigned char *base; + int ret; - host = scsi_register(&cumanascsi2_template, sizeof (struct cumanascsi2_info)); - if (!host) + resbase = ecard_resource_start(ec, ECARD_RES_MEMC); + reslen = ecard_resource_len(ec, ECARD_RES_MEMC); + + if (!request_mem_region(resbase, reslen, "cumanascsi2")) { + ret = -EBUSY; goto out; + } - host->io_port = ecard_address(ec, ECARD_MEMC, 0); - host->irq = ec->irq; - host->dma_channel = ec->dma; + base = ioremap(resbase, reslen); + if (!base) { + ret = -ENOMEM; + goto out_region; + } - if (!request_region(host->io_port + CUMANASCSI2_FAS216_OFFSET, - CUMANASCSI2_FAS216_SIZE, "cumanascsi2-fas")) { - ret = -EBUSY; - goto out_free; + host = scsi_register(&cumanascsi2_template, + sizeof(struct cumanascsi2_info)); + if (!host) { + ret = -ENOMEM; + goto out_unmap; } + host->base = (unsigned long)base; + host->irq = ec->irq; + host->dma_channel = ec->dma; + ecard_set_drvdata(ec, host); info = (struct cumanascsi2_info *)host->hostdata; - info->dmaarea = host->io_port + CUMANASCSI2_PSEUDODMA; - info->status = host->io_port + CUMANASCSI2_STATUS; - info->alatch = host->io_port + CUMANASCSI2_ALATCH; + info->ec = ec; + info->dmaarea = base + CUMANASCSI2_PSEUDODMA; + info->status = base + CUMANASCSI2_STATUS; + info->alatch = base + CUMANASCSI2_ALATCH; - ec->irqaddr = (unsigned char *)ioaddr(info->status); + ec->irqaddr = info->status; ec->irqmask = STATUS_INT; - ec->irq_data = (void *)info->alatch; - ec->ops = (expansioncard_ops_t *)&cumanascsi_2_ops; + ec->irq_data = base + CUMANASCSI2_ALATCH; + ec->ops = &cumanascsi_2_ops; cumanascsi_2_terminator_ctl(host, term[ec->slot_no]); - info->info.scsi.io_port = host->io_port + CUMANASCSI2_FAS216_OFFSET; + info->info.scsi.io_base = base + CUMANASCSI2_FAS216_OFFSET; info->info.scsi.io_shift = CUMANASCSI2_FAS216_SHIFT; info->info.scsi.irq = host->irq; info->info.ifcfg.clockrate = 40; /* MHz */ @@ -481,16 +486,21 @@ info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK; info->info.ifcfg.disconnect_ok = 1; info->info.ifcfg.wide_max_size = 0; + info->info.ifcfg.capabilities = FASCAP_PSEUDODMA; info->info.dma.setup = cumanascsi_2_dma_setup; info->info.dma.pseudo = cumanascsi_2_dma_pseudo; info->info.dma.stop = cumanascsi_2_dma_stop; + ret = fas216_init(host); + if (ret) + goto out_free; + ret = request_irq(host->irq, cumanascsi_2_intr, - SA_INTERRUPT, "cumanascsi2", host); + SA_INTERRUPT, "cumanascsi2", info); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, host->irq, ret); - goto out_region; + goto out_release; } if (host->dma_channel != NO_DMA) { @@ -500,26 +510,30 @@ host->dma_channel = NO_DMA; } else { set_dma_speed(host->dma_channel, 180); + info->info.ifcfg.capabilities |= FASCAP_DMA; } } - fas216_init(host); - - ret = scsi_add_host(host, &ec->dev); + ret = fas216_add(host, &ec->dev); if (ret == 0) goto out; - fas216_release(host); - if (host->dma_channel != NO_DMA) free_dma(host->dma_channel); free_irq(host->irq, host); - out_region: - release_region(host->io_port + CUMANASCSI2_FAS216_OFFSET, - CUMANASCSI2_FAS216_SIZE); + + out_release: + fas216_release(host); + out_free: scsi_unregister(host); + out_unmap: + iounmap(base); + + out_region: + release_mem_region(resbase, reslen); + out: return ret; } @@ -527,17 +541,24 @@ static void __devexit cumanascsi2_remove(struct expansion_card *ec) { struct Scsi_Host *host = ecard_get_drvdata(ec); + struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; + unsigned long resbase, reslen; ecard_set_drvdata(ec, NULL); - scsi_remove_host(host); - fas216_release(host); + fas216_remove(host); if (host->dma_channel != NO_DMA) free_dma(host->dma_channel); - free_irq(host->irq, host); - release_region(host->io_port + CUMANASCSI2_FAS216_OFFSET, - CUMANASCSI2_FAS216_SIZE); + free_irq(host->irq, info); + iounmap((void *)host->base); + + resbase = ecard_resource_start(ec, ECARD_RES_MEMC); + reslen = ecard_resource_len(ec, ECARD_RES_MEMC); + + release_mem_region(resbase, reslen); + + fas216_release(host); scsi_unregister(host); } @@ -551,7 +572,8 @@ .remove = __devexit_p(cumanascsi2_remove), .id_table = cumanascsi2_cids, .drv = { - .name = "cumanascsi2", + .devclass = &shost_devclass, + .name = "cumanascsi2", }, }; diff -Nru a/drivers/acorn/scsi/eesox.c b/drivers/acorn/scsi/eesox.c --- a/drivers/acorn/scsi/eesox.c Sun Feb 9 21:13:37 2003 +++ b/drivers/acorn/scsi/eesox.c Sun Feb 9 21:13:37 2003 @@ -1,7 +1,7 @@ /* * linux/drivers/acorn/scsi/eesox.c * - * Copyright (C) 1997-2002 Russell King + * Copyright (C) 1997-2003 Russell King * * 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 @@ -47,25 +47,21 @@ #include -#define EESOX_FAS216_OFFSET 0xc00 -#define EESOX_FAS216_SHIFT 3 -#define EESOX_FAS216_SIZE (16 << EESOX_FAS216_SHIFT) +#define EESOX_FAS216_OFFSET 0x3000 +#define EESOX_FAS216_SHIFT 5 -#define EESOX_STATUS 0xa00 +#define EESOX_DMASTAT 0x2800 #define EESOX_STAT_INTR 0x01 #define EESOX_STAT_DMA 0x02 -#define EESOX_CONTROL 0xa00 +#define EESOX_CONTROL 0x2800 #define EESOX_INTR_ENABLE 0x04 #define EESOX_TERM_ENABLE 0x02 #define EESOX_RESET 0x01 -#define EESOX_DMA_OFFSET 0xe00 +#define EESOX_DMADATA 0x3800 -/* - * Version - */ -#define VERSION "1.00 (13/11/2002 2.5.47)" +#define VERSION "1.10 (17/01/2003 2.5.59)" /* * Use term=0,1,0,0,0 to turn terminators on/off @@ -75,12 +71,12 @@ #define NR_SG 256 struct eesoxscsi_info { - FAS216_Info info; + FAS216_Info info; + struct expansion_card *ec; - unsigned int ctl_port; - unsigned int control; - unsigned int dmaarea; /* Pseudo DMA area */ - struct scatterlist sg[NR_SG]; /* Scatter DMA list */ + void *ctl_port; + unsigned int control; + struct scatterlist sg[NR_SG]; /* Scatter DMA list */ }; /* Prototype: void eesoxscsi_irqenable(ec, irqnr) @@ -95,7 +91,7 @@ info->control |= EESOX_INTR_ENABLE; - outb(info->control, info->ctl_port); + writeb(info->control, info->ctl_port); } /* Prototype: void eesoxscsi_irqdisable(ec, irqnr) @@ -110,7 +106,7 @@ info->control &= ~EESOX_INTR_ENABLE; - outb(info->control, info->ctl_port); + writeb(info->control, info->ctl_port); } static const expansioncard_ops_t eesoxscsi_ops = { @@ -135,7 +131,7 @@ else info->control &= ~EESOX_TERM_ENABLE; - outb(info->control, info->ctl_port); + writeb(info->control, info->ctl_port); spin_unlock_irqrestore(host->host_lock, flags); } @@ -148,9 +144,9 @@ static void eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct Scsi_Host *host = (struct Scsi_Host *)dev_id; + struct eesoxscsi_info *info = dev_id; - fas216_intr(host); + fas216_intr(&info->info); } /* Prototype: fasdmatype_t eesoxscsi_dma_setup(host, SCpnt, direction, min_type) @@ -198,93 +194,164 @@ return fasdma_pseudo; } +static void eesoxscsi_buffer_in(void *buf, int length, void *base) +{ + const void *reg_fas = base + EESOX_FAS216_OFFSET; + const void *reg_dmastat = base + EESOX_DMASTAT; + const void *reg_dmadata = base + EESOX_DMADATA; + const register unsigned long mask = 0xffff; + + do { + unsigned int status; + + /* + * Interrupt request? + */ + status = readb(reg_fas + (REG_STAT << EESOX_FAS216_SHIFT)); + if (status & STAT_INT) + break; + + /* + * DMA request active? + */ + status = readb(reg_dmastat); + if (!(status & EESOX_STAT_DMA)) + continue; + + /* + * Get number of bytes in FIFO + */ + status = readb(reg_fas + (REG_CFIS << EESOX_FAS216_SHIFT)) & CFIS_CF; + if (status > 16) + status = 16; + if (status > length) + status = length; + + /* + * Align buffer. + */ + if (((u32)buf) & 2 && status >= 2) { + *((u16 *)buf)++ = readl(reg_dmadata); + status -= 2; + length -= 2; + } + + if (status >= 8) { + unsigned long l1, l2; + + l1 = readl(reg_dmadata) & mask; + l1 |= readl(reg_dmadata) << 16; + l2 = readl(reg_dmadata) & mask; + l2 |= readl(reg_dmadata) << 16; + *((u32 *)buf)++ = l1; + *((u32 *)buf)++ = l2; + length -= 8; + continue; + } + + if (status >= 4) { + unsigned long l1; + + l1 = readl(reg_dmadata) & mask; + l1 |= readl(reg_dmadata) << 16; + + *((u32 *)buf)++ = l1; + length -= 4; + continue; + } + + if (status >= 2) { + *((u16 *)buf)++ = readl(reg_dmadata); + length -= 2; + } + } while (length); +} + +static void eesoxscsi_buffer_out(void *buf, int length, void *base) +{ + const void *reg_fas = base + EESOX_FAS216_OFFSET; + const void *reg_dmastat = base + EESOX_DMASTAT; + const void *reg_dmadata = base + EESOX_DMADATA; + + do { + unsigned int status; + + /* + * Interrupt request? + */ + status = readb(reg_fas + (REG_STAT << EESOX_FAS216_SHIFT)); + if (status & STAT_INT) + break; + + /* + * DMA request active? + */ + status = readb(reg_dmastat); + if (!(status & EESOX_STAT_DMA)) + continue; + + /* + * Get number of bytes in FIFO + */ + status = readb(reg_fas + (REG_CFIS << EESOX_FAS216_SHIFT)) & CFIS_CF; + if (status > 16) + status = 16; + status = 16 - status; + if (status > length) + status = length; + status &= ~1; + + /* + * Align buffer. + */ + if (((u32)buf) & 2 && status >= 2) { + writel(*((u16 *)buf)++ << 16, reg_dmadata); + status -= 2; + length -= 2; + } + + if (status >= 8) { + unsigned long l1, l2; + + l1 = *((u32 *)buf)++; + l2 = *((u32 *)buf)++; + + writel(l1 << 16, reg_dmadata); + writel(l1, reg_dmadata); + writel(l2 << 16, reg_dmadata); + writel(l2, reg_dmadata); + length -= 8; + continue; + } + + if (status >= 4) { + unsigned long l1; + + l1 = *((u32 *)buf)++; + + writel(l1 << 16, reg_dmadata); + writel(l1, reg_dmadata); + length -= 4; + continue; + } + + if (status >= 2) { + writel(*((u16 *)buf)++ << 16, reg_dmadata); + length -= 2; + } + } while (length); +} + static void eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t dir, int transfer_size) { - struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; - unsigned int status; - unsigned int length = SCp->this_residual; - union { - unsigned char *c; - unsigned short *s; - unsigned long *l; - } buffer; - - buffer.c = SCp->ptr; - - status = inb(host->io_port + EESOX_STATUS); + void *base = (void *)host->base; if (dir == DMA_IN) { - while (length > 8) { - if (status & EESOX_STAT_DMA) { - unsigned long l1, l2; - - l1 = inw(info->dmaarea); - l1 |= inw(info->dmaarea) << 16; - l2 = inw(info->dmaarea); - l2 |= inw(info->dmaarea) << 16; - *buffer.l++ = l1; - *buffer.l++ = l2; - length -= 8; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); - } - - while (length > 1) { - if (status & EESOX_STAT_DMA) { - *buffer.s++ = inw(info->dmaarea); - length -= 2; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); - } - - while (length > 0) { - if (status & EESOX_STAT_DMA) { - *buffer.c++ = inw(info->dmaarea); - length -= 1; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); - } + eesoxscsi_buffer_in(SCp->ptr, SCp->this_residual, base); } else { - while (length > 8) { - if (status & EESOX_STAT_DMA) { - unsigned long l1, l2; - - l1 = *buffer.l++; - l2 = *buffer.l++; - - outw(l1, info->dmaarea); - outw(l1 >> 16, info->dmaarea); - outw(l2, info->dmaarea); - outw(l2 >> 16, info->dmaarea); - length -= 8; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); - } - - while (length > 1) { - if (status & EESOX_STAT_DMA) { - outw(*buffer.s++, info->dmaarea); - length -= 2; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); - } - - while (length > 0) { - if (status & EESOX_STAT_DMA) { - outw(*buffer.c++, info->dmaarea); - length -= 1; - } else if (status & EESOX_STAT_INTR) - goto end; - status = inb(host->io_port + EESOX_STATUS); - } + eesoxscsi_buffer_out(SCp->ptr, SCp->this_residual, base); } -end: } /* Prototype: int eesoxscsi_dma_stop(host, SCpnt) @@ -307,14 +374,11 @@ const char *eesoxscsi_info(struct Scsi_Host *host) { struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; - static char string[100], *p; + static char string[150]; - p = string; - p += sprintf(p, "%s ", host->hostt->name); - p += fas216_info(&info->info, p); - p += sprintf(p, "v%s terminators o%s", - VERSION, - info->control & EESOX_TERM_ENABLE ? "n" : "ff"); + sprintf(string, "%s (%s) in slot %d v%s terminators o%s", + host->hostt->name, info->info.scsi.type, info->ec->slot_no, + VERSION, info->control & EESOX_TERM_ENABLE ? "n" : "ff"); return string; } @@ -381,9 +445,7 @@ info = (struct eesoxscsi_info *)host->hostdata; begin = 0; - pos = sprintf(buffer, - "EESOX SCSI driver version v%s\n", - VERSION); + pos = sprintf(buffer, "EESOX SCSI driver v%s\n", VERSION); pos += fas216_print_host(&info->info, buffer + pos); pos += sprintf(buffer + pos, "Term : o%s\n", info->control & EESOX_TERM_ENABLE ? "n" : "ff"); @@ -417,6 +479,39 @@ return pos; } +static ssize_t eesoxscsi_show_term(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + struct Scsi_Host *host = ecard_get_drvdata(ec); + struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; + + return sprintf(buf, "%d\n", info->control & EESOX_TERM_ENABLE ? 1 : 0); +} + +static ssize_t eesoxscsi_store_term(struct device *dev, const char *buf, size_t len) +{ + struct expansion_card *ec = ECARD_DEV(dev); + struct Scsi_Host *host = ecard_get_drvdata(ec); + struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; + unsigned long flags; + + if (len > 1) { + spin_lock_irqsave(host->host_lock, flags); + if (buf[0] != '0') { + info->control |= EESOX_TERM_ENABLE; + } else { + info->control &= ~EESOX_TERM_ENABLE; + } + writeb(info->control, info->ctl_port); + spin_unlock_irqrestore(host->host_lock, flags); + } + + return len; +} + +static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR, + eesoxscsi_show_term, eesoxscsi_store_term); + static Scsi_Host_Template eesox_template = { .module = THIS_MODULE, .proc_info = eesoxscsi_proc_info, @@ -440,57 +535,75 @@ eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; - struct eesoxscsi_info *info; - int ret = -ENOMEM; + struct eesoxscsi_info *info; + unsigned long resbase, reslen; + unsigned char *base; + int ret; - host = scsi_register(&eesox_template, - sizeof(struct eesoxscsi_info)); - if (!host) + resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST); + reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST); + + if (!request_mem_region(resbase, reslen, "eesoxscsi")) { + ret = -EBUSY; goto out; + } - host->io_port = ecard_address(ec, ECARD_IOC, ECARD_FAST); - host->irq = ec->irq; - host->dma_channel = ec->dma; + base = ioremap(resbase, reslen); + if (!base) { + ret = -ENOMEM; + goto out_region; + } - if (!request_region(host->io_port + EESOX_FAS216_OFFSET, - EESOX_FAS216_SIZE, "eesox2-fas")) { - ret = -EBUSY; - goto out_free; + host = scsi_register(&eesox_template, + sizeof(struct eesoxscsi_info)); + if (!host) { + ret = -ENOMEM; + goto out_unmap; } + host->base = (unsigned long)base; + host->irq = ec->irq; + host->dma_channel = ec->dma; + ecard_set_drvdata(ec, host); info = (struct eesoxscsi_info *)host->hostdata; - info->ctl_port = host->io_port + EESOX_CONTROL; - info->control = term[ec->slot_no] ? EESOX_TERM_ENABLE : 0; - outb(info->control, info->ctl_port); - - ec->irqaddr = (unsigned char *)ioaddr(host->io_port + EESOX_STATUS); - ec->irqmask = EESOX_STAT_INTR; - ec->irq_data = info; - ec->ops = (expansioncard_ops_t *)&eesoxscsi_ops; + info->ec = ec; + info->ctl_port = base + EESOX_CONTROL; + info->control = term[ec->slot_no] ? EESOX_TERM_ENABLE : 0; + writeb(info->control, info->ctl_port); + + ec->irqaddr = base + EESOX_DMASTAT; + ec->irqmask = EESOX_STAT_INTR; + ec->irq_data = info; + ec->ops = &eesoxscsi_ops; - info->info.scsi.io_port = host->io_port + EESOX_FAS216_OFFSET; + info->info.scsi.io_base = base + EESOX_FAS216_OFFSET; info->info.scsi.io_shift = EESOX_FAS216_SHIFT; info->info.scsi.irq = host->irq; info->info.ifcfg.clockrate = 40; /* MHz */ info->info.ifcfg.select_timeout = 255; info->info.ifcfg.asyncperiod = 200; /* ns */ info->info.ifcfg.sync_max_depth = 7; - info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK; + info->info.ifcfg.cntl3 = CNTL3_FASTSCSI | CNTL3_FASTCLK; info->info.ifcfg.disconnect_ok = 1; info->info.ifcfg.wide_max_size = 0; + info->info.ifcfg.capabilities = FASCAP_PSEUDODMA; info->info.dma.setup = eesoxscsi_dma_setup; info->info.dma.pseudo = eesoxscsi_dma_pseudo; info->info.dma.stop = eesoxscsi_dma_stop; - info->dmaarea = host->io_port + EESOX_DMA_OFFSET; - ret = request_irq(host->irq, eesoxscsi_intr, - SA_INTERRUPT, "eesox", host); + device_create_file(&ec->dev, &dev_attr_bus_term); + + ret = fas216_init(host); + if (ret) + goto out_free; + + ret = request_irq(host->irq, eesoxscsi_intr, 0, "eesoxscsi", info); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, host->irq, ret); - goto out_region; + goto out_remove; } if (host->dma_channel != NO_DMA) { @@ -500,24 +613,32 @@ host->dma_channel = NO_DMA; } else { set_dma_speed(host->dma_channel, 180); + info->info.ifcfg.capabilities |= FASCAP_DMA; + info->info.ifcfg.cntl3 |= CNTL3_BS8; } } - fas216_init(host); - ret = scsi_add_host(host, &ec->dev); + ret = fas216_add(host, &ec->dev); if (ret == 0) goto out; - fas216_release(host); - if (host->dma_channel != NO_DMA) free_dma(host->dma_channel); free_irq(host->irq, host); - out_region: - release_region(host->io_port + EESOX_FAS216_OFFSET, - EESOX_FAS216_SIZE); + + out_remove: + fas216_remove(host); + out_free: + device_remove_file(&ec->dev, &dev_attr_bus_term); scsi_unregister(host); + + out_unmap: + iounmap(base); + + out_region: + release_mem_region(resbase, reslen); + out: return ret; } @@ -525,15 +646,26 @@ static void __devexit eesoxscsi_remove(struct expansion_card *ec) { struct Scsi_Host *host = ecard_get_drvdata(ec); + struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; + unsigned long resbase, reslen; ecard_set_drvdata(ec, NULL); - scsi_remove_host(host); - fas216_release(host); + fas216_remove(host); if (host->dma_channel != NO_DMA) free_dma(host->dma_channel); - free_irq(host->irq, host); - release_region(host->io_port + EESOX_FAS216_OFFSET, EESOX_FAS216_SIZE); + free_irq(host->irq, info); + + device_remove_file(&ec->dev, &dev_attr_bus_term); + + iounmap((void *)host->base); + + resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST); + reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST); + + release_mem_region(resbase, reslen); + + fas216_release(host); scsi_unregister(host); } @@ -547,7 +679,8 @@ .remove = __devexit_p(eesoxscsi_remove), .id_table = eesoxscsi_cids, .drv = { - .name = "eesoxscsi", + .devclass = &shost_devclass, + .name = "eesoxscsi", }, }; diff -Nru a/drivers/acorn/scsi/fas216.c b/drivers/acorn/scsi/fas216.c --- a/drivers/acorn/scsi/fas216.c Sun Feb 9 21:13:31 2003 +++ b/drivers/acorn/scsi/fas216.c Sun Feb 9 21:13:31 2003 @@ -1,7 +1,7 @@ /* * linux/drivers/acorn/scsi/fas216.c * - * Copyright (C) 1997-2000 Russell King + * Copyright (C) 1997-2003 Russell King * * 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 @@ -10,7 +10,7 @@ * Based on information in qlogicfas.c by Tom Zerucha, Michael Griffith, and * other sources, including: * the AMD Am53CF94 data sheet - * the AMD Am53C94 data sheet + * the AMD Am53C94 data sheet * * This is a generic driver. To use it, have a look at cumana_2.c. You * should define your own structure that overlays FAS216_Info, eg: @@ -33,9 +33,6 @@ * 02-04-2000 RMK Converted to use the new error handling, and * automatically request sense data upon check * condition status from targets. - * - * Todo: - * - allow individual devices to enable sync xfers. */ #include #include @@ -45,6 +42,7 @@ #include #include #include +#include #include #include @@ -52,17 +50,11 @@ #include #include -#define FAS216_C - #include "../../scsi/scsi.h" #include "../../scsi/hosts.h" #include "fas216.h" #include "scsi.h" -#define VER_MAJOR 0 -#define VER_MINOR 0 -#define VER_PATCH 5 - /* NOTE: SCSI2 Synchronous transfers *require* DMA according to * the data sheet. This restriction is crazy, especially when * you only want to send 16 bytes! What were the guys who @@ -104,22 +96,43 @@ static int level_mask = LOG_ERROR; +static inline unsigned char fas216_readb(FAS216_Info *info, unsigned int reg) +{ + unsigned int off = reg << info->scsi.io_shift; + if (info->scsi.io_base) + return readb(info->scsi.io_base + off); + else + return inb(info->scsi.io_port + off); +} + +static inline void fas216_writeb(FAS216_Info *info, unsigned int reg, unsigned int val) +{ + unsigned int off = reg << info->scsi.io_shift; + if (info->scsi.io_base) + writeb(val, info->scsi.io_base + off); + else + outb(val, info->scsi.io_port + off); +} + static void fas216_dumpstate(FAS216_Info *info) { unsigned char is, stat, inst; - is = inb(REG_IS(info)); - stat = inb(REG_STAT(info)); - inst = inb(REG_INST(info)); + is = fas216_readb(info, REG_IS); + stat = fas216_readb(info, REG_STAT); + inst = fas216_readb(info, REG_INST); printk("FAS216: CTCL=%02X CTCM=%02X CMD=%02X STAT=%02X" " INST=%02X IS=%02X CFIS=%02X", - inb(REG_CTCL(info)), inb(REG_CTCM(info)), - inb(REG_CMD(info)), stat, inst, is, - inb(REG_CFIS(info))); + fas216_readb(info, REG_CTCL), + fas216_readb(info, REG_CTCM), + fas216_readb(info, REG_CMD), stat, inst, is, + fas216_readb(info, REG_CFIS)); printk(" CNTL1=%02X CNTL2=%02X CNTL3=%02X CTCH=%02X\n", - inb(REG_CNTL1(info)), inb(REG_CNTL2(info)), - inb(REG_CNTL3(info)), inb(REG_CTCH(info))); + fas216_readb(info, REG_CNTL1), + fas216_readb(info, REG_CNTL2), + fas216_readb(info, REG_CNTL3), + fas216_readb(info, REG_CTCH)); } static void print_SCp(Scsi_Pointer *SCp, const char *prefix, const char *suffix) @@ -236,19 +249,63 @@ return 'H'; } +static void +fas216_do_log(FAS216_Info *info, char target, char *fmt, va_list ap) +{ + static char buf[1024]; + + vsnprintf(buf, sizeof(buf), fmt, ap); + printk("scsi%d.%c: %s", info->host->host_no, target, buf); +} + +static void +fas216_log_command(FAS216_Info *info, int level, Scsi_Cmnd *SCpnt, char *fmt, ...) +{ + va_list args; + + if (level != 0 && !(level & level_mask)) + return; + + va_start(args, fmt); + fas216_do_log(info, '0' + SCpnt->target, fmt, args); + va_end(args); + + printk(" CDB: "); + print_command(SCpnt->cmnd); +} + +static void +fas216_log_target(FAS216_Info *info, int level, int target, char *fmt, ...) +{ + va_list args; + + if (level != 0 && !(level & level_mask)) + return; + + if (target < 0) + target = 'H'; + else + target += '0'; + + va_start(args, fmt); + fas216_do_log(info, target, fmt, args); + va_end(args); + + printk("\n"); +} + static void fas216_log(FAS216_Info *info, int level, char *fmt, ...) { va_list args; - static char buf[1024]; if (level != 0 && !(level & level_mask)) return; va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); + fas216_do_log(info, fas216_target(info), fmt, args); va_end(args); - printk("scsi%d.%c: %s\n", info->host->host_no, fas216_target(info), buf); + printk("\n"); } #define PH_SIZE 32 @@ -276,7 +333,7 @@ cmd_ptr = (cmd_ptr + 1) & 7; - outb(command, REG_CMD(info)); + fas216_writeb(info, REG_CMD, command); } static void print_debug_list(void) @@ -308,11 +365,11 @@ static void fas216_done(FAS216_Info *info, unsigned int result); -/** - * fast216_clockrate - calculate clock conversion factor +/** + * fas216_clockrate - calculate clock conversion factor * @clock: clock speed in MHz - * - * Calculate correct value to be written into clock conversion factor + * + * Calculate correct value to be written into clock conversion factor * register. Returns CLKF_ value. */ static int fas216_clockrate(int clock) @@ -327,11 +384,11 @@ return clock; } -/** +/** * fas216_get_last_msg - retrive last message from the list * @info: interface to search * @pos: current fifo position - * + * * Retrieve a last message from the list, using position in fifo. */ static inline unsigned short @@ -359,12 +416,12 @@ return packed_msg; } -/** +/** * fas216_syncperiod - calculate STP register value * @info: state structure for interface connected to device * @ns: period in ns (between subsequent bytes) - * - * Calculate value to be loaded into the STP register for a given period + * + * Calculate value to be loaded into the STP register for a given period * in ns. Returns a value suitable for REG_STP. */ static int fas216_syncperiod(FAS216_Info *info, int ns) @@ -381,11 +438,11 @@ return value & 31; } -/** +/** * fas216_set_sync - setup FAS216 chip for specified transfer period. - * @info: state structure for interface connected to device + * @info: state structure for interface connected to device * @target: target - * + * * Correctly setup FAS216 chip for specified transfer period. * Notes : we need to switch the chip out of FASTSCSI mode if we have * a transfer period >= 200ns - otherwise the chip will violate @@ -393,12 +450,16 @@ */ static void fas216_set_sync(FAS216_Info *info, int target) { - outb(info->device[target].sof, REG_SOF(info)); - outb(info->device[target].stp, REG_STP(info)); + unsigned int cntl3; + + fas216_writeb(info, REG_SOF, info->device[target].sof); + fas216_writeb(info, REG_STP, info->device[target].stp); + + cntl3 = info->scsi.cfg[2]; if (info->device[target].period >= (200 / 4)) - outb(info->scsi.cfg[2] & ~CNTL3_FASTSCSI, REG_CNTL3(info)); - else - outb(info->scsi.cfg[2], REG_CNTL3(info)); + cntl3 = cntl3 & ~CNTL3_FASTSCSI; + + fas216_writeb(info, REG_CNTL3, cntl3); } /* Synchronous transfer support @@ -428,8 +489,8 @@ /** * fas216_handlesync - Handle a synchronous transfer message * @info: state structure for interface - * @ms: message from target - * + * @msg: message from target + * * Handle a synchronous transfer message from the target */ static void fas216_handlesync(FAS216_Info *info, char *msg) @@ -538,11 +599,11 @@ } } -/** - * fas216_handlewide - Handle a wide transfer message +/** + * fas216_handlewide - Handle a wide transfer message * @info: state structure for interface * @msg: message from target - * + * * Handle a wide transfer message from the target */ static void fas216_handlewide(FAS216_Info *info, char *msg) @@ -637,11 +698,11 @@ } } -/** +/** * fas216_updateptrs - update data pointers after transfer suspended/paused * @info: interface's local pointer to update * @bytes_transferred: number of bytes transferred - * + * * Update data pointers after transfer suspended/paused */ static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred) @@ -662,7 +723,7 @@ * next buffer. */ bytes_transferred -= SCp->this_residual; - if (!next_SCp(&info->scsi.SCp) && bytes_transferred) { + if (!next_SCp(SCp) && bytes_transferred) { printk(KERN_WARNING "scsi%d.%c: out of buffers\n", info->host->host_no, '0' + info->SCpnt->target); return; @@ -680,33 +741,67 @@ * fas216_pio - transfer data off of/on to card using programmed IO * @info: interface to transfer data to/from * @direction: direction to transfer data (DMA_OUT/DMA_IN) - * + * * Transfer data off of/on to card using programmed IO. * Notes: this is incredibly slow. */ static void fas216_pio(FAS216_Info *info, fasdmadir_t direction) { + Scsi_Pointer *SCp = &info->scsi.SCp; + fas216_checkmagic(info); if (direction == DMA_OUT) - outb(get_next_SCp_byte(&info->scsi.SCp), REG_FF(info)); + fas216_writeb(info, REG_FF, get_next_SCp_byte(SCp)); else - put_next_SCp_byte(&info->scsi.SCp, inb(REG_FF(info))); + put_next_SCp_byte(SCp, fas216_readb(info, REG_FF)); + + if (SCp->this_residual == 0) + next_SCp(SCp); +} + +static void fas216_set_stc(FAS216_Info *info, unsigned int length) +{ + fas216_writeb(info, REG_STCL, length); + fas216_writeb(info, REG_STCM, length >> 8); + fas216_writeb(info, REG_STCH, length >> 16); +} + +static unsigned int fas216_get_ctc(FAS216_Info *info) +{ + return fas216_readb(info, REG_CTCL) + + (fas216_readb(info, REG_CTCM) << 8) + + (fas216_readb(info, REG_CTCH) << 16); } +/** + * fas216_cleanuptransfer - clean up after a transfer has completed. + * @info: interface to clean up + * + * Update the data pointers according to the number of bytes transferred + * on the SCSI bus. + */ static void fas216_cleanuptransfer(FAS216_Info *info) { unsigned long total, residual, fifo; + fasdmatype_t dmatype = info->dma.transfer_type; + + info->dma.transfer_type = fasdma_none; - if (info->dma.transfer_type == fasdma_real_all) + /* + * PIO transfers do not need to be cleaned up. + */ + if (dmatype == fasdma_pio || dmatype == fasdma_none) + return; + + if (dmatype == fasdma_real_all) total = info->SCpnt->request_bufflen; else total = info->scsi.SCp.this_residual; - residual = inb(REG_CTCL(info)) + (inb(REG_CTCM(info)) << 8) + - (inb(REG_CTCH(info)) << 16); + residual = fas216_get_ctc(info); - fifo = inb(REG_CFIS(info)) & CFIS_CF; + fifo = fas216_readb(info, REG_CFIS) & CFIS_CF; fas216_log(info, LOG_BUFFER, "cleaning up from previous " "transfer: length 0x%06x, residual 0x%x, fifo %d", @@ -718,54 +813,22 @@ * host to the FIFO. This means we must include the * bytes left in the FIFO from the transfer counter. */ - if (info->scsi.phase == PHASE_DATAOUT) { + if (info->scsi.phase == PHASE_DATAOUT) residual += fifo; - fifo = 0; - } - - if (info->dma.transfer_type != fasdma_none && - info->dma.transfer_type != fasdma_pio) { - fas216_updateptrs(info, total - residual); - } - - /* - * If we were performing Data-In, then the FIFO counter - * contains the number of bytes not transferred via DMA - * from the on-board FIFO. Read them manually. - */ - if (info->scsi.phase == PHASE_DATAIN) { - while (fifo && info->scsi.SCp.ptr) { - *info->scsi.SCp.ptr = inb(REG_FF(info)); - fas216_updateptrs(info, 1); - fifo--; - } - } - info->dma.transfer_type = fasdma_none; + fas216_updateptrs(info, total - residual); } -/** - * fas216_starttransfer - Start a DMA/PIO transfer off of/on to card +/** + * fas216_transfer - Perform a DMA/PIO transfer off of/on to card * @info: interface from which device disconnected from - * @direction: transfer direction (DMA_OUT/DMA_IN) - * + * * Start a DMA/PIO transfer off of/on to card */ -static void fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction) +static void fas216_transfer(FAS216_Info *info) { + fasdmadir_t direction; fasdmatype_t dmatype; - int phase = (direction == DMA_OUT) ? PHASE_DATAOUT : PHASE_DATAIN; - - fas216_checkmagic(info); - - if (phase != info->scsi.phase) { - info->scsi.phase = phase; - - if (direction == DMA_OUT) - fas216_cmd(info, CMD_FLUSHFIFO); - } else { - fas216_cleanuptransfer(info); - } fas216_log(info, LOG_BUFFER, "starttransfer: buffer %p length 0x%06x reqlen 0x%06x", @@ -781,36 +844,41 @@ } /* - * Default to PIO mode or DMA mode if we have - * a synchronous transfer agreement. + * If we have a synchronous transfer agreement in effect, we must + * use DMA mode. If we are using asynchronous transfers, we may + * use DMA mode or PIO mode. */ - if (info->device[info->SCpnt->target].sof && info->dma.setup) + if (info->device[info->SCpnt->target].sof) dmatype = fasdma_real_all; else dmatype = fasdma_pio; + if (info->scsi.phase == PHASE_DATAOUT) + direction = DMA_OUT; + else + direction = DMA_IN; + if (info->dma.setup) dmatype = info->dma.setup(info->host, &info->scsi.SCp, direction, dmatype); info->dma.transfer_type = dmatype; + if (dmatype == fasdma_real_all) + fas216_set_stc(info, info->SCpnt->request_bufflen); + else + fas216_set_stc(info, info->scsi.SCp.this_residual); + switch (dmatype) { case fasdma_pio: fas216_log(info, LOG_BUFFER, "PIO transfer"); - outb(0, REG_SOF(info)); - outb(info->scsi.async_stp, REG_STP(info)); - outb(info->scsi.SCp.this_residual, REG_STCL(info)); - outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info)); - outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info)); + fas216_writeb(info, REG_SOF, 0); + fas216_writeb(info, REG_STP, info->scsi.async_stp); fas216_cmd(info, CMD_TRANSFERINFO); fas216_pio(info, direction); break; case fasdma_pseudo: fas216_log(info, LOG_BUFFER, "pseudo transfer"); - outb(info->scsi.SCp.this_residual, REG_STCL(info)); - outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info)); - outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info)); fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA); info->dma.pseudo(info->host, &info->scsi.SCp, direction, info->SCpnt->transfersize); @@ -818,17 +886,11 @@ case fasdma_real_block: fas216_log(info, LOG_BUFFER, "block dma transfer"); - outb(info->scsi.SCp.this_residual, REG_STCL(info)); - outb(info->scsi.SCp.this_residual >> 8, REG_STCM(info)); - outb(info->scsi.SCp.this_residual >> 16, REG_STCH(info)); fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA); break; case fasdma_real_all: fas216_log(info, LOG_BUFFER, "total dma transfer"); - outb(info->SCpnt->request_bufflen, REG_STCL(info)); - outb(info->SCpnt->request_bufflen >> 8, REG_STCM(info)); - outb(info->SCpnt->request_bufflen >> 16, REG_STCH(info)); fas216_cmd(info, CMD_TRANSFERINFO | CMD_WITHDMA); break; @@ -839,44 +901,61 @@ } } -/** +/** * fas216_stoptransfer - Stop a DMA transfer onto / off of the card * @info: interface from which device disconnected from - * - * Stop a DMA transfer onto / off of the card + * + * Called when we switch away from DATA IN or DATA OUT phases. */ static void fas216_stoptransfer(FAS216_Info *info) { fas216_checkmagic(info); - if ((info->dma.transfer_type == fasdma_real_all || - info->dma.transfer_type == fasdma_real_block) && - info->dma.stop) + if (info->dma.transfer_type == fasdma_real_all || + info->dma.transfer_type == fasdma_real_block) info->dma.stop(info->host, &info->scsi.SCp); fas216_cleanuptransfer(info); - if (info->scsi.phase == PHASE_DATAOUT) + if (info->scsi.phase == PHASE_DATAIN) { + unsigned int fifo; + + /* + * If we were performing Data-In, then the FIFO counter + * contains the number of bytes not transferred via DMA + * from the on-board FIFO. Read them manually. + */ + fifo = fas216_readb(info, REG_CFIS) & CFIS_CF; + while (fifo && info->scsi.SCp.ptr) { + *info->scsi.SCp.ptr = fas216_readb(info, REG_FF); + fas216_updateptrs(info, 1); + fifo--; + } + } else { + /* + * After a Data-Out phase, there may be unsent + * bytes left in the FIFO. Flush them out. + */ fas216_cmd(info, CMD_FLUSHFIFO); + } } static void fas216_aborttransfer(FAS216_Info *info) { fas216_checkmagic(info); - if ((info->dma.transfer_type == fasdma_real_all || - info->dma.transfer_type == fasdma_real_block) && - info->dma.stop) + if (info->dma.transfer_type == fasdma_real_all || + info->dma.transfer_type == fasdma_real_block) info->dma.stop(info->host, &info->scsi.SCp); info->dma.transfer_type = fasdma_none; fas216_cmd(info, CMD_FLUSHFIFO); } -/** +/** * fas216_disconnected_intr - handle device disconnection * @info: interface from which device disconnected from - * + * * Handle device disconnection */ static void fas216_disconnect_intr(FAS216_Info *info) @@ -924,10 +1003,10 @@ } } -/** +/** * fas216_reselected_intr - start reconnection of a device * @info: interface which was reselected - * + * * Start reconnection of a device */ static void @@ -952,19 +1031,14 @@ fas216_log(info, LOG_CONNECT, "reconnect phase=%02X", info->scsi.phase); - if ((inb(REG_CFIS(info)) & CFIS_CF) != 2) { + if ((fas216_readb(info, REG_CFIS) & CFIS_CF) != 2) { printk(KERN_ERR "scsi%d.H: incorrect number of bytes after reselect\n", info->host->host_no); - fas216_cmd(info, CMD_SETATN); - msgqueue_flush(&info->scsi.msgs); - msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR); - info->scsi.phase = PHASE_MSGOUT_EXPECT; - fas216_cmd(info, CMD_MSGACCEPTED); - return; + goto initiator_error; } - target = inb(REG_FF(info)); - identify_msg = inb(REG_FF(info)); + target = fas216_readb(info, REG_FF); + identify_msg = fas216_readb(info, REG_FF); ok = 1; if (!(target & (1 << info->host->this_id))) { @@ -983,26 +1057,11 @@ * Something went wrong - send an initiator error to * the target. */ - fas216_cmd(info, CMD_SETATN); - msgqueue_flush(&info->scsi.msgs); - msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR); - info->scsi.phase = PHASE_MSGOUT_EXPECT; - fas216_cmd(info, CMD_MSGACCEPTED); - return; + goto initiator_error; } target &= ~(1 << info->host->this_id); - switch (target) { - case 1: target = 0; break; - case 2: target = 1; break; - case 4: target = 2; break; - case 8: target = 3; break; - case 16: target = 4; break; - case 32: target = 5; break; - case 64: target = 6; break; - case 128: target = 7; break; - default: target = info->host->this_id; break; - } + target = ffs(target) - 1; identify_msg &= 7; info->scsi.reconnected.target = target; @@ -1023,7 +1082,7 @@ msgqueue_flush(&info->scsi.msgs); if (ok) { info->scsi.phase = PHASE_RECONNECTED; - outb(target, REG_SDID(info)); + fas216_writeb(info, REG_SDID, target); } else { /* * Our command structure not found - abort the @@ -1037,9 +1096,17 @@ } fas216_cmd(info, CMD_MSGACCEPTED); + return; + + initiator_error: + fas216_cmd(info, CMD_SETATN); + msgqueue_flush(&info->scsi.msgs); + msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR); + info->scsi.phase = PHASE_MSGOUT_EXPECT; + fas216_cmd(info, CMD_MSGACCEPTED); } -/** +/** * fas216_finish_reconnect - finish reconnection sequence for device * @info: interface which caused function done interrupt * @@ -1232,7 +1299,7 @@ fas216_cmd(info, cmd); for (tout = 1000; tout; tout -= 1) { - stat = inb(REG_STAT(info)); + stat = fas216_readb(info, REG_STAT); if (stat & (STAT_INT|STAT_PARITYERROR)) break; udelay(1); @@ -1251,7 +1318,7 @@ if ((stat & STAT_BUSMASK) != STAT_MESGIN) goto unexpected_phase_change; - inb(REG_INST(info)); + fas216_readb(info, REG_INST); stat = fas216_wait_cmd(info, CMD_TRANSFERINFO); @@ -1264,9 +1331,9 @@ if ((stat & STAT_BUSMASK) != STAT_MESGIN) goto unexpected_phase_change; - inb(REG_INST(info)); + fas216_readb(info, REG_INST); - return inb(REG_FF(info)); + return fas216_readb(info, REG_FF); timedout: fas216_log(info, LOG_ERROR, "timed out waiting for message byte"); @@ -1284,7 +1351,7 @@ /** * fas216_message - handle a function done interrupt from FAS216 chip * @info: interface which caused function done interrupt - * + * * Handle a function done interrupt from FAS216 chip */ static void fas216_message(FAS216_Info *info) @@ -1295,7 +1362,7 @@ fas216_checkmagic(info); - message[0] = inb(REG_FF(info)); + message[0] = fas216_readb(info, REG_FF); if (message[0] == EXTENDED_MESSAGE) { msgbyte = fas216_get_msg_byte(info); @@ -1317,8 +1384,6 @@ if (msgbyte == -3) goto parity_error; - info->scsi.msglen = msglen; - #ifdef DEBUG_MESSAGES { int i; @@ -1354,7 +1419,7 @@ /** * fas216_send_command - send command after all message bytes have been sent * @info: interface which caused bus service - * + * * Send a command to a target after all message bytes have been sent */ static void fas216_send_command(FAS216_Info *info) @@ -1368,17 +1433,17 @@ /* load command */ for (i = info->scsi.SCp.sent_command; i < info->SCpnt->cmd_len; i++) - outb(info->SCpnt->cmnd[i], REG_FF(info)); + fas216_writeb(info, REG_FF, info->SCpnt->cmnd[i]); fas216_cmd(info, CMD_TRANSFERINFO); info->scsi.phase = PHASE_COMMAND; } -/** +/** * fas216_send_messageout - handle bus service to send a message * @info: interface which caused bus service - * + * * Handle bus service to send a message. * Note: We do not allow the device to change the data direction! */ @@ -1398,25 +1463,25 @@ int i; for (i = start; i < msg->length; i++) - outb(msg->msg[i], REG_FF(info)); + fas216_writeb(info, REG_FF, msg->msg[i]); - msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF); + msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF); start = 0; } } else - outb(NOP, REG_FF(info)); + fas216_writeb(info, REG_FF, NOP); fas216_cmd(info, CMD_TRANSFERINFO); info->scsi.phase = PHASE_MSGOUT; } -/** +/** * fas216_busservice_intr - handle bus service interrupt from FAS216 chip * @info: interface which caused bus service interrupt * @stat: Status register contents * @ssr: SCSI Status register contents - * + * * Handle a bus service interrupt from FAS216 chip */ static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr) @@ -1429,7 +1494,7 @@ switch (info->scsi.phase) { case PHASE_SELECTION: - if ((ssr & IS_BITS) != 1) + if ((ssr & IS_BITS) != IS_MSGBYTESENT) goto bad_is; break; @@ -1464,15 +1529,17 @@ case STATE(STAT_DATAIN, PHASE_RECONNECTED): fas216_finish_reconnect(info); case STATE(STAT_DATAIN, PHASE_SELSTEPS):/* Sel w/ steps -> Data In */ - case STATE(STAT_DATAIN, PHASE_DATAIN): /* Data In -> Data In */ case STATE(STAT_DATAIN, PHASE_MSGOUT): /* Message Out -> Data In */ case STATE(STAT_DATAIN, PHASE_COMMAND): /* Command -> Data In */ case STATE(STAT_DATAIN, PHASE_MSGIN): /* Message In -> Data In */ - fas216_starttransfer(info, DMA_IN); + info->scsi.phase = PHASE_DATAIN; + fas216_transfer(info); return; + case STATE(STAT_DATAIN, PHASE_DATAIN): /* Data In -> Data In */ case STATE(STAT_DATAOUT, PHASE_DATAOUT):/* Data Out -> Data Out */ - fas216_starttransfer(info, DMA_OUT); + fas216_cleanuptransfer(info); + fas216_transfer(info); return; /* Reselmsgin -> Data Out */ @@ -1482,7 +1549,9 @@ case STATE(STAT_DATAOUT, PHASE_MSGOUT): /* Message Out -> Data Out */ case STATE(STAT_DATAOUT, PHASE_COMMAND):/* Command -> Data Out */ case STATE(STAT_DATAOUT, PHASE_MSGIN): /* Message In -> Data Out */ - fas216_starttransfer(info, DMA_OUT); + fas216_cmd(info, CMD_FLUSHFIFO); + info->scsi.phase = PHASE_DATAOUT; + fas216_transfer(info); return; /* Reselmsgin -> Status */ @@ -1507,7 +1576,7 @@ case STATE(STAT_MESGIN, PHASE_COMMAND): /* Command -> Message In */ case STATE(STAT_MESGIN, PHASE_SELSTEPS):/* Sel w/ steps -> Message In */ case STATE(STAT_MESGIN, PHASE_MSGOUT): /* Message Out -> Message In */ - info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF; + info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF; fas216_cmd(info, CMD_FLUSHFIFO); fas216_cmd(info, CMD_TRANSFERINFO); info->scsi.phase = PHASE_MSGIN; @@ -1516,7 +1585,7 @@ /* Reselmsgin -> Message In */ case STATE(STAT_MESGIN, PHASE_RECONNECTED): case STATE(STAT_MESGIN, PHASE_MSGIN): - info->scsi.msgin_fifo = inb(REG_CFIS(info)) & CFIS_CF; + info->scsi.msgin_fifo = fas216_readb(info, REG_CFIS) & CFIS_CF; fas216_cmd(info, CMD_TRANSFERINFO); return; @@ -1555,7 +1624,7 @@ */ info->device[info->SCpnt->target].parity_check = 0; info->device[info->SCpnt->target].parity_enabled = 1; - outb(info->scsi.cfg[0], REG_CNTL1(info)); + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]); } if (msgqueue_msglength(&info->scsi.msgs) > 1) @@ -1584,9 +1653,7 @@ "target trying to receive more command bytes\n", info->host->host_no, fas216_target(info)); fas216_cmd(info, CMD_SETATN); - outb(15, REG_STCL(info)); - outb(0, REG_STCM(info)); - outb(0, REG_STCH(info)); + fas216_set_stc(info, 15); fas216_cmd(info, CMD_PADBYTES | CMD_WITHDMA); msgqueue_flush(&info->scsi.msgs); msgqueue_addmsg(&info->scsi.msgs, 1, INITIATOR_ERROR); @@ -1615,6 +1682,7 @@ bad_is: fas216_log(info, 0, "bus service at step %d?", ssr & IS_BITS); + fas216_dumpstate(info); print_debug_list(); fas216_done(info, DID_ERROR); @@ -1625,12 +1693,12 @@ * @info: interface which caused function done interrupt * @stat: Status register contents * @ssr: SCSI Status register contents - * + * * Handle a function done interrupt from FAS216 chip */ static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr) { - unsigned int fifo_len = inb(REG_CFIS(info)) & CFIS_CF; + unsigned int fifo_len = fas216_readb(info, REG_CFIS) & CFIS_CF; unsigned int status, message; fas216_checkmagic(info); @@ -1644,8 +1712,8 @@ if (fifo_len != 2) { fas216_log(info, 0, "odd number of bytes in FIFO: %d", fifo_len); } - status = inb(REG_FF(info)); - message = inb(REG_FF(info)); + status = fas216_readb(info, REG_FF); + message = fas216_readb(info, REG_FF); info->scsi.SCp.Message = message; info->scsi.SCp.Status = status; info->scsi.phase = PHASE_DONE; @@ -1679,26 +1747,21 @@ info->scsi.reconnected.lun = 0; info->scsi.reconnected.tag = 0; - if (info->ifcfg.wide_max_size == 0) - wide_state = neg_invalid; - else + wide_state = neg_invalid; + sync_state = neg_invalid; + #ifdef SCSI2_WIDE + if (info->ifcfg.wide_max_size != 0) wide_state = neg_wait; -#else - wide_state = neg_invalid; #endif - - if (info->host->dma_channel == NO_DMA || !info->dma.setup) - sync_state = neg_invalid; - else #ifdef SCSI2_SYNC + if (info->ifcfg.capabilities & (FASCAP_DMA|FASCAP_PSEUDODMA)) sync_state = neg_wait; -#else - sync_state = neg_invalid; #endif info->scsi.phase = PHASE_IDLE; info->SCpnt = NULL; /* bug! */ + memset(&info->scsi.SCp, 0, sizeof(info->scsi.SCp)); for (i = 0; i < 8; i++) { info->device[i].disconnect_ok = info->ifcfg.disconnect_ok; @@ -1714,22 +1777,21 @@ wake_up(&info->eh_wait); } -/** +/** * fas216_intr - handle interrupts to progress a command - * @instance: interface to service - * + * @info: interface to service + * * Handle interrupts from the interface to progress a command */ -void fas216_intr(struct Scsi_Host *instance) +void fas216_intr(FAS216_Info *info) { - FAS216_Info *info = (FAS216_Info *)instance->hostdata; unsigned char isr, ssr, stat; fas216_checkmagic(info); - stat = inb(REG_STAT(info)); - ssr = inb(REG_IS(info)); - isr = inb(REG_INST(info)); + stat = fas216_readb(info, REG_STAT); + ssr = fas216_readb(info, REG_IS); + isr = fas216_readb(info, REG_INST); add_debug_list(stat, ssr, isr, info->scsi.phase); @@ -1762,17 +1824,15 @@ int tot_msglen; /* following what the ESP driver says */ - outb(0, REG_STCL(info)); - outb(0, REG_STCM(info)); - outb(0, REG_STCH(info)); + fas216_set_stc(info, 0); fas216_cmd(info, CMD_NOP | CMD_WITHDMA); /* flush FIFO */ fas216_cmd(info, CMD_FLUSHFIFO); /* load bus-id and timeout */ - outb(BUSID(SCpnt->target), REG_SDID(info)); - outb(info->ifcfg.select_timeout, REG_STIM(info)); + fas216_writeb(info, REG_SDID, BUSID(SCpnt->target)); + fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout); /* synchronous transfers */ fas216_set_sync(info, SCpnt->target); @@ -1808,13 +1868,13 @@ /* load message bytes */ while ((msg = msgqueue_getmsg(&info->scsi.msgs, msgnr++)) != NULL) { for (i = 0; i < msg->length; i++) - outb(msg->msg[i], REG_FF(info)); - msg->fifo = tot_msglen - (inb(REG_CFIS(info)) & CFIS_CF); + fas216_writeb(info, REG_FF, msg->msg[i]); + msg->fifo = tot_msglen - (fas216_readb(info, REG_CFIS) & CFIS_CF); } /* load command */ for (i = 0; i < SCpnt->cmd_len; i++) - outb(SCpnt->cmnd[i], REG_FF(info)); + fas216_writeb(info, REG_FF, SCpnt->cmnd[i]); if (tot_msglen == 1) fas216_cmd(info, CMD_SELECTATN); @@ -1828,7 +1888,7 @@ */ struct message *msg = msgqueue_getmsg(&info->scsi.msgs, 0); - outb(msg->msg[0], REG_FF(info)); + fas216_writeb(info, REG_FF, msg->msg[0]); msg->fifo = 1; fas216_cmd(info, CMD_SELECTATNSTOP); @@ -1855,11 +1915,6 @@ { int disconnect_ok; - if (parity_test(info, SCpnt->target)) - outb(info->scsi.cfg[0] | CNTL1_PTE, REG_CNTL1(info)); - else - outb(info->scsi.cfg[0], REG_CNTL1(info)); - /* * claim host busy */ @@ -1868,6 +1923,11 @@ info->SCpnt = SCpnt; info->dma.transfer_type = fasdma_none; + if (parity_test(info, SCpnt->target)) + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_PTE); + else + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]); + /* * Don't allow request sense commands to disconnect. */ @@ -1966,24 +2026,22 @@ msgqueue_addmsg(&info->scsi.msgs, 1, BUS_DEVICE_RESET); /* following what the ESP driver says */ - outb(0, REG_STCL(info)); - outb(0, REG_STCM(info)); - outb(0, REG_STCH(info)); + fas216_set_stc(info, 0); fas216_cmd(info, CMD_NOP | CMD_WITHDMA); /* flush FIFO */ fas216_cmd(info, CMD_FLUSHFIFO); /* load bus-id and timeout */ - outb(BUSID(SCpnt->target), REG_SDID(info)); - outb(info->ifcfg.select_timeout, REG_STIM(info)); + fas216_writeb(info, REG_SDID, BUSID(SCpnt->target)); + fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout); /* synchronous transfers */ fas216_set_sync(info, SCpnt->target); msg = msgqueue_getmsg(&info->scsi.msgs, 0); - outb(BUS_DEVICE_RESET, REG_FF(info)); + fas216_writeb(info, REG_FF, BUS_DEVICE_RESET); msg->fifo = 1; fas216_cmd(info, CMD_SELECTATNSTOP); @@ -1992,8 +2050,8 @@ /** * fas216_kick - kick a command to the interface * @info: our host interface to kick - * - * kick a command to the interface, interface should be idle. + * + * Kick a command to the interface, interface should be idle. * Notes: Interrupts are always disabled! */ static void fas216_kick(FAS216_Info *info) @@ -2050,11 +2108,8 @@ info->SCpnt = NULL; } -#if defined(DEBUG_CONNECT) || defined(DEBUG_MESSAGES) - printk("scsi%d.%c: starting ", - info->host->host_no, '0' + SCpnt->target); - print_command(SCpnt->cmnd); -#endif + fas216_log_command(info, LOG_CONNECT | LOG_MESSAGES, SCpnt, + "starting"); switch (where_from) { case TYPE_QUEUE: @@ -2094,13 +2149,13 @@ * @info: interface that completed * @SCpnt: command that completed * @result: driver byte of result - * + * * Finish processing automatic request sense command */ static void fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result) { - fas216_log(info, LOG_CONNECT, + fas216_log_target(info, LOG_CONNECT, SCpnt->target, "request sense complete, result=0x%04x%02x%02x", result, SCpnt->SCp.Message, SCpnt->SCp.Status); @@ -2127,7 +2182,7 @@ * @info: interface that completed * @SCpnt: command that completed * @result: driver byte of result - * + * * Finish processing of standard command */ static void @@ -2138,17 +2193,14 @@ SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 | info->scsi.SCp.Status; -#ifdef DEBUG_CONNECT - printk("scsi%d.%c: command complete, result=%08X, command=", - info->host->host_no, '0' + SCpnt->target, SCpnt->result); - print_command(SCpnt->cmnd); -#endif + fas216_log_command(info, LOG_CONNECT, SCpnt, + "command complete, result=0x%08x", SCpnt->result); /* - * If the driver detected an error, or the command - * was request sense, then we're all done. + * If the driver detected an error, we're all done. */ - if (result != DID_OK || SCpnt->cmnd[0] == REQUEST_SENSE) + if (host_byte(SCpnt->result) != DID_OK || + msg_byte(SCpnt->result) != COMMAND_COMPLETE) goto done; /* @@ -2163,7 +2215,7 @@ * If the command did not complete with GOOD status, * we are all done here. */ - if (info->scsi.SCp.Status != GOOD) + if (status_byte(SCpnt->result) != GOOD) goto done; /* @@ -2177,17 +2229,19 @@ switch (SCpnt->cmnd[0]) { case INQUIRY: case START_STOP: -// case READ_CAPACITY: case MODE_SENSE: break; default: printk(KERN_ERR "scsi%d.%c: incomplete data transfer " - "detected: res=%08X ptr=%p len=%X command=", + "detected: res=%08X ptr=%p len=%X CDB: ", info->host->host_no, '0' + SCpnt->target, SCpnt->result, info->scsi.SCp.ptr, info->scsi.SCp.this_residual); print_command(SCpnt->cmnd); + SCpnt->result &= ~(255 << 16); + SCpnt->result |= DID_BAD_TARGET << 16; + goto request_sense; } } @@ -2202,6 +2256,11 @@ request_sense: + if (SCpnt->cmnd[0] == REQUEST_SENSE) + goto done; + + fas216_log_target(info, LOG_CONNECT, SCpnt->target, + "requesting sense"); memset(SCpnt->cmnd, 0, sizeof (SCpnt->cmnd)); SCpnt->cmnd[0] = REQUEST_SENSE; SCpnt->cmnd[1] = SCpnt->lun << 5; @@ -2213,6 +2272,7 @@ SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer); SCpnt->SCp.Message = 0; SCpnt->SCp.Status = 0; + SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer); SCpnt->sc_data_direction = SCSI_DATA_READ; SCpnt->use_sg = 0; SCpnt->tag = 0; @@ -2233,7 +2293,7 @@ * fas216_done - complete processing for current command * @info: interface that completed * @result: driver byte of result - * + * * Complete processing for current command */ static void fas216_done(FAS216_Info *info, unsigned int result) @@ -2263,7 +2323,7 @@ */ if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) { printk("scsi%d.%c: zero bytes left to transfer, but " - "buffer pointer still valid: ptr=%p len=%08x command=", + "buffer pointer still valid: ptr=%p len=%08x CDB: ", info->host->host_no, '0' + SCpnt->target, info->scsi.SCp.ptr, info->scsi.SCp.this_residual); info->scsi.SCp.ptr = NULL; @@ -2298,9 +2358,9 @@ * fas216_queue_command - queue a command for adapter to process. * @SCpnt: Command to queue * @done: done function to call once command is complete - * + * * Queue a command for adapter to process. - * Returns: 0 in success, else error. + * Returns: 0 on success, else error. * Notes: io_request_lock is held, interrupts are disabled. */ int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) @@ -2310,11 +2370,8 @@ fas216_checkmagic(info); -#ifdef DEBUG_CONNECT - printk("scsi%d.H: received command for id %d (%p) ", - SCpnt->host->host_no, SCpnt->target, SCpnt); - print_command(SCpnt->cmnd); -#endif + fas216_log_command(info, LOG_CONNECT, SCpnt, + "received command (%p)", SCpnt); SCpnt->scsi_done = done; SCpnt->host_scribble = (void *)fas216_std_done; @@ -2341,10 +2398,8 @@ fas216_kick(info); spin_unlock(&info->host_lock); -#ifdef DEBUG_CONNECT - printk("scsi%d.H: queue %s\n", info->host->host_no, + fas216_log_target(info, LOG_CONNECT, -1, "queue %s", result ? "failure" : "success"); -#endif return result; } @@ -2352,7 +2407,7 @@ /** * fas216_internal_done - trigger restart of a waiting thread in fas216_command * @SCpnt: Command to wake - * + * * Trigger restart of a waiting thread in fas216_command */ static void fas216_internal_done(Scsi_Cmnd *SCpnt) @@ -2366,9 +2421,9 @@ /** * fas216_command - queue a command for adapter to process. - * @SCpnt: Command to queue - * - * Qqueue a command for adapter to process. + * @SCpnt: Command to queue + * + * Queue a command for adapter to process. * Returns: scsi result code. * Notes: io_request_lock is held, interrupts are disabled. */ @@ -2405,9 +2460,9 @@ * and go to sleep if we know that the device is going * to be some time (eg, disconnected). */ - if (inb(REG_STAT(info)) & STAT_INT) { + if (fas216_readb(info, REG_STAT) & STAT_INT) { spin_lock_irq(info->host->host_lock); - fas216_intr(info->host); + fas216_intr(info); spin_unlock_irq(info->host->host_lock); } } @@ -2446,7 +2501,7 @@ /** * fas216_do_abort - decide how to abort a command * @SCpnt: command to abort - * + * * Decide how to abort a command. * Returns: abort status */ @@ -2512,7 +2567,7 @@ /** * fas216_eh_abort - abort this command * @SCpnt: command to abort - * + * * Abort this command. * Returns: FAILED if unable to abort * Notes: io_request_lock is taken, and irqs are disabled @@ -2567,12 +2622,12 @@ /** * fas216_eh_device_reset - Reset the device associated with this command - * @SCpnt: command specifing device to reset - * + * @SCpnt: command specifing device to reset + * * Reset the device associated with this command. * Returns: FAILED if unable to reset. * Notes: We won't be re-entered, so we'll only have one device - * reset on the go at one time. + * reset on the go at one time. */ int fas216_eh_device_reset(Scsi_Cmnd *SCpnt) { @@ -2650,7 +2705,7 @@ /** * fas216_eh_bus_reset - Reset the bus associated with the command * @SCpnt: command specifing bus to reset - * + * * Reset the bus associated with the command. * Returns: FAILED if unable to reset. * Notes: Further commands are blocked. @@ -2672,13 +2727,13 @@ * Stop all activity on this interface. */ fas216_aborttransfer(info); - outb(info->scsi.cfg[2], REG_CNTL3(info)); + fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]); /* * Clear any pending interrupts. */ - while (inb(REG_STAT(info)) & STAT_INT) - inb(REG_INST(info)); + while (fas216_readb(info, REG_STAT) & STAT_INT) + fas216_readb(info, REG_INST); info->rst_bus_status = 0; @@ -2728,26 +2783,26 @@ /** * fas216_init_chip - Initialise FAS216 state after reset - * @info: state structure for interface - * + * @info: state structure for interface + * * Initialise FAS216 state after reset */ static void fas216_init_chip(FAS216_Info *info) { - outb(fas216_clockrate(info->ifcfg.clockrate), REG_CLKF(info)); - outb(info->scsi.cfg[0], REG_CNTL1(info)); - outb(info->scsi.cfg[1], REG_CNTL2(info)); - outb(info->scsi.cfg[2], REG_CNTL3(info)); - outb(info->ifcfg.select_timeout, REG_STIM(info)); - outb(0, REG_SOF(info)); - outb(info->scsi.async_stp, REG_STP(info)); - outb(info->scsi.cfg[0], REG_CNTL1(info)); + fas216_writeb(info, REG_CLKF, fas216_clockrate(info->ifcfg.clockrate)); + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]); + fas216_writeb(info, REG_CNTL2, info->scsi.cfg[1]); + fas216_writeb(info, REG_CNTL3, info->scsi.cfg[2]); + fas216_writeb(info, REG_STIM, info->ifcfg.select_timeout); + fas216_writeb(info, REG_SOF, 0); + fas216_writeb(info, REG_STP, info->scsi.async_stp); + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]); } /** * fas216_eh_host_reset - Reset the host associated with this command * @SCpnt: command specifing host to reset - * + * * Reset the host associated with this command. * Returns: FAILED if unable to reset. * Notes: io_request_lock is taken, and irqs are disabled @@ -2811,56 +2866,56 @@ /* * Reset the chip. */ - outb(CMD_RESETCHIP, REG_CMD(info)); + fas216_writeb(info, REG_CMD, CMD_RESETCHIP); udelay(50); - outb(CMD_NOP, REG_CMD(info)); + fas216_writeb(info, REG_CMD, CMD_NOP); /* * Check to see if control reg 2 is present. */ - outb(0, REG_CNTL3(info)); - outb(CNTL2_S2FE, REG_CNTL2(info)); + fas216_writeb(info, REG_CNTL3, 0); + fas216_writeb(info, REG_CNTL2, CNTL2_S2FE); /* * If we are unable to read back control reg 2 * correctly, it is not present, and we have a * NCR53C90. */ - if ((inb(REG_CNTL2(info)) & (~0xe0)) != CNTL2_S2FE) + if ((fas216_readb(info, REG_CNTL2) & (~0xe0)) != CNTL2_S2FE) return TYPE_NCR53C90; /* * Now, check control register 3 */ - outb(0, REG_CNTL2(info)); - outb(0, REG_CNTL3(info)); - outb(5, REG_CNTL3(info)); + fas216_writeb(info, REG_CNTL2, 0); + fas216_writeb(info, REG_CNTL3, 0); + fas216_writeb(info, REG_CNTL3, 5); /* * If we are unable to read the register back * correctly, we have a NCR53C90A */ - if (inb(REG_CNTL3(info)) != 5) + if (fas216_readb(info, REG_CNTL3) != 5) return TYPE_NCR53C90A; /* * Now read the ID from the chip. */ - outb(0, REG_CNTL3(info)); + fas216_writeb(info, REG_CNTL3, 0); - outb(CNTL3_ADIDCHK, REG_CNTL3(info)); - outb(0, REG_CNTL3(info)); + fas216_writeb(info, REG_CNTL3, CNTL3_ADIDCHK); + fas216_writeb(info, REG_CNTL3, 0); - outb(CMD_RESETCHIP, REG_CMD(info)); - udelay(5); - outb(CMD_WITHDMA | CMD_NOP, REG_CMD(info)); + fas216_writeb(info, REG_CMD, CMD_RESETCHIP); + udelay(50); + fas216_writeb(info, REG_CMD, CMD_WITHDMA | CMD_NOP); - outb(CNTL2_ENF, REG_CNTL2(info)); - outb(CMD_RESETCHIP, REG_CMD(info)); - udelay(5); - outb(CMD_NOP, REG_CMD(info)); + fas216_writeb(info, REG_CNTL2, CNTL2_ENF); + fas216_writeb(info, REG_CMD, CMD_RESETCHIP); + udelay(50); + fas216_writeb(info, REG_CMD, CMD_NOP); - rev = inb(REG1_ID(info)); + rev = fas216_readb(info, REG_ID); family = rev >> 3; rev &= 7; @@ -2886,10 +2941,10 @@ return TYPE_NCR53C9x; } -/** +/** * fas216_reset_state - Initialise driver internal state * @info: state to initialise - * + * * Initialise driver internal state */ static void fas216_reset_state(FAS216_Info *info) @@ -2927,23 +2982,23 @@ } /** - * fas216_init - initialise FAS/NCR/AMD SCSI ic. - * @instance: a driver-specific filled-out structure - * - * Initialise FAS/NCR/AMD SCSI ic. + * fas216_init - initialise FAS/NCR/AMD SCSI structures. + * @host: a driver-specific filled-out structure + * + * Initialise FAS/NCR/AMD SCSI structures. * Returns: 0 on success */ -int fas216_init(struct Scsi_Host *instance) +int fas216_init(struct Scsi_Host *host) { - FAS216_Info *info = (FAS216_Info *)instance->hostdata; - int type; + FAS216_Info *info = (FAS216_Info *)host->hostdata; info->magic_start = MAGIC; info->magic_end = MAGIC; - info->host = instance; - info->scsi.cfg[0] = instance->this_id | CNTL1_PERE; + info->host = host; + info->scsi.cfg[0] = host->this_id | CNTL1_PERE; info->scsi.cfg[1] = CNTL2_ENF | CNTL2_S2FE; - info->scsi.cfg[2] = info->ifcfg.cntl3 | CNTL3_ADIDCHK | CNTL3_G2CB; + info->scsi.cfg[2] = info->ifcfg.cntl3 | + CNTL3_ADIDCHK | CNTL3_G2CB | CNTL3_LBTM; info->scsi.async_stp = fas216_syncperiod(info, info->ifcfg.asyncperiod); info->rst_dev_status = -1; @@ -2960,13 +3015,29 @@ msgqueue_initialise(&info->scsi.msgs); if (!queue_initialise(&info->queues.issue)) - return 1; + return -ENOMEM; if (!queue_initialise(&info->queues.disconnected)) { queue_free(&info->queues.issue); - return 1; + return -ENOMEM; } + return 0; +} + +/** + * fas216_add - initialise FAS/NCR/AMD SCSI ic. + * @host: a driver-specific filled-out structure + * @dev: parent device + * + * Initialise FAS/NCR/AMD SCSI ic. + * Returns: 0 on success + */ +int fas216_add(struct Scsi_Host *host, struct device *dev) +{ + FAS216_Info *info = (FAS216_Info *)host->hostdata; + int type, ret; + fas216_reset_state(info); type = fas216_detect_type(info); info->scsi.type = chip_types[type]; @@ -2983,8 +3054,8 @@ * the resulting reset interrupt, so mask it * out. */ - outb(info->scsi.cfg[0] | CNTL1_DISR, REG_CNTL1(info)); - outb(CMD_RESETSCSI, REG_CMD(info)); + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0] | CNTL1_DISR); + fas216_writeb(info, REG_CMD, CMD_RESETSCSI); /* * scsi standard says wait 250ms @@ -2993,60 +3064,40 @@ scsi_sleep(100*HZ/100); spin_lock_irq(info->host->host_lock); - outb(info->scsi.cfg[0], REG_CNTL1(info)); - inb(REG_INST(info)); + fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]); + fas216_readb(info, REG_INST); fas216_checkmagic(info); - return 0; + ret = scsi_add_host(host, dev); + if (ret) + fas216_writeb(info, REG_CMD, CMD_RESETCHIP); + + return ret; } -/** - * fas216_release - release all resources for FAS/NCR/AMD SCSI ic. - * @instance: a driver-specific filled-out structure - * - * release all resources and put everything to bed for FAS/NCR/AMD SCSI ic, - * Returns: 0 on success. - */ -int fas216_release(struct Scsi_Host *instance) +void fas216_remove(struct Scsi_Host *host) { - FAS216_Info *info = (FAS216_Info *)instance->hostdata; + FAS216_Info *info = (FAS216_Info *)host->hostdata; fas216_checkmagic(info); + scsi_remove_host(host); - outb(CMD_RESETCHIP, REG_CMD(info)); - queue_free(&info->queues.disconnected); - queue_free(&info->queues.issue); - - return 0; + fas216_writeb(info, REG_CMD, CMD_RESETCHIP); } /** - * fas216_info - generate a string containing information about host. - * @info: FAS216 host information - * @buffer: string buffer to build string - * - * Generate a string containing information about this host. - * Returns: size of built string + * fas216_release - release all resources for FAS/NCR/AMD SCSI ic. + * @host: a driver-specific filled-out structure + * + * release all resources and put everything to bed for FAS/NCR/AMD SCSI ic. */ -int fas216_info(FAS216_Info *info, char *buffer) +void fas216_release(struct Scsi_Host *host) { - char *p = buffer; - - p += sprintf(p, "(%s) at port 0x%08lX ", - info->scsi.type, info->host->io_port); + FAS216_Info *info = (FAS216_Info *)host->hostdata; - if (info->host->irq != NO_IRQ) - p += sprintf(p, "irq %d ", info->host->irq); - else - p += sprintf(p, "no irq "); - - if (info->host->dma_channel != NO_DMA) - p += sprintf(p, "dma %d ", info->host->dma_channel); - else - p += sprintf(p, "no dma "); - - return p - buffer; + queue_free(&info->queues.disconnected); + queue_free(&info->queues.issue); } int fas216_print_host(FAS216_Info *info, char *buffer) @@ -3054,7 +3105,7 @@ return sprintf(buffer, "\n" "Chip : %s\n" - " Address: 0x%08lX\n" + " Address: 0x%08lx\n" " IRQ : %d\n" " DMA : %d\n", info->scsi.type, info->host->io_port, @@ -3116,11 +3167,12 @@ return p - buffer; } -EXPORT_SYMBOL(fas216_info); EXPORT_SYMBOL(fas216_init); +EXPORT_SYMBOL(fas216_add); EXPORT_SYMBOL(fas216_queue_command); EXPORT_SYMBOL(fas216_command); EXPORT_SYMBOL(fas216_intr); +EXPORT_SYMBOL(fas216_remove); EXPORT_SYMBOL(fas216_release); EXPORT_SYMBOL(fas216_eh_abort); EXPORT_SYMBOL(fas216_eh_device_reset); diff -Nru a/drivers/acorn/scsi/fas216.h b/drivers/acorn/scsi/fas216.h --- a/drivers/acorn/scsi/fas216.h Sun Feb 9 21:13:37 2003 +++ b/drivers/acorn/scsi/fas216.h Sun Feb 9 21:13:37 2003 @@ -22,18 +22,18 @@ /* FAS register definitions */ /* transfer count low */ -#define REG_CTCL(x) ((x)->scsi.io_port) -#define REG_STCL(x) ((x)->scsi.io_port) +#define REG_CTCL (0) +#define REG_STCL (0) /* transfer count medium */ -#define REG_CTCM(x) ((x)->scsi.io_port + (1 << (x)->scsi.io_shift)) -#define REG_STCM(x) ((x)->scsi.io_port + (1 << (x)->scsi.io_shift)) +#define REG_CTCM (1) +#define REG_STCM (1) /* fifo data */ -#define REG_FF(x) ((x)->scsi.io_port + (2 << (x)->scsi.io_shift)) +#define REG_FF (2) /* command */ -#define REG_CMD(x) ((x)->scsi.io_port + (3 << (x)->scsi.io_shift)) +#define REG_CMD (3) #define CMD_NOP 0x00 #define CMD_FLUSHFIFO 0x01 #define CMD_RESETCHIP 0x02 @@ -57,7 +57,7 @@ #define CMD_WITHDMA 0x80 /* status register (read) */ -#define REG_STAT(x) ((x)->scsi.io_port + (4 << (x)->scsi.io_shift)) +#define REG_STAT (4) #define STAT_IO (1 << 0) /* IO phase */ #define STAT_CD (1 << 1) /* CD phase */ #define STAT_MSG (1 << 2) /* MSG phase */ @@ -76,11 +76,11 @@ #define STAT_MESGIN (STAT_MSG|STAT_CD|STAT_IO) /* Message In */ /* bus ID for select / reselect */ -#define REG_SDID(x) ((x)->scsi.io_port + (4 << (x)->scsi.io_shift)) +#define REG_SDID (4) #define BUSID(target) ((target) & 7) /* Interrupt status register (read) */ -#define REG_INST(x) ((x)->scsi.io_port + (5 << (x)->scsi.io_shift)) +#define REG_INST (5) #define INST_SELWOATN (1 << 0) /* Select w/o ATN */ #define INST_SELATN (1 << 1) /* Select w/ATN */ #define INST_RESELECTED (1 << 2) /* Reselected */ @@ -91,10 +91,10 @@ #define INST_BUSRESET (1 << 7) /* SCSI Bus reset */ /* Timeout register (write) */ -#define REG_STIM(x) ((x)->scsi.io_port + (5 << (x)->scsi.io_shift)) +#define REG_STIM (5) /* Sequence step register (read) */ -#define REG_IS(x) ((x)->scsi.io_port + (6 << (x)->scsi.io_shift)) +#define REG_IS (6) #define IS_BITS 0x07 #define IS_SELARB 0x00 /* Select & Arb ok */ #define IS_MSGBYTESENT 0x01 /* One byte message sent*/ @@ -104,18 +104,18 @@ #define IS_SOF 0x08 /* Sync off flag */ /* Transfer period step (write) */ -#define REG_STP(x) ((x)->scsi.io_port + (6 << (x)->scsi.io_shift)) +#define REG_STP (6) /* Synchronous Offset (write) */ -#define REG_SOF(x) ((x)->scsi.io_port + (7 << (x)->scsi.io_shift)) +#define REG_SOF (7) /* Fifo state register (read) */ -#define REG_CFIS(x) ((x)->scsi.io_port + (7 << (x)->scsi.io_shift)) +#define REG_CFIS (7) #define CFIS_CF 0x1f /* Num bytes in FIFO */ #define CFIS_IS 0xe0 /* Step */ /* config register 1 */ -#define REG_CNTL1(x) ((x)->scsi.io_port + (8 << (x)->scsi.io_shift)) +#define REG_CNTL1 (8) #define CNTL1_CID (7 << 0) /* Chip ID */ #define CNTL1_STE (1 << 3) /* Self test enable */ #define CNTL1_PERE (1 << 4) /* Parity enable reporting en. */ @@ -124,7 +124,7 @@ #define CNTL1_ETM (1 << 7) /* Extended Timing Mode */ /* Clock conversion factor (read) */ -#define REG_CLKF(x) ((x)->scsi.io_port + (9 << (x)->scsi.io_shift)) +#define REG_CLKF (9) #define CLKF_F37MHZ 0x00 /* 35.01 - 40 MHz */ #define CLKF_F10MHZ 0x02 /* 10 MHz */ #define CLKF_F12MHZ 0x03 /* 10.01 - 15 MHz */ @@ -134,13 +134,13 @@ #define CLKF_F32MHZ 0x07 /* 30.01 - 35 MHz */ /* Chip test register (write) */ -#define REG0_FTM(x) ((x)->scsi.io_port + (10 << (x)->scsi.io_shift)) +#define REG_FTM (10) #define TEST_FTM 0x01 /* Force target mode */ #define TEST_FIM 0x02 /* Force initiator mode */ #define TEST_FHI 0x04 /* Force high impedance mode */ /* Configuration register 2 (read/write) */ -#define REG_CNTL2(x) ((x)->scsi.io_port + (11 << (x)->scsi.io_shift)) +#define REG_CNTL2 (11) #define CNTL2_PGDP (1 << 0) /* Pass Th/Generate Data Parity */ #define CNTL2_PGRP (1 << 1) /* Pass Th/Generate Reg Parity */ #define CNTL2_ACDPE (1 << 2) /* Abort on Cmd/Data Parity Err */ @@ -151,7 +151,7 @@ #define CNTL2_DAE (1 << 7) /* Data Alignment Enable */ /* Configuration register 3 (read/write) */ -#define REG_CNTL3(x) ((x)->scsi.io_port + (12 << (x)->scsi.io_shift)) +#define REG_CNTL3 (12) #define CNTL3_BS8 (1 << 0) /* Burst size 8 */ #define CNTL3_MDM (1 << 1) /* Modify DMA mode */ #define CNTL3_LBTM (1 << 2) /* Last Byte Transfer mode */ @@ -162,14 +162,14 @@ #define CNTL3_ADIDCHK (1 << 7) /* Additional ID check */ /* High transfer count (read/write) */ -#define REG_CTCH(x) ((x)->scsi.io_port + (14 << (x)->scsi.io_shift)) -#define REG_STCH(x) ((x)->scsi.io_port + (14 << (x)->scsi.io_shift)) +#define REG_CTCH (14) +#define REG_STCH (14) -/* ID reigster (read only) */ -#define REG1_ID(x) ((x)->scsi.io_port + (14 << (x)->scsi.io_shift)) +/* ID register (read only) */ +#define REG_ID (14) /* Data alignment */ -#define REG0_DAL(x) ((x)->scsi.io_port + (15 << (x)->scsi.io_shift)) +#define REG_DAL (15) typedef enum { PHASE_IDLE, /* we're not planning on doing anything */ @@ -212,6 +212,9 @@ #define MAGIC 0x441296bdUL #define NR_MSGS 8 +#define FASCAP_DMA (1 << 0) +#define FASCAP_PSEUDODMA (1 << 1) + typedef struct { unsigned long magic_start; spinlock_t host_lock; @@ -233,12 +236,13 @@ /* driver information */ struct { + phase_t phase; /* current phase */ + void *io_base; /* iomem base of FAS216 */ unsigned int io_port; /* base address of FAS216 */ unsigned int io_shift; /* shift to adjust reg offsets by */ - unsigned int irq; /* interrupt */ unsigned char cfg[4]; /* configuration registers */ const char *type; /* chip type */ - phase_t phase; /* current phase */ + unsigned int irq; /* interrupt */ struct { unsigned char target; /* reconnected target */ @@ -253,7 +257,6 @@ unsigned int async_stp; /* Async transfer STP value */ unsigned char msgin_fifo; /* bytes in fifo at time of message in */ unsigned char message[256]; /* last message received from device */ - unsigned int msglen; /* length of last message received */ unsigned char disconnectable:1; /* this command can be disconnected */ unsigned char aborting:1; /* aborting command */ @@ -281,6 +284,7 @@ unsigned char wide_max_size; /* Maximum wide transfer size */ unsigned char cntl3; /* Control Reg 3 */ unsigned int asyncperiod; /* Async transfer period (ns) */ + unsigned int capabilities; /* driver capabilities */ unsigned int disconnect_ok:1; /* Disconnects allowed? */ } ifcfg; @@ -319,26 +323,18 @@ } FAS216_Info; /* Function: int fas216_init (struct Scsi_Host *instance) - * Purpose : initialise FAS/NCR/AMD SCSI ic. + * Purpose : initialise FAS/NCR/AMD SCSI structures. * Params : instance - a driver-specific filled-out structure * Returns : 0 on success */ extern int fas216_init (struct Scsi_Host *instance); -/* Function: int fas216_abort (Scsi_Cmnd *SCpnt) - * Purpose : abort a command if something horrible happens. - * Params : SCpnt - Command that is believed to be causing a problem. - * Returns : one of SCSI_ABORT_ macros. - */ -extern int fas216_abort (Scsi_Cmnd *); - -/* Function: int fas216_reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags) - * Purpose : resets the adapter if something horrible happens. - * Params : SCpnt - Command that is believed to be causing a problem. - * reset_flags - flags indicating reset type that is believed to be required. - * Returns : one of SCSI_RESET_ macros, or'd with the SCSI_RESET_*_RESET macros. +/* Function: int fas216_add (struct Scsi_Host *instance, struct device *dev) + * Purpose : initialise FAS/NCR/AMD SCSI ic. + * Params : instance - a driver-specific filled-out structure + * Returns : 0 on success */ -extern int fas216_reset (Scsi_Cmnd *, unsigned int); +extern int fas216_add (struct Scsi_Host *instance, struct device *dev); /* Function: int fas216_queue_command (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) * Purpose : queue a command for adapter to process. @@ -355,20 +351,21 @@ */ extern int fas216_command (Scsi_Cmnd *); -/* Function: void fas216_intr (struct Scsi_Host *instance) +/* Function: void fas216_intr (FAS216_Info *info) * Purpose : handle interrupts from the interface to progress a command - * Params : instance - interface to service + * Params : info - interface to service */ -extern void fas216_intr (struct Scsi_Host *instance); +extern void fas216_intr (FAS216_Info *info); + +extern void fas216_remove (struct Scsi_Host *instance); -/* Function: int fas216_release (struct Scsi_Host *instance) +/* Function: void fas216_release (struct Scsi_Host *instance) * Purpose : release all resources and put everything to bed for FAS/NCR/AMD SCSI ic. * Params : instance - a driver-specific filled-out structure * Returns : 0 on success */ -extern int fas216_release (struct Scsi_Host *instance); +extern void fas216_release (struct Scsi_Host *instance); -extern int fas216_info(FAS216_Info *info, char *buffer); extern int fas216_print_host(FAS216_Info *info, char *buffer); extern int fas216_print_stats(FAS216_Info *info, char *buffer); extern int fas216_print_device(FAS216_Info *info, Scsi_Device *scd, char *buffer); diff -Nru a/drivers/acorn/scsi/oak.c b/drivers/acorn/scsi/oak.c --- a/drivers/acorn/scsi/oak.c Sun Feb 9 21:13:28 2003 +++ b/drivers/acorn/scsi/oak.c Sun Feb 9 21:13:28 2003 @@ -192,7 +192,8 @@ .remove = __devexit_p(oakscsi_remove), .id_table = oakscsi_cids, .drv = { - .name = "oakscsi", + .devclass = &shost_devclass, + .name = "oakscsi", }, }; diff -Nru a/drivers/acorn/scsi/powertec.c b/drivers/acorn/scsi/powertec.c --- a/drivers/acorn/scsi/powertec.c Sun Feb 9 21:13:33 2003 +++ b/drivers/acorn/scsi/powertec.c Sun Feb 9 21:13:33 2003 @@ -1,7 +1,7 @@ /* * linux/drivers/acorn/scsi/powertec.c * - * Copyright (C) 1997-2002 Russell King + * Copyright (C) 1997-2003 Russell King * * 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 @@ -32,24 +32,23 @@ #include -#define POWERTEC_FAS216_OFFSET 0xc00 -#define POWERTEC_FAS216_SHIFT 4 -#define POWERTEC_FAS216_SIZE (16 << POWERTEC_FAS216_SHIFT) +#define POWERTEC_FAS216_OFFSET 0x3000 +#define POWERTEC_FAS216_SHIFT 6 -#define POWERTEC_INTR_STATUS 0x800 +#define POWERTEC_INTR_STATUS 0x2000 #define POWERTEC_INTR_BIT 0x80 -#define POWERTEC_RESET_CONTROL 0x406 +#define POWERTEC_RESET_CONTROL 0x1018 #define POWERTEC_RESET_BIT 1 -#define POWERTEC_TERM_CONTROL 0x806 +#define POWERTEC_TERM_CONTROL 0x2018 #define POWERTEC_TERM_ENABLE 1 -#define POWERTEC_INTR_CONTROL 0x407 +#define POWERTEC_INTR_CONTROL 0x101c #define POWERTEC_INTR_ENABLE 1 #define POWERTEC_INTR_DISABLE 0 -#define VERSION "1.00 (13/11/2002 2.5.47)" +#define VERSION "1.10 (19/01/2003 2.5.59)" /* * Use term=0,1,0,0,0 to turn terminators on/off. @@ -60,10 +59,11 @@ #define NR_SG 256 struct powertec_info { - FAS216_Info info; - unsigned int term_port; - unsigned int term_ctl; - struct scatterlist sg[NR_SG]; + FAS216_Info info; + struct expansion_card *ec; + void *term_port; + unsigned int term_ctl; + struct scatterlist sg[NR_SG]; }; /* Prototype: void powertecscsi_irqenable(ec, irqnr) @@ -74,8 +74,7 @@ static void powertecscsi_irqenable(struct expansion_card *ec, int irqnr) { - unsigned int port = (unsigned int)ec->irq_data; - outb(POWERTEC_INTR_ENABLE, port); + writeb(POWERTEC_INTR_ENABLE, ec->irq_data); } /* Prototype: void powertecscsi_irqdisable(ec, irqnr) @@ -86,8 +85,7 @@ static void powertecscsi_irqdisable(struct expansion_card *ec, int irqnr) { - unsigned int port = (unsigned int)ec->irq_data; - outb(POWERTEC_INTR_DISABLE, port); + writeb(POWERTEC_INTR_DISABLE, ec->irq_data); } static const expansioncard_ops_t powertecscsi_ops = { @@ -106,7 +104,7 @@ struct powertec_info *info = (struct powertec_info *)host->hostdata; info->term_ctl = on_off ? POWERTEC_TERM_ENABLE : 0; - outb(info->term_ctl, info->term_port); + writeb(info->term_ctl, info->term_port); } /* Prototype: void powertecscsi_intr(irq, *dev_id, *regs) @@ -118,9 +116,9 @@ static void powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs) { - struct Scsi_Host *host = (struct Scsi_Host *)dev_id; + struct powertec_info *info = dev_id; - fas216_intr(host); + fas216_intr(&info->info); } /* Prototype: fasdmatype_t powertecscsi_dma_setup(host, SCpnt, direction, min_type) @@ -139,8 +137,8 @@ struct device *dev = scsi_get_device(host); int dmach = host->dma_channel; - if (dmach != NO_DMA && - (min_type == fasdma_real_all || SCp->this_residual >= 512)) { + if (info->info.ifcfg.capabilities & FASCAP_DMA && + min_type == fasdma_real_all) { int bufs, map_dir, dma_dir; bufs = copy_SCp_to_sg(&info->sg[0], SCp, NR_SG); @@ -188,13 +186,11 @@ const char *powertecscsi_info(struct Scsi_Host *host) { struct powertec_info *info = (struct powertec_info *)host->hostdata; - static char string[100], *p; + static char string[150]; - p = string; - p += sprintf(p, "%s ", host->hostt->name); - p += fas216_info(&info->info, p); - p += sprintf(p, "v%s terminators o%s", - VERSION, info->term_ctl ? "n" : "ff"); + sprintf(string, "%s (%s) in slot %d v%s terminators o%s", + host->hostt->name, info->info.scsi.type, info->ec->slot_no, + VERSION, info->term_ctl ? "n" : "ff"); return string; } @@ -262,7 +258,6 @@ begin = 0; pos = sprintf(buffer, "PowerTec SCSI driver v%s\n", VERSION); - pos += fas216_print_host(&info->info, buffer + pos); pos += sprintf(buffer + pos, "Term : o%s\n", info->term_ctl ? "n" : "ff"); @@ -290,6 +285,30 @@ return pos; } +static ssize_t powertecscsi_show_term(struct device *dev, char *buf) +{ + struct expansion_card *ec = ECARD_DEV(dev); + struct Scsi_Host *host = ecard_get_drvdata(ec); + struct powertec_info *info = (struct powertec_info *)host->hostdata; + + return sprintf(buf, "%d\n", info->term_ctl ? 1 : 0); +} + +static ssize_t +powertecscsi_store_term(struct device *dev, const char *buf, size_t len) +{ + struct expansion_card *ec = ECARD_DEV(dev); + struct Scsi_Host *host = ecard_get_drvdata(ec); + + if (len > 1) + powertecscsi_terminator_ctl(host, buf[0] != '0'); + + return len; +} + +static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR, + powertecscsi_show_term, powertecscsi_store_term); + static Scsi_Host_Template powertecscsi_template = { .module = THIS_MODULE, .proc_info = powertecscsi_proc_info, @@ -302,10 +321,10 @@ .eh_device_reset_handler = fas216_eh_device_reset, .eh_abort_handler = fas216_eh_abort, - .can_queue = 1, + .can_queue = 8, .this_id = 7, .sg_tablesize = SG_ALL, - .cmd_per_lun = 1, + .cmd_per_lun = 2, .use_clustering = ENABLE_CLUSTERING, .proc_name = "powertec", }; @@ -314,37 +333,50 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; - struct powertec_info *info; - int ret = -ENOMEM; + struct powertec_info *info; + unsigned long resbase, reslen; + unsigned char *base; + int ret; + + resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST); + reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST); + + if (!request_mem_region(resbase, reslen, "powertecscsi")) { + ret = -EBUSY; + goto out; + } + + base = ioremap(resbase, reslen); + if (!base) { + ret = -ENOMEM; + goto out_region; + } host = scsi_register(&powertecscsi_template, sizeof (struct powertec_info)); - if (!host) - goto out; + if (!host) { + ret = -ENOMEM; + goto out_unmap; + } - host->io_port = ecard_address(ec, ECARD_IOC, ECARD_FAST); + host->base = (unsigned long)base; host->irq = ec->irq; host->dma_channel = ec->dma; - if (!request_region(host->io_port + POWERTEC_FAS216_OFFSET, - POWERTEC_FAS216_SIZE, "powertec2-fas")) { - ret = -EBUSY; - goto out_free; - } - - ec->irqaddr = (unsigned char *) - ioaddr(host->io_port + POWERTEC_INTR_STATUS); + ec->irqaddr = base + POWERTEC_INTR_STATUS; ec->irqmask = POWERTEC_INTR_BIT; - ec->irq_data = (void *)(host->io_port + POWERTEC_INTR_CONTROL); - ec->ops = (expansioncard_ops_t *)&powertecscsi_ops; + ec->irq_data = base + POWERTEC_INTR_CONTROL; + ec->ops = &powertecscsi_ops; ecard_set_drvdata(ec, host); info = (struct powertec_info *)host->hostdata; - info->term_port = host->io_port + POWERTEC_TERM_CONTROL; + info->term_port = base + POWERTEC_TERM_CONTROL; powertecscsi_terminator_ctl(host, term[ec->slot_no]); - info->info.scsi.io_port = host->io_port + POWERTEC_FAS216_OFFSET; + device_create_file(&ec->dev, &dev_attr_bus_term); + + info->info.scsi.io_base = base + POWERTEC_FAS216_OFFSET; info->info.scsi.io_shift = POWERTEC_FAS216_SHIFT; info->info.scsi.irq = host->irq; info->info.ifcfg.clockrate = 40; /* MHz */ @@ -354,16 +386,21 @@ info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK; info->info.ifcfg.disconnect_ok = 1; info->info.ifcfg.wide_max_size = 0; + info->info.ifcfg.capabilities = 0; info->info.dma.setup = powertecscsi_dma_setup; info->info.dma.pseudo = NULL; info->info.dma.stop = powertecscsi_dma_stop; + ret = fas216_init(host); + if (ret) + goto out_free; + ret = request_irq(host->irq, powertecscsi_intr, - SA_INTERRUPT, "powertec", host); + SA_INTERRUPT, "powertec", info); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, host->irq, ret); - goto out_region; + goto out_release; } if (host->dma_channel != NO_DMA) { @@ -373,26 +410,31 @@ host->dma_channel = NO_DMA; } else { set_dma_speed(host->dma_channel, 180); + info->info.ifcfg.capabilities |= FASCAP_DMA; } } - fas216_init(host); - - ret = scsi_add_host(host, &ec->dev); + ret = fas216_add(host, &ec->dev); if (ret == 0) goto out; - fas216_release(host); - if (host->dma_channel != NO_DMA) free_dma(host->dma_channel); free_irq(host->irq, host); - out_region: - release_region(host->io_port + POWERTEC_FAS216_OFFSET, - POWERTEC_FAS216_SIZE); + + out_release: + fas216_release(host); + out_free: + device_remove_file(&ec->dev, &dev_attr_bus_term); scsi_unregister(host); + out_unmap: + iounmap(base); + + out_region: + release_mem_region(resbase, reslen); + out: return ret; } @@ -400,16 +442,26 @@ static void __devexit powertecscsi_remove(struct expansion_card *ec) { struct Scsi_Host *host = ecard_get_drvdata(ec); + struct powertecscsi_info *info = (struct powertecscsi_info *)host->hostdata; + unsigned long resbase, reslen; ecard_set_drvdata(ec, NULL); - scsi_remove_host(host); - fas216_release(host); + fas216_remove(host); + + device_remove_file(&ec->dev, &dev_attr_bus_term); if (host->dma_channel != NO_DMA) free_dma(host->dma_channel); - free_irq(host->irq, host); - release_region(host->io_port + POWERTEC_FAS216_OFFSET, - POWERTEC_FAS216_SIZE); + free_irq(host->irq, info); + + iounmap((void *)host->base); + + resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST); + reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST); + + release_mem_region(resbase, reslen); + + fas216_release(host); scsi_unregister(host); } @@ -423,7 +475,8 @@ .remove = __devexit_p(powertecscsi_remove), .id_table = powertecscsi_cids, .drv = { - .name = "powertecscsi", + .devclass = &shost_devclass, + .name = "powertecscsi", }, }; diff -Nru a/drivers/acorn/scsi/scsi.h b/drivers/acorn/scsi/scsi.h --- a/drivers/acorn/scsi/scsi.h Sun Feb 9 21:13:29 2003 +++ b/drivers/acorn/scsi/scsi.h Sun Feb 9 21:13:29 2003 @@ -55,8 +55,6 @@ SCp->ptr += 1; SCp->this_residual -= 1; - if (SCp->this_residual == 0) - next_SCp(SCp); return c; } @@ -66,8 +64,6 @@ *SCp->ptr = c; SCp->ptr += 1; SCp->this_residual -= 1; - if (SCp->this_residual == 0) - next_SCp(SCp); } static inline void init_SCp(Scsi_Cmnd *SCpnt) @@ -112,7 +108,7 @@ * we aren't interested in the buffer pointer. */ if (SCpnt->SCp.this_residual == 0 && SCpnt->SCp.ptr) { -#ifdef BELT_AND_BRACES +#if 0 //def BELT_AND_BRACES printk(KERN_WARNING "scsi%d.%c: zero length buffer passed for " "command ", SCpnt->host->host_no, '0' + SCpnt->target); print_command(SCpnt->cmnd); diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig --- a/drivers/acpi/Kconfig Sun Feb 9 21:13:37 2003 +++ b/drivers/acpi/Kconfig Sun Feb 9 21:13:37 2003 @@ -116,14 +116,6 @@ ACPI C2 and C3 processor states to save power, on systems that support it. -config ACPI_PROCESSOR_PERF - bool "Processor Performance States" - depends on X86 && ACPI && !ACPI_HT_ONLY && ACPI_PROCESSOR && CPU_FREQ - help - This driver adds support for CPU frequency scaling, if this is supported - by the hardware and the BIOS. If you are compiling for a mobile system, - say Y. - config ACPI_THERMAL tristate "Thermal Zone" depends on ACPI_PROCESSOR diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile --- a/drivers/acpi/Makefile Sun Feb 9 21:13:36 2003 +++ b/drivers/acpi/Makefile Sun Feb 9 21:13:36 2003 @@ -4,15 +4,13 @@ export ACPI_CFLAGS -ACPI_CFLAGS := -D_LINUX -Idrivers/acpi/include +ACPI_CFLAGS := -D_LINUX -Os -Iinclude/acpi ifdef CONFIG_ACPI_DEBUG ACPI_CFLAGS += -DACPI_DEBUG_OUTPUT endif EXTRA_CFLAGS += $(ACPI_CFLAGS) - -export-objs := acpi_ksyms.o processor.o obj-y := acpi_ksyms.o diff -Nru a/drivers/acpi/ac.c b/drivers/acpi/ac.c --- a/drivers/acpi/ac.c Sun Feb 9 21:13:31 2003 +++ b/drivers/acpi/ac.c Sun Feb 9 21:13:31 2003 @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include "acpi_bus.h" diff -Nru a/drivers/acpi/acpi_bus.h b/drivers/acpi/acpi_bus.h --- a/drivers/acpi/acpi_bus.h Sun Feb 9 21:13:31 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,312 +0,0 @@ -/* - * acpi_bus.h - ACPI Bus Driver ($Revision: 22 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * 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. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#ifndef __ACPI_BUS_H__ -#define __ACPI_BUS_H__ - -#include -#include - -#include "include/acpi.h" - -#define PREFIX "ACPI: " - -extern int acpi_disabled; - -/* TBD: Make dynamic */ -#define ACPI_MAX_HANDLES 10 -struct acpi_handle_list { - u32 count; - acpi_handle handles[ACPI_MAX_HANDLES]; -}; - - -/* acpi_utils.h */ -acpi_status -acpi_extract_package ( - union acpi_object *package, - struct acpi_buffer *format, - struct acpi_buffer *buffer); -acpi_status -acpi_evaluate_integer ( - acpi_handle handle, - acpi_string pathname, - struct acpi_object_list *arguments, - unsigned long *data); -acpi_status -acpi_evaluate_reference ( - acpi_handle handle, - acpi_string pathname, - struct acpi_object_list *arguments, - struct acpi_handle_list *list); - - -#ifdef CONFIG_ACPI_BUS - -#include - -#define ACPI_BUS_FILE_ROOT "acpi" -extern struct proc_dir_entry *acpi_root_dir; -extern FADT_DESCRIPTOR acpi_fadt; - -enum acpi_bus_removal_type { - ACPI_BUS_REMOVAL_NORMAL = 0, - ACPI_BUS_REMOVAL_EJECT, - ACPI_BUS_REMOVAL_SUPRISE, - ACPI_BUS_REMOVAL_TYPE_COUNT -}; - -enum acpi_bus_device_type { - ACPI_BUS_TYPE_DEVICE = 0, - ACPI_BUS_TYPE_POWER, - ACPI_BUS_TYPE_PROCESSOR, - ACPI_BUS_TYPE_THERMAL, - ACPI_BUS_TYPE_SYSTEM, - ACPI_BUS_TYPE_POWER_BUTTON, - ACPI_BUS_TYPE_SLEEP_BUTTON, - ACPI_BUS_DEVICE_TYPE_COUNT -}; - -struct acpi_driver; -struct acpi_device; - - -/* - * ACPI Driver - * ----------- - */ - -typedef int (*acpi_op_add) (struct acpi_device *device); -typedef int (*acpi_op_remove) (struct acpi_device *device, int type); -typedef int (*acpi_op_lock) (struct acpi_device *device, int type); -typedef int (*acpi_op_start) (struct acpi_device *device); -typedef int (*acpi_op_stop) (struct acpi_device *device, int type); -typedef int (*acpi_op_suspend) (struct acpi_device *device, int state); -typedef int (*acpi_op_resume) (struct acpi_device *device, int state); -typedef int (*acpi_op_scan) (struct acpi_device *device); -typedef int (*acpi_op_bind) (struct acpi_device *device); - -struct acpi_device_ops { - acpi_op_add add; - acpi_op_remove remove; - acpi_op_lock lock; - acpi_op_start start; - acpi_op_stop stop; - acpi_op_suspend suspend; - acpi_op_resume resume; - acpi_op_scan scan; - acpi_op_bind bind; -}; - -struct acpi_driver { - struct list_head node; - char name[80]; - char class[80]; - atomic_t references; - char *ids; /* Supported Hardware IDs */ - struct acpi_device_ops ops; -}; - -/* - * ACPI Device - * ----------- - */ - -/* Status (_STA) */ - -struct acpi_device_status { - u32 present:1; - u32 enabled:1; - u32 show_in_ui:1; - u32 functional:1; - u32 battery_present:1; - u32 reserved:27; -}; - - -/* Flags */ - -struct acpi_device_flags { - u32 dynamic_status:1; - u32 hardware_id:1; - u32 compatible_ids:1; - u32 bus_address:1; - u32 unique_id:1; - u32 removable:1; - u32 ejectable:1; - u32 lockable:1; - u32 suprise_removal_ok:1; - u32 power_manageable:1; - u32 performance_manageable:1; - u32 reserved:21; -}; - - -/* File System */ - -struct acpi_device_dir { - struct proc_dir_entry *entry; -}; - -#define acpi_device_dir(d) ((d)->dir.entry) - - -/* Plug and Play */ - -typedef char acpi_bus_id[5]; -typedef unsigned long acpi_bus_address; -typedef char acpi_hardware_id[9]; -typedef char acpi_unique_id[9]; -typedef char acpi_device_name[40]; -typedef char acpi_device_class[20]; - -struct acpi_device_pnp { - acpi_bus_id bus_id; /* Object name */ - acpi_bus_address bus_address; /* _ADR */ - acpi_hardware_id hardware_id; /* _HID */ - acpi_unique_id unique_id; /* _UID */ - acpi_device_name device_name; /* Driver-determined */ - acpi_device_class device_class; /* " */ -}; - -#define acpi_device_bid(d) ((d)->pnp.bus_id) -#define acpi_device_adr(d) ((d)->pnp.bus_address) -#define acpi_device_hid(d) ((d)->pnp.hardware_id) -#define acpi_device_uid(d) ((d)->pnp.unique_id) -#define acpi_device_name(d) ((d)->pnp.device_name) -#define acpi_device_class(d) ((d)->pnp.device_class) - - -/* Power Management */ - -struct acpi_device_power_flags { - u32 explicit_get:1; /* _PSC present? */ - u32 power_resources:1; /* Power resources */ - u32 inrush_current:1; /* Serialize Dx->D0 */ - u32 wake_capable:1; /* Wakeup supported? */ - u32 wake_enabled:1; /* Enabled for wakeup */ - u32 power_removed:1; /* Optimize Dx->D0 */ - u32 reserved:26; -}; - -struct acpi_device_power_state { - struct { - u8 valid:1; - u8 explicit_set:1; /* _PSx present? */ - u8 reserved:6; - } flags; - int power; /* % Power (compared to D0) */ - int latency; /* Dx->D0 time (microseconds) */ - struct acpi_handle_list resources; /* Power resources referenced */ -}; - -struct acpi_device_power { - int state; /* Current state */ - struct acpi_device_power_flags flags; - struct acpi_device_power_state states[4]; /* Power states (D0-D3) */ -}; - - -/* Performance Management */ - -struct acpi_device_perf_flags { - u8 reserved:8; -}; - -struct acpi_device_perf_state { - struct { - u8 valid:1; - u8 reserved:7; - } flags; - u8 power; /* % Power (compared to P0) */ - u8 performance; /* % Performance ( " ) */ - int latency; /* Px->P0 time (microseconds) */ -}; - -struct acpi_device_perf { - int state; - struct acpi_device_perf_flags flags; - int state_count; - struct acpi_device_perf_state *states; -}; - - -/* Device */ - -struct acpi_device { - acpi_handle handle; - struct acpi_device *parent; - struct list_head children; - struct list_head node; - struct list_head g_list; - struct acpi_device_status status; - struct acpi_device_flags flags; - struct acpi_device_pnp pnp; - struct acpi_device_power power; - struct acpi_device_perf performance; - struct acpi_device_dir dir; - struct acpi_device_ops ops; - struct acpi_driver *driver; - void *driver_data; - struct kobject kobj; -}; - -#define acpi_driver_data(d) ((d)->driver_data) - - -/* - * Events - * ------ - */ - -struct acpi_bus_event { - struct list_head node; - acpi_device_class device_class; - acpi_bus_id bus_id; - u32 type; - u32 data; -}; - -extern struct subsystem acpi_subsys; - -/* - * External Functions - */ - -int acpi_bus_get_device(acpi_handle, struct acpi_device **device); -int acpi_bus_get_status (struct acpi_device *device); -int acpi_bus_get_power (acpi_handle handle, int *state); -int acpi_bus_set_power (acpi_handle handle, int state); -int acpi_bus_generate_event (struct acpi_device *device, u8 type, int data); -int acpi_bus_receive_event (struct acpi_bus_event *event); -int acpi_bus_register_driver (struct acpi_driver *driver); -int acpi_bus_unregister_driver (struct acpi_driver *driver); - -int acpi_create_dir(struct acpi_device *); -void acpi_remove_dir(struct acpi_device *); - -#endif /*CONFIG_ACPI_BUS*/ - -#endif /*__ACPI_BUS_H__*/ diff -Nru a/drivers/acpi/acpi_drivers.h b/drivers/acpi/acpi_drivers.h --- a/drivers/acpi/acpi_drivers.h Sun Feb 9 21:13:34 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,163 +0,0 @@ -/* - * acpi_drivers.h ($Revision: 31 $) - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * 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. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -#ifndef __ACPI_DRIVERS_H__ -#define __ACPI_DRIVERS_H__ - -#include -#include "acpi_bus.h" - - -#define ACPI_MAX_STRING 80 - -#define ACPI_BUS_COMPONENT 0x00010000 -#define ACPI_SYSTEM_COMPONENT 0x02000000 - -/* _HID definitions */ - -#define ACPI_POWER_HID "ACPI_PWR" -#define ACPI_PROCESSOR_HID "ACPI_CPU" -#define ACPI_SYSTEM_HID "ACPI_SYS" -#define ACPI_THERMAL_HID "ACPI_THM" -#define ACPI_BUTTON_HID_POWERF "ACPI_FPB" -#define ACPI_BUTTON_HID_SLEEPF "ACPI_FSB" - - -/* -------------------------------------------------------------------------- - PCI - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI_PCI - -#define ACPI_PCI_COMPONENT 0x00400000 - -/* ACPI PCI Root Bridge (pci_root.c) */ - -void acpi_pci_get_translations (struct acpi_pci_id* id, u64* mem_tra, u64* io_tra); - -/* ACPI PCI Interrupt Link (pci_link.c) */ - -int acpi_pci_link_check (void); -int acpi_pci_link_get_irq (acpi_handle handle, int index); - -/* ACPI PCI Interrupt Routing (pci_irq.c) */ - -int acpi_pci_irq_add_prt (acpi_handle handle, int segment, int bus); - -/* ACPI PCI Device Binding (pci_bind.c) */ - -struct pci_bus; - -int acpi_pci_bind (struct acpi_device *device); -int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus); - -#endif /*CONFIG_ACPI_PCI*/ - - -/* -------------------------------------------------------------------------- - Power Resource - -------------------------------------------------------------------------- */ - -#ifdef CONFIG_ACPI_POWER - -int acpi_power_get_inferred_state (struct acpi_device *device); -int acpi_power_transition (struct acpi_device *device, int state); -#endif - - -/* -------------------------------------------------------------------------- - Embedded Controller - -------------------------------------------------------------------------- */ -#ifdef CONFIG_ACPI_EC -int acpi_ec_ecdt_probe (void); -#endif - -/* -------------------------------------------------------------------------- - Processor - -------------------------------------------------------------------------- */ - -#define ACPI_PROCESSOR_LIMIT_NONE 0x00 -#define ACPI_PROCESSOR_LIMIT_INCREMENT 0x01 -#define ACPI_PROCESSOR_LIMIT_DECREMENT 0x02 - -int acpi_processor_set_thermal_limit(acpi_handle handle, int type); - - -/* -------------------------------------------------------------------------- - Debug Support - -------------------------------------------------------------------------- */ - -#define ACPI_DEBUG_RESTORE 0 -#define ACPI_DEBUG_LOW 1 -#define ACPI_DEBUG_MEDIUM 2 -#define ACPI_DEBUG_HIGH 3 -#define ACPI_DEBUG_DRIVERS 4 - -extern u32 acpi_dbg_level; -extern u32 acpi_dbg_layer; - -static inline void -acpi_set_debug ( - u32 flag) -{ - static u32 layer_save; - static u32 level_save; - - switch (flag) { - case ACPI_DEBUG_RESTORE: - acpi_dbg_layer = layer_save; - acpi_dbg_level = level_save; - break; - case ACPI_DEBUG_LOW: - case ACPI_DEBUG_MEDIUM: - case ACPI_DEBUG_HIGH: - case ACPI_DEBUG_DRIVERS: - layer_save = acpi_dbg_layer; - level_save = acpi_dbg_level; - break; - } - - switch (flag) { - case ACPI_DEBUG_LOW: - acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS; - acpi_dbg_level = ACPI_DEBUG_DEFAULT; - break; - case ACPI_DEBUG_MEDIUM: - acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS; - acpi_dbg_level = ACPI_LV_FUNCTIONS | ACPI_LV_ALL_EXCEPTIONS; - break; - case ACPI_DEBUG_HIGH: - acpi_dbg_layer = 0xFFFFFFFF; - acpi_dbg_level = 0xFFFFFFFF; - break; - case ACPI_DEBUG_DRIVERS: - acpi_dbg_layer = ACPI_ALL_DRIVERS; - acpi_dbg_level = 0xFFFFFFFF; - break; - } -} - - -#endif /*__ACPI_DRIVERS_H__*/ diff -Nru a/drivers/acpi/acpi_ksyms.c b/drivers/acpi/acpi_ksyms.c --- a/drivers/acpi/acpi_ksyms.c Sun Feb 9 21:13:30 2003 +++ b/drivers/acpi/acpi_ksyms.c Sun Feb 9 21:13:30 2003 @@ -25,7 +25,7 @@ #include #include -#include "include/acpi.h" +#include #include "acpi_bus.h" diff -Nru a/drivers/acpi/battery.c b/drivers/acpi/battery.c --- a/drivers/acpi/battery.c Sun Feb 9 21:13:34 2003 +++ b/drivers/acpi/battery.c Sun Feb 9 21:13:34 2003 @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "acpi_bus.h" #include "acpi_drivers.h" diff -Nru a/drivers/acpi/button.c b/drivers/acpi/button.c --- a/drivers/acpi/button.c Sun Feb 9 21:13:28 2003 +++ b/drivers/acpi/button.c Sun Feb 9 21:13:28 2003 @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include "acpi_bus.h" diff -Nru a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c --- a/drivers/acpi/dispatcher/dsinit.c Sun Feb 9 21:13:36 2003 +++ b/drivers/acpi/dispatcher/dsinit.c Sun Feb 9 21:13:36 2003 @@ -24,11 +24,8 @@ #include "acpi.h" -#include "acparser.h" -#include "amlcode.h" #include "acdispat.h" #include "acnamesp.h" -#include "acinterp.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME ("dsinit") diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c --- a/drivers/acpi/ec.c Sun Feb 9 21:13:32 2003 +++ b/drivers/acpi/ec.c Sun Feb 9 21:13:32 2003 @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include "acpi_bus.h" diff -Nru a/drivers/acpi/fan.c b/drivers/acpi/fan.c --- a/drivers/acpi/fan.c Sun Feb 9 21:13:28 2003 +++ b/drivers/acpi/fan.c Sun Feb 9 21:13:28 2003 @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "acpi_bus.h" #include "acpi_drivers.h" diff -Nru a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c --- a/drivers/acpi/hardware/hwtimer.c Sun Feb 9 21:13:29 2003 +++ b/drivers/acpi/hardware/hwtimer.c Sun Feb 9 21:13:29 2003 @@ -117,7 +117,10 @@ * Note that this function accomodates only a single timer * rollover. Thus for 24-bit timers, this function should only * be used for calculating durations less than ~4.6 seconds - * (~20 hours for 32-bit timers). + * (~20 minutes for 32-bit timers) -- calculations below + * + * 2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec + * 2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes * ******************************************************************************/ diff -Nru a/drivers/acpi/include/acconfig.h b/drivers/acpi/include/acconfig.h --- a/drivers/acpi/include/acconfig.h Sun Feb 9 21:13:34 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,188 +0,0 @@ -/****************************************************************************** - * - * Name: acconfig.h - Global configuration constants - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef _ACCONFIG_H -#define _ACCONFIG_H - - -/****************************************************************************** - * - * Compile-time options - * - *****************************************************************************/ - -/* - * ACPI_DEBUG_OUTPUT - This switch enables all the debug facilities of the - * ACPI subsystem. This includes the DEBUG_PRINT output - * statements. When disabled, all DEBUG_PRINT - * statements are compiled out. - * - * ACPI_APPLICATION - Use this switch if the subsystem is going to be run - * at the application level. - * - */ - - -/****************************************************************************** - * - * Subsystem Constants - * - *****************************************************************************/ - - -/* Version string */ - -#define ACPI_CA_VERSION 0x20030109 - -/* Version of ACPI supported */ - -#define ACPI_CA_SUPPORT_LEVEL 2 - -/* Maximum objects in the various object caches */ - -#define ACPI_MAX_STATE_CACHE_DEPTH 64 /* State objects for stacks */ -#define ACPI_MAX_PARSE_CACHE_DEPTH 96 /* Parse tree objects */ -#define ACPI_MAX_EXTPARSE_CACHE_DEPTH 64 /* Parse tree objects */ -#define ACPI_MAX_OBJECT_CACHE_DEPTH 64 /* Interpreter operand objects */ -#define ACPI_MAX_WALK_CACHE_DEPTH 4 /* Objects for parse tree walks */ - -/* String size constants */ - -#define ACPI_MAX_STRING_LENGTH 512 -#define ACPI_PATHNAME_MAX 256 /* A full namespace pathname */ - -/* Maximum count for a semaphore object */ - -#define ACPI_MAX_SEMAPHORE_COUNT 256 - -/* Max reference count (for debug only) */ - -#define ACPI_MAX_REFERENCE_COUNT 0x400 - -/* Size of cached memory mapping for system memory operation region */ - -#define ACPI_SYSMEM_REGION_WINDOW_SIZE 4096 - - -/****************************************************************************** - * - * Configuration of subsystem behavior - * - *****************************************************************************/ - - -/* - * Should the subystem abort the loading of an ACPI table if the - * table checksum is incorrect? - */ -#define ACPI_CHECKSUM_ABORT FALSE - - -/****************************************************************************** - * - * ACPI Specification constants (Do not change unless the specification changes) - * - *****************************************************************************/ - -/* Number of distinct GPE register blocks and register width */ - -#define ACPI_MAX_GPE_BLOCKS 2 -#define ACPI_GPE_REGISTER_WIDTH 8 - -/* - * Method info (in WALK_STATE), containing local variables and argumetns - */ -#define ACPI_METHOD_NUM_LOCALS 8 -#define ACPI_METHOD_MAX_LOCAL 7 - -#define ACPI_METHOD_NUM_ARGS 7 -#define ACPI_METHOD_MAX_ARG 6 - -/* Maximum length of resulting string when converting from a buffer */ - -#define ACPI_MAX_STRING_CONVERSION 200 - -/* - * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG - */ -#define ACPI_OBJ_NUM_OPERANDS 8 -#define ACPI_OBJ_MAX_OPERAND 7 - -/* Names within the namespace are 4 bytes long */ - -#define ACPI_NAME_SIZE 4 -#define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */ -#define ACPI_PATH_SEPARATOR '.' - -/* Constants used in searching for the RSDP in low memory */ - -#define ACPI_LO_RSDP_WINDOW_BASE 0 /* Physical Address */ -#define ACPI_HI_RSDP_WINDOW_BASE 0xE0000 /* Physical Address */ -#define ACPI_LO_RSDP_WINDOW_SIZE 0x400 -#define ACPI_HI_RSDP_WINDOW_SIZE 0x20000 -#define ACPI_RSDP_SCAN_STEP 16 - -/* Operation regions */ - -#define ACPI_NUM_PREDEFINED_REGIONS 8 -#define ACPI_USER_REGION_BEGIN 0x80 - -/* Maximum space_ids for Operation Regions */ - -#define ACPI_MAX_ADDRESS_SPACE 255 - -/* Array sizes. Used for range checking also */ - -#define ACPI_NUM_ACCESS_TYPES 6 -#define ACPI_NUM_UPDATE_RULES 3 -#define ACPI_NUM_LOCK_RULES 2 -#define ACPI_NUM_MATCH_OPS 6 -#define ACPI_NUM_OPCODES 256 -#define ACPI_NUM_FIELD_NAMES 2 - -/* RSDP checksums */ - -#define ACPI_RSDP_CHECKSUM_LENGTH 20 -#define ACPI_RSDP_XCHECKSUM_LENGTH 36 - -/* SMBus bidirectional buffer size */ - -#define ACPI_SMBUS_BUFFER_SIZE 34 - - -/****************************************************************************** - * - * ACPI AML Debugger - * - *****************************************************************************/ - - -#define ACPI_DEBUGGER_MAX_ARGS 8 /* Must be max method args + 1 */ - -#define ACPI_DEBUGGER_COMMAND_PROMPT '-' -#define ACPI_DEBUGGER_EXECUTE_PROMPT '%' - - -#endif /* _ACCONFIG_H */ - diff -Nru a/drivers/acpi/include/acdebug.h b/drivers/acpi/include/acdebug.h --- a/drivers/acpi/include/acdebug.h Sun Feb 9 21:13:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,430 +0,0 @@ -/****************************************************************************** - * - * Name: acdebug.h - ACPI/AML debugger - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACDEBUG_H__ -#define __ACDEBUG_H__ - - -#define ACPI_DEBUG_BUFFER_SIZE 4196 - -struct command_info -{ - char *name; /* Command Name */ - u8 min_args; /* Minimum arguments required */ -}; - - -struct argument_info -{ - char *name; /* Argument Name */ -}; - - -#define PARAM_LIST(pl) pl - -#define DBTEST_OUTPUT_LEVEL(lvl) if (acpi_gbl_db_opt_verbose) - -#define VERBOSE_PRINT(fp) DBTEST_OUTPUT_LEVEL(lvl) {\ - acpi_os_printf PARAM_LIST(fp);} - -#define EX_NO_SINGLE_STEP 1 -#define EX_SINGLE_STEP 2 - - -/* Prototypes */ - - -/* - * dbapi - external debugger interfaces - */ - -acpi_status -acpi_db_initialize ( - void); - -void -acpi_db_terminate ( - void); - -acpi_status -acpi_db_single_step ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op, - u32 op_type); - - -/* - * dbcmds - debug commands and output routines - */ - -void -acpi_db_display_table_info ( - char *table_arg); - -void -acpi_db_unload_acpi_table ( - char *table_arg, - char *instance_arg); - -void -acpi_db_set_method_breakpoint ( - char *location, - struct acpi_walk_state *walk_state, - union acpi_parse_object *op); - -void -acpi_db_set_method_call_breakpoint ( - union acpi_parse_object *op); - -void -acpi_db_disassemble_aml ( - char *statements, - union acpi_parse_object *op); - -void -acpi_db_dump_namespace ( - char *start_arg, - char *depth_arg); - -void -acpi_db_dump_namespace_by_owner ( - char *owner_arg, - char *depth_arg); - -void -acpi_db_send_notify ( - char *name, - u32 value); - -void -acpi_db_set_method_data ( - char *type_arg, - char *index_arg, - char *value_arg); - -acpi_status -acpi_db_display_objects ( - char *obj_type_arg, - char *display_count_arg); - -acpi_status -acpi_db_find_name_in_namespace ( - char *name_arg); - -void -acpi_db_set_scope ( - char *name); - -void -acpi_db_find_references ( - char *object_arg); - -void -acpi_db_display_locks (void); - - -void -acpi_db_display_resources ( - char *object_arg); - -void -acpi_db_check_integrity ( - void); - -acpi_status -acpi_db_integrity_walk ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value); - -acpi_status -acpi_db_walk_and_match_name ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value); - -acpi_status -acpi_db_walk_for_references ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value); - -acpi_status -acpi_db_walk_for_specific_objects ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value); - - -/* - * dbdisply - debug display commands - */ - -void -acpi_db_display_method_info ( - union acpi_parse_object *op); - -void -acpi_db_decode_and_display_object ( - char *target, - char *output_type); - -void -acpi_db_decode_node ( - struct acpi_namespace_node *node); - -void -acpi_db_display_result_object ( - union acpi_operand_object *obj_desc, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_db_display_all_methods ( - char *display_count_arg); - -void -acpi_db_display_internal_object ( - union acpi_operand_object *obj_desc, - struct acpi_walk_state *walk_state); - -void -acpi_db_display_arguments ( - void); - -void -acpi_db_display_locals ( - void); - -void -acpi_db_display_results ( - void); - -void -acpi_db_display_calling_tree ( - void); - -void -acpi_db_display_argument_object ( - union acpi_operand_object *obj_desc, - struct acpi_walk_state *walk_state); - -void -acpi_db_dump_parser_descriptor ( - union acpi_parse_object *op); - -void * -acpi_db_get_pointer ( - void *target); - -void -acpi_db_decode_internal_object ( - union acpi_operand_object *obj_desc); - - -/* - * dbexec - debugger control method execution - */ - -void -acpi_db_execute ( - char *name, - char **args, - u32 flags); - -void -acpi_db_create_execution_threads ( - char *num_threads_arg, - char *num_loops_arg, - char *method_name_arg); - -acpi_status -acpi_db_execute_method ( - struct acpi_db_method_info *info, - struct acpi_buffer *return_obj); - -void -acpi_db_execute_setup ( - struct acpi_db_method_info *info); - -u32 -acpi_db_get_outstanding_allocations ( - void); - -void ACPI_SYSTEM_XFACE -acpi_db_method_thread ( - void *context); - - -/* - * dbfileio - Debugger file I/O commands - */ - -acpi_object_type -acpi_db_match_argument ( - char *user_argument, - struct argument_info *arguments); - -acpi_status -ae_local_load_table ( - struct acpi_table_header *table_ptr); - -void -acpi_db_close_debug_file ( - void); - -void -acpi_db_open_debug_file ( - char *name); - -acpi_status -acpi_db_load_acpi_table ( - char *filename); - -acpi_status -acpi_db_get_acpi_table ( - char *filename); - -/* - * dbhistry - debugger HISTORY command - */ - -void -acpi_db_add_to_history ( - char *command_line); - -void -acpi_db_display_history (void); - -char * -acpi_db_get_from_history ( - char *command_num_arg); - - -/* - * dbinput - user front-end to the AML debugger - */ - -acpi_status -acpi_db_command_dispatch ( - char *input_buffer, - struct acpi_walk_state *walk_state, - union acpi_parse_object *op); - -void ACPI_SYSTEM_XFACE -acpi_db_execute_thread ( - void *context); - -acpi_status -acpi_db_user_commands ( - char prompt, - union acpi_parse_object *op); - -void -acpi_db_display_help ( - char *help_type); - -char * -acpi_db_get_next_token ( - char *string, - char **next); - -u32 -acpi_db_get_line ( - char *input_buffer); - -u32 -acpi_db_match_command ( - char *user_command); - -void -acpi_db_single_thread ( - void); - - -/* - * dbstats - Generation and display of ACPI table statistics - */ - -void -acpi_db_generate_statistics ( - union acpi_parse_object *root, - u8 is_method); - - -acpi_status -acpi_db_display_statistics ( - char *type_arg); - -acpi_status -acpi_db_classify_one_object ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value); - -void -acpi_db_count_namespace_objects ( - void); - -void -acpi_db_enumerate_object ( - union acpi_operand_object *obj_desc); - - -/* - * dbutils - AML debugger utilities - */ - -void -acpi_db_set_output_destination ( - u32 where); - -void -acpi_db_dump_buffer ( - u32 address); - -void -acpi_db_dump_object ( - union acpi_object *obj_desc, - u32 level); - -void -acpi_db_prep_namestring ( - char *name); - - -acpi_status -acpi_db_second_pass_parse ( - union acpi_parse_object *root); - -struct acpi_namespace_node * -acpi_db_local_ns_lookup ( - char *name); - - -#endif /* __ACDEBUG_H__ */ diff -Nru a/drivers/acpi/include/acdispat.h b/drivers/acpi/include/acdispat.h --- a/drivers/acpi/include/acdispat.h Sun Feb 9 21:13:34 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,494 +0,0 @@ -/****************************************************************************** - * - * Name: acdispat.h - dispatcher (parser to interpreter interface) - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - - -#ifndef _ACDISPAT_H_ -#define _ACDISPAT_H_ - - -#define NAMEOF_LOCAL_NTE "__L0" -#define NAMEOF_ARG_NTE "__A0" - - -/* Common interfaces */ - -acpi_status -acpi_ds_obj_stack_push ( - void *object, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_obj_stack_pop ( - u32 pop_count, - struct acpi_walk_state *walk_state); - -void * -acpi_ds_obj_stack_get_value ( - u32 index, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_obj_stack_pop_object ( - union acpi_operand_object **object, - struct acpi_walk_state *walk_state); - - -/* dsopcode - support for late evaluation */ - -acpi_status -acpi_ds_execute_arguments ( - struct acpi_namespace_node *node, - struct acpi_namespace_node *scope_node, - u32 aml_length, - u8 *aml_start); - -acpi_status -acpi_ds_get_buffer_field_arguments ( - union acpi_operand_object *obj_desc); - -acpi_status -acpi_ds_get_region_arguments ( - union acpi_operand_object *rgn_desc); - -acpi_status -acpi_ds_get_buffer_arguments ( - union acpi_operand_object *obj_desc); - -acpi_status -acpi_ds_get_package_arguments ( - union acpi_operand_object *obj_desc); - -acpi_status -acpi_ds_init_buffer_field ( - u16 aml_opcode, - union acpi_operand_object *obj_desc, - union acpi_operand_object *buffer_desc, - union acpi_operand_object *offset_desc, - union acpi_operand_object *length_desc, - union acpi_operand_object *result_desc); - -acpi_status -acpi_ds_eval_buffer_field_operands ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op); - -acpi_status -acpi_ds_eval_region_operands ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op); - -acpi_status -acpi_ds_eval_data_object_operands ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op, - union acpi_operand_object *obj_desc); - -acpi_status -acpi_ds_initialize_region ( - acpi_handle obj_handle); - - -/* dsctrl - Parser/Interpreter interface, control stack routines */ - - -acpi_status -acpi_ds_exec_begin_control_op ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op); - -acpi_status -acpi_ds_exec_end_control_op ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op); - - -/* dsexec - Parser/Interpreter interface, method execution callbacks */ - - -acpi_status -acpi_ds_get_predicate_value ( - struct acpi_walk_state *walk_state, - union acpi_operand_object *result_obj); - -acpi_status -acpi_ds_exec_begin_op ( - struct acpi_walk_state *walk_state, - union acpi_parse_object **out_op); - -acpi_status -acpi_ds_exec_end_op ( - struct acpi_walk_state *state); - - -/* dsfield - Parser/Interpreter interface for AML fields */ - -acpi_status -acpi_ds_get_field_names ( - struct acpi_create_field_info *info, - struct acpi_walk_state *walk_state, - union acpi_parse_object *arg); - -acpi_status -acpi_ds_create_field ( - union acpi_parse_object *op, - struct acpi_namespace_node *region_node, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_create_bank_field ( - union acpi_parse_object *op, - struct acpi_namespace_node *region_node, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_create_index_field ( - union acpi_parse_object *op, - struct acpi_namespace_node *region_node, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_create_buffer_field ( - union acpi_parse_object *op, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_init_field_objects ( - union acpi_parse_object *op, - struct acpi_walk_state *walk_state); - - -/* dsload - Parser/Interpreter interface, namespace load callbacks */ - -acpi_status -acpi_ds_load1_begin_op ( - struct acpi_walk_state *walk_state, - union acpi_parse_object **out_op); - -acpi_status -acpi_ds_load1_end_op ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_load2_begin_op ( - struct acpi_walk_state *walk_state, - union acpi_parse_object **out_op); - -acpi_status -acpi_ds_load2_end_op ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_init_callbacks ( - struct acpi_walk_state *walk_state, - u32 pass_number); - - -/* dsmthdat - method data (locals/args) */ - - -acpi_status -acpi_ds_store_object_to_local ( - u16 opcode, - u32 index, - union acpi_operand_object *src_desc, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_method_data_get_entry ( - u16 opcode, - u32 index, - struct acpi_walk_state *walk_state, - union acpi_operand_object ***node); - -void -acpi_ds_method_data_delete_all ( - struct acpi_walk_state *walk_state); - -u8 -acpi_ds_is_method_value ( - union acpi_operand_object *obj_desc); - -acpi_object_type -acpi_ds_method_data_get_type ( - u16 opcode, - u32 index, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_method_data_get_value ( - u16 opcode, - u32 index, - struct acpi_walk_state *walk_state, - union acpi_operand_object **dest_desc); - -void -acpi_ds_method_data_delete_value ( - u16 opcode, - u32 index, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_method_data_init_args ( - union acpi_operand_object **params, - u32 max_param_count, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_method_data_get_node ( - u16 opcode, - u32 index, - struct acpi_walk_state *walk_state, - struct acpi_namespace_node **node); - -void -acpi_ds_method_data_init ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_method_data_set_value ( - u16 opcode, - u32 index, - union acpi_operand_object *object, - struct acpi_walk_state *walk_state); - - -/* dsmethod - Parser/Interpreter interface - control method parsing */ - -acpi_status -acpi_ds_parse_method ( - acpi_handle obj_handle); - -acpi_status -acpi_ds_call_control_method ( - struct acpi_thread_state *thread, - struct acpi_walk_state *walk_state, - union acpi_parse_object *op); - -acpi_status -acpi_ds_restart_control_method ( - struct acpi_walk_state *walk_state, - union acpi_operand_object *return_desc); - -acpi_status -acpi_ds_terminate_control_method ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_begin_method_execution ( - struct acpi_namespace_node *method_node, - union acpi_operand_object *obj_desc, - struct acpi_namespace_node *calling_method_node); - - -/* dsobj - Parser/Interpreter interface - object initialization and conversion */ - -acpi_status -acpi_ds_init_one_object ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value); - -acpi_status -acpi_ds_initialize_objects ( - struct acpi_table_desc *table_desc, - struct acpi_namespace_node *start_node); - -acpi_status -acpi_ds_build_internal_buffer_obj ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op, - u32 buffer_length, - union acpi_operand_object **obj_desc_ptr); - -acpi_status -acpi_ds_build_internal_package_obj ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op, - u32 package_length, - union acpi_operand_object **obj_desc); - -acpi_status -acpi_ds_build_internal_object ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op, - union acpi_operand_object **obj_desc_ptr); - -acpi_status -acpi_ds_init_object_from_op ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op, - u16 opcode, - union acpi_operand_object **obj_desc); - -acpi_status -acpi_ds_create_node ( - struct acpi_walk_state *walk_state, - struct acpi_namespace_node *node, - union acpi_parse_object *op); - - -/* dsutils - Parser/Interpreter interface utility routines */ - -u8 -acpi_ds_is_result_used ( - union acpi_parse_object *op, - struct acpi_walk_state *walk_state); - -void -acpi_ds_delete_result_if_not_used ( - union acpi_parse_object *op, - union acpi_operand_object *result_obj, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_create_operand ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *arg, - u32 args_remaining); - -acpi_status -acpi_ds_create_operands ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *first_arg); - -acpi_status -acpi_ds_resolve_operands ( - struct acpi_walk_state *walk_state); - -void -acpi_ds_clear_operands ( - struct acpi_walk_state *walk_state); - - -/* - * dswscope - Scope Stack manipulation - */ - -acpi_status -acpi_ds_scope_stack_push ( - struct acpi_namespace_node *node, - acpi_object_type type, - struct acpi_walk_state *walk_state); - - -acpi_status -acpi_ds_scope_stack_pop ( - struct acpi_walk_state *walk_state); - -void -acpi_ds_scope_stack_clear ( - struct acpi_walk_state *walk_state); - - -/* dswstate - parser WALK_STATE management routines */ - -struct acpi_walk_state * -acpi_ds_create_walk_state ( - acpi_owner_id owner_id, - union acpi_parse_object *origin, - union acpi_operand_object *mth_desc, - struct acpi_thread_state *thread); - -acpi_status -acpi_ds_init_aml_walk ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op, - struct acpi_namespace_node *method_node, - u8 *aml_start, - u32 aml_length, - union acpi_operand_object **params, - union acpi_operand_object **return_obj_desc, - u32 pass_number); - -acpi_status -acpi_ds_obj_stack_delete_all ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_obj_stack_pop_and_delete ( - u32 pop_count, - struct acpi_walk_state *walk_state); - -void -acpi_ds_delete_walk_state ( - struct acpi_walk_state *walk_state); - -struct acpi_walk_state * -acpi_ds_pop_walk_state ( - struct acpi_thread_state *thread); - -void -acpi_ds_push_walk_state ( - struct acpi_walk_state *walk_state, - struct acpi_thread_state *thread); - -acpi_status -acpi_ds_result_stack_pop ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_stack_push ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_stack_clear ( - struct acpi_walk_state *walk_state); - -struct acpi_walk_state * -acpi_ds_get_current_walk_state ( - struct acpi_thread_state *thread); - -void -acpi_ds_delete_walk_state_cache ( - void); - -acpi_status -acpi_ds_result_insert ( - void *object, - u32 index, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_remove ( - union acpi_operand_object **object, - u32 index, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_pop ( - union acpi_operand_object **object, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_push ( - union acpi_operand_object *object, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ds_result_pop_from_bottom ( - union acpi_operand_object **object, - struct acpi_walk_state *walk_state); - -#endif /* _ACDISPAT_H_ */ diff -Nru a/drivers/acpi/include/acevents.h b/drivers/acpi/include/acevents.h --- a/drivers/acpi/include/acevents.h Sun Feb 9 21:13:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,221 +0,0 @@ -/****************************************************************************** - * - * Name: acevents.h - Event subcomponent prototypes and defines - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACEVENTS_H__ -#define __ACEVENTS_H__ - - -acpi_status -acpi_ev_initialize ( - void); - -acpi_status -acpi_ev_handler_initialize ( - void); - - -/* - * Evfixed - Fixed event handling - */ - -acpi_status -acpi_ev_fixed_event_initialize ( - void); - -u32 -acpi_ev_fixed_event_detect ( - void); - -u32 -acpi_ev_fixed_event_dispatch ( - u32 event); - - -/* - * Evmisc - */ - -u8 -acpi_ev_is_notify_object ( - struct acpi_namespace_node *node); - -acpi_status -acpi_ev_acquire_global_lock( - u16 timeout); - -acpi_status -acpi_ev_release_global_lock( - void); - -acpi_status -acpi_ev_init_global_lock_handler ( - void); - -u32 -acpi_ev_get_gpe_register_index ( - u32 gpe_number); - -u32 -acpi_ev_get_gpe_number_index ( - u32 gpe_number); - -acpi_status -acpi_ev_queue_notify_request ( - struct acpi_namespace_node *node, - u32 notify_value); - -void ACPI_SYSTEM_XFACE -acpi_ev_notify_dispatch ( - void *context); - - -/* - * Evgpe - GPE handling and dispatch - */ - -acpi_status -acpi_ev_gpe_initialize ( - void); - -acpi_status -acpi_ev_init_gpe_control_methods ( - void); - -u32 -acpi_ev_gpe_dispatch ( - u32 gpe_number); - -u32 -acpi_ev_gpe_detect ( - void); - -/* - * Evregion - Address Space handling - */ - -acpi_status -acpi_ev_init_address_spaces ( - void); - -acpi_status -acpi_ev_address_space_dispatch ( - union acpi_operand_object *region_obj, - u32 function, - acpi_physical_address address, - u32 bit_width, - void *value); - -acpi_status -acpi_ev_addr_handler_helper ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value); - -acpi_status -acpi_ev_attach_region ( - union acpi_operand_object *handler_obj, - union acpi_operand_object *region_obj, - u8 acpi_ns_is_locked); - -void -acpi_ev_detach_region ( - union acpi_operand_object *region_obj, - u8 acpi_ns_is_locked); - - -/* - * Evregini - Region initialization and setup - */ - -acpi_status -acpi_ev_system_memory_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_io_space_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_pci_config_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_cmos_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_pci_bar_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_default_region_setup ( - acpi_handle handle, - u32 function, - void *handler_context, - void **region_context); - -acpi_status -acpi_ev_initialize_region ( - union acpi_operand_object *region_obj, - u8 acpi_ns_locked); - - -/* - * Evsci - SCI (System Control Interrupt) handling/dispatch - */ - -u32 -acpi_ev_install_sci_handler ( - void); - -acpi_status -acpi_ev_remove_sci_handler ( - void); - -u32 -acpi_ev_initialize_sCI ( - u32 program_sCI); - -void -acpi_ev_terminate ( - void); - - -#endif /* __ACEVENTS_H__ */ diff -Nru a/drivers/acpi/include/acexcep.h b/drivers/acpi/include/acexcep.h --- a/drivers/acpi/include/acexcep.h Sun Feb 9 21:13:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,283 +0,0 @@ -/****************************************************************************** - * - * Name: acexcep.h - Exception codes returned by the ACPI subsystem - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACEXCEP_H__ -#define __ACEXCEP_H__ - - -/* - * Exceptions returned by external ACPI interfaces - */ - -#define AE_CODE_ENVIRONMENTAL 0x0000 -#define AE_CODE_PROGRAMMER 0x1000 -#define AE_CODE_ACPI_TABLES 0x2000 -#define AE_CODE_AML 0x3000 -#define AE_CODE_CONTROL 0x4000 -#define AE_CODE_MASK 0xF000 - - -#define ACPI_SUCCESS(a) (!(a)) -#define ACPI_FAILURE(a) (a) - - -#define AE_OK (acpi_status) 0x0000 - -/* - * Environmental exceptions - */ -#define AE_ERROR (acpi_status) (0x0001 | AE_CODE_ENVIRONMENTAL) -#define AE_NO_ACPI_TABLES (acpi_status) (0x0002 | AE_CODE_ENVIRONMENTAL) -#define AE_NO_NAMESPACE (acpi_status) (0x0003 | AE_CODE_ENVIRONMENTAL) -#define AE_NO_MEMORY (acpi_status) (0x0004 | AE_CODE_ENVIRONMENTAL) -#define AE_NOT_FOUND (acpi_status) (0x0005 | AE_CODE_ENVIRONMENTAL) -#define AE_NOT_EXIST (acpi_status) (0x0006 | AE_CODE_ENVIRONMENTAL) -#define AE_ALREADY_EXISTS (acpi_status) (0x0007 | AE_CODE_ENVIRONMENTAL) -#define AE_TYPE (acpi_status) (0x0008 | AE_CODE_ENVIRONMENTAL) -#define AE_NULL_OBJECT (acpi_status) (0x0009 | AE_CODE_ENVIRONMENTAL) -#define AE_NULL_ENTRY (acpi_status) (0x000A | AE_CODE_ENVIRONMENTAL) -#define AE_BUFFER_OVERFLOW (acpi_status) (0x000B | AE_CODE_ENVIRONMENTAL) -#define AE_STACK_OVERFLOW (acpi_status) (0x000C | AE_CODE_ENVIRONMENTAL) -#define AE_STACK_UNDERFLOW (acpi_status) (0x000D | AE_CODE_ENVIRONMENTAL) -#define AE_NOT_IMPLEMENTED (acpi_status) (0x000E | AE_CODE_ENVIRONMENTAL) -#define AE_VERSION_MISMATCH (acpi_status) (0x000F | AE_CODE_ENVIRONMENTAL) -#define AE_SUPPORT (acpi_status) (0x0010 | AE_CODE_ENVIRONMENTAL) -#define AE_SHARE (acpi_status) (0x0011 | AE_CODE_ENVIRONMENTAL) -#define AE_LIMIT (acpi_status) (0x0012 | AE_CODE_ENVIRONMENTAL) -#define AE_TIME (acpi_status) (0x0013 | AE_CODE_ENVIRONMENTAL) -#define AE_UNKNOWN_STATUS (acpi_status) (0x0014 | AE_CODE_ENVIRONMENTAL) -#define AE_ACQUIRE_DEADLOCK (acpi_status) (0x0015 | AE_CODE_ENVIRONMENTAL) -#define AE_RELEASE_DEADLOCK (acpi_status) (0x0016 | AE_CODE_ENVIRONMENTAL) -#define AE_NOT_ACQUIRED (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL) -#define AE_ALREADY_ACQUIRED (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL) -#define AE_NO_HARDWARE_RESPONSE (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL) -#define AE_NO_GLOBAL_LOCK (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL) -#define AE_LOGICAL_ADDRESS (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL) -#define AE_ABORT_METHOD (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL) - -#define AE_CODE_ENV_MAX 0x001C - -/* - * Programmer exceptions - */ -#define AE_BAD_PARAMETER (acpi_status) (0x0001 | AE_CODE_PROGRAMMER) -#define AE_BAD_CHARACTER (acpi_status) (0x0002 | AE_CODE_PROGRAMMER) -#define AE_BAD_PATHNAME (acpi_status) (0x0003 | AE_CODE_PROGRAMMER) -#define AE_BAD_DATA (acpi_status) (0x0004 | AE_CODE_PROGRAMMER) -#define AE_BAD_ADDRESS (acpi_status) (0x0005 | AE_CODE_PROGRAMMER) -#define AE_ALIGNMENT (acpi_status) (0x0006 | AE_CODE_PROGRAMMER) -#define AE_BAD_HEX_CONSTANT (acpi_status) (0x0007 | AE_CODE_PROGRAMMER) -#define AE_BAD_OCTAL_CONSTANT (acpi_status) (0x0008 | AE_CODE_PROGRAMMER) -#define AE_BAD_DECIMAL_CONSTANT (acpi_status) (0x0009 | AE_CODE_PROGRAMMER) - -#define AE_CODE_PGM_MAX 0x0009 - - -/* - * Acpi table exceptions - */ -#define AE_BAD_SIGNATURE (acpi_status) (0x0001 | AE_CODE_ACPI_TABLES) -#define AE_BAD_HEADER (acpi_status) (0x0002 | AE_CODE_ACPI_TABLES) -#define AE_BAD_CHECKSUM (acpi_status) (0x0003 | AE_CODE_ACPI_TABLES) -#define AE_BAD_VALUE (acpi_status) (0x0004 | AE_CODE_ACPI_TABLES) -#define AE_TABLE_NOT_SUPPORTED (acpi_status) (0x0005 | AE_CODE_ACPI_TABLES) -#define AE_INVALID_TABLE_LENGTH (acpi_status) (0x0006 | AE_CODE_ACPI_TABLES) - -#define AE_CODE_TBL_MAX 0x0006 - - -/* - * AML exceptions. These are caused by problems with - * the actual AML byte stream - */ -#define AE_AML_ERROR (acpi_status) (0x0001 | AE_CODE_AML) -#define AE_AML_PARSE (acpi_status) (0x0002 | AE_CODE_AML) -#define AE_AML_BAD_OPCODE (acpi_status) (0x0003 | AE_CODE_AML) -#define AE_AML_NO_OPERAND (acpi_status) (0x0004 | AE_CODE_AML) -#define AE_AML_OPERAND_TYPE (acpi_status) (0x0005 | AE_CODE_AML) -#define AE_AML_OPERAND_VALUE (acpi_status) (0x0006 | AE_CODE_AML) -#define AE_AML_UNINITIALIZED_LOCAL (acpi_status) (0x0007 | AE_CODE_AML) -#define AE_AML_UNINITIALIZED_ARG (acpi_status) (0x0008 | AE_CODE_AML) -#define AE_AML_UNINITIALIZED_ELEMENT (acpi_status) (0x0009 | AE_CODE_AML) -#define AE_AML_NUMERIC_OVERFLOW (acpi_status) (0x000A | AE_CODE_AML) -#define AE_AML_REGION_LIMIT (acpi_status) (0x000B | AE_CODE_AML) -#define AE_AML_BUFFER_LIMIT (acpi_status) (0x000C | AE_CODE_AML) -#define AE_AML_PACKAGE_LIMIT (acpi_status) (0x000D | AE_CODE_AML) -#define AE_AML_DIVIDE_BY_ZERO (acpi_status) (0x000E | AE_CODE_AML) -#define AE_AML_BAD_NAME (acpi_status) (0x000F | AE_CODE_AML) -#define AE_AML_NAME_NOT_FOUND (acpi_status) (0x0010 | AE_CODE_AML) -#define AE_AML_INTERNAL (acpi_status) (0x0011 | AE_CODE_AML) -#define AE_AML_INVALID_SPACE_ID (acpi_status) (0x0012 | AE_CODE_AML) -#define AE_AML_STRING_LIMIT (acpi_status) (0x0013 | AE_CODE_AML) -#define AE_AML_NO_RETURN_VALUE (acpi_status) (0x0014 | AE_CODE_AML) -#define AE_AML_METHOD_LIMIT (acpi_status) (0x0015 | AE_CODE_AML) -#define AE_AML_NOT_OWNER (acpi_status) (0x0016 | AE_CODE_AML) -#define AE_AML_MUTEX_ORDER (acpi_status) (0x0017 | AE_CODE_AML) -#define AE_AML_MUTEX_NOT_ACQUIRED (acpi_status) (0x0018 | AE_CODE_AML) -#define AE_AML_INVALID_RESOURCE_TYPE (acpi_status) (0x0019 | AE_CODE_AML) -#define AE_AML_INVALID_INDEX (acpi_status) (0x001A | AE_CODE_AML) -#define AE_AML_REGISTER_LIMIT (acpi_status) (0x001B | AE_CODE_AML) -#define AE_AML_NO_WHILE (acpi_status) (0x001C | AE_CODE_AML) -#define AE_AML_ALIGNMENT (acpi_status) (0x001D | AE_CODE_AML) -#define AE_AML_NO_RESOURCE_END_TAG (acpi_status) (0x001E | AE_CODE_AML) -#define AE_AML_BAD_RESOURCE_VALUE (acpi_status) (0x001F | AE_CODE_AML) -#define AE_AML_CIRCULAR_REFERENCE (acpi_status) (0x0020 | AE_CODE_AML) - -#define AE_CODE_AML_MAX 0x0020 - -/* - * Internal exceptions used for control - */ -#define AE_CTRL_RETURN_VALUE (acpi_status) (0x0001 | AE_CODE_CONTROL) -#define AE_CTRL_PENDING (acpi_status) (0x0002 | AE_CODE_CONTROL) -#define AE_CTRL_TERMINATE (acpi_status) (0x0003 | AE_CODE_CONTROL) -#define AE_CTRL_TRUE (acpi_status) (0x0004 | AE_CODE_CONTROL) -#define AE_CTRL_FALSE (acpi_status) (0x0005 | AE_CODE_CONTROL) -#define AE_CTRL_DEPTH (acpi_status) (0x0006 | AE_CODE_CONTROL) -#define AE_CTRL_END (acpi_status) (0x0007 | AE_CODE_CONTROL) -#define AE_CTRL_TRANSFER (acpi_status) (0x0008 | AE_CODE_CONTROL) -#define AE_CTRL_BREAK (acpi_status) (0x0009 | AE_CODE_CONTROL) -#define AE_CTRL_CONTINUE (acpi_status) (0x000A | AE_CODE_CONTROL) -#define AE_CTRL_SKIP (acpi_status) (0x000B | AE_CODE_CONTROL) - -#define AE_CODE_CTRL_MAX 0x000B - - -#ifdef DEFINE_ACPI_GLOBALS - -/* - * String versions of the exception codes above - * These strings must match the corresponding defines exactly - */ -char const *acpi_gbl_exception_names_env[] = -{ - "AE_OK", - "AE_ERROR", - "AE_NO_ACPI_TABLES", - "AE_NO_NAMESPACE", - "AE_NO_MEMORY", - "AE_NOT_FOUND", - "AE_NOT_EXIST", - "AE_ALREADY_EXISTS", - "AE_TYPE", - "AE_NULL_OBJECT", - "AE_NULL_ENTRY", - "AE_BUFFER_OVERFLOW", - "AE_STACK_OVERFLOW", - "AE_STACK_UNDERFLOW", - "AE_NOT_IMPLEMENTED", - "AE_VERSION_MISMATCH", - "AE_SUPPORT", - "AE_SHARE", - "AE_LIMIT", - "AE_TIME", - "AE_UNKNOWN_STATUS", - "AE_ACQUIRE_DEADLOCK", - "AE_RELEASE_DEADLOCK", - "AE_NOT_ACQUIRED", - "AE_ALREADY_ACQUIRED", - "AE_NO_HARDWARE_RESPONSE", - "AE_NO_GLOBAL_LOCK", - "AE_LOGICAL_ADDRESS", - "AE_ABORT_METHOD" -}; - -char const *acpi_gbl_exception_names_pgm[] = -{ - "AE_BAD_PARAMETER", - "AE_BAD_CHARACTER", - "AE_BAD_PATHNAME", - "AE_BAD_DATA", - "AE_BAD_ADDRESS", - "AE_ALIGNMENT", - "AE_BAD_HEX_CONSTANT", - "AE_BAD_OCTAL_CONSTANT", - "AE_BAD_DECIMAL_CONSTANT" -}; - -char const *acpi_gbl_exception_names_tbl[] = -{ - "AE_BAD_SIGNATURE", - "AE_BAD_HEADER", - "AE_BAD_CHECKSUM", - "AE_BAD_VALUE", - "AE_TABLE_NOT_SUPPORTED", - "AE_INVALID_TABLE_LENGTH" -}; - -char const *acpi_gbl_exception_names_aml[] = -{ - "AE_AML_ERROR", - "AE_AML_PARSE", - "AE_AML_BAD_OPCODE", - "AE_AML_NO_OPERAND", - "AE_AML_OPERAND_TYPE", - "AE_AML_OPERAND_VALUE", - "AE_AML_UNINITIALIZED_LOCAL", - "AE_AML_UNINITIALIZED_ARG", - "AE_AML_UNINITIALIZED_ELEMENT", - "AE_AML_NUMERIC_OVERFLOW", - "AE_AML_REGION_LIMIT", - "AE_AML_BUFFER_LIMIT", - "AE_AML_PACKAGE_LIMIT", - "AE_AML_DIVIDE_BY_ZERO", - "AE_AML_BAD_NAME", - "AE_AML_NAME_NOT_FOUND", - "AE_AML_INTERNAL", - "AE_AML_INVALID_SPACE_ID", - "AE_AML_STRING_LIMIT", - "AE_AML_NO_RETURN_VALUE", - "AE_AML_METHOD_LIMIT", - "AE_AML_NOT_OWNER", - "AE_AML_MUTEX_ORDER", - "AE_AML_MUTEX_NOT_ACQUIRED", - "AE_AML_INVALID_RESOURCE_TYPE", - "AE_AML_INVALID_INDEX", - "AE_AML_REGISTER_LIMIT", - "AE_AML_NO_WHILE", - "AE_AML_ALIGNMENT", - "AE_AML_NO_RESOURCE_END_TAG", - "AE_AML_BAD_RESOURCE_VALUE", - "AE_AML_CIRCULAR_REFERENCE" -}; - -char const *acpi_gbl_exception_names_ctrl[] = -{ - "AE_CTRL_RETURN_VALUE", - "AE_CTRL_PENDING", - "AE_CTRL_TERMINATE", - "AE_CTRL_TRUE", - "AE_CTRL_FALSE", - "AE_CTRL_DEPTH", - "AE_CTRL_END", - "AE_CTRL_TRANSFER", - "AE_CTRL_BREAK", - "AE_CTRL_CONTINUE", - "AE_CTRL_SKIP" -}; - -#endif /* ACPI GLOBALS */ - - -#endif /* __ACEXCEP_H__ */ diff -Nru a/drivers/acpi/include/acglobal.h b/drivers/acpi/include/acglobal.h --- a/drivers/acpi/include/acglobal.h Sun Feb 9 21:13:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,298 +0,0 @@ -/****************************************************************************** - * - * Name: acglobal.h - Declarations for global variables - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACGLOBAL_H__ -#define __ACGLOBAL_H__ - - -/* - * Ensure that the globals are actually defined only once. - * - * The use of these defines allows a single list of globals (here) in order - * to simplify maintenance of the code. - */ -#ifdef DEFINE_ACPI_GLOBALS -#define ACPI_EXTERN -#else -#define ACPI_EXTERN extern -#endif - - -/***************************************************************************** - * - * Debug support - * - ****************************************************************************/ - -/* Runtime configuration of debug print levels */ - -extern u32 acpi_dbg_level; -extern u32 acpi_dbg_layer; - -/* Procedure nesting level for debug output */ - -extern u32 acpi_gbl_nesting_level; - - -/***************************************************************************** - * - * ACPI Table globals - * - ****************************************************************************/ - -/* - * Table pointers. - * Although these pointers are somewhat redundant with the global acpi_table, - * they are convenient because they are typed pointers. - * - * These tables are single-table only; meaning that there can be at most one - * of each in the system. Each global points to the actual table. - * - */ -ACPI_EXTERN u32 acpi_gbl_table_flags; -ACPI_EXTERN u32 acpi_gbl_rsdt_table_count; -ACPI_EXTERN struct rsdp_descriptor *acpi_gbl_RSDP; -ACPI_EXTERN XSDT_DESCRIPTOR *acpi_gbl_XSDT; -ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT; -ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT; -ACPI_EXTERN FACS_DESCRIPTOR *acpi_gbl_FACS; -ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS; - -/* - * Handle both ACPI 1.0 and ACPI 2.0 Integer widths - * If we are running a method that exists in a 32-bit ACPI table. - * Use only 32 bits of the Integer for conversion. - */ -ACPI_EXTERN u8 acpi_gbl_integer_bit_width; -ACPI_EXTERN u8 acpi_gbl_integer_byte_width; - -/* - * Since there may be multiple SSDTs and PSDTS, a single pointer is not - * sufficient; Therefore, there isn't one! - */ - - -/* - * ACPI Table info arrays - */ -extern struct acpi_table_desc acpi_gbl_acpi_tables[NUM_ACPI_TABLES]; -extern struct acpi_table_support acpi_gbl_acpi_table_data[NUM_ACPI_TABLES]; - -/* - * Predefined mutex objects. This array contains the - * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs. - * (The table maps local handles to the real OS handles) - */ -ACPI_EXTERN struct acpi_mutex_info acpi_gbl_acpi_mutex_info [NUM_MTX]; - - -/***************************************************************************** - * - * Miscellaneous globals - * - ****************************************************************************/ - - -ACPI_EXTERN struct acpi_memory_list acpi_gbl_memory_lists[ACPI_NUM_MEM_LISTS]; -ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_drv_notify; -ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_sys_notify; -ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; -ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; -ACPI_EXTERN acpi_handle acpi_gbl_global_lock_semaphore; - -ACPI_EXTERN u32 acpi_gbl_global_lock_thread_count; -ACPI_EXTERN u32 acpi_gbl_original_mode; -ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; -ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; -ACPI_EXTERN u32 acpi_gbl_ps_find_count; -ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; -ACPI_EXTERN u16 acpi_gbl_next_table_owner_id; -ACPI_EXTERN u16 acpi_gbl_next_method_owner_id; -ACPI_EXTERN u16 acpi_gbl_global_lock_handle; -ACPI_EXTERN u8 acpi_gbl_debugger_configuration; -ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; -ACPI_EXTERN u8 acpi_gbl_step_to_next_call; -ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; -ACPI_EXTERN u8 acpi_gbl_global_lock_present; -ACPI_EXTERN u8 acpi_gbl_events_initialized; - -extern u8 acpi_gbl_shutdown; -extern u32 acpi_gbl_startup_flags; -extern const u8 acpi_gbl_decode_to8bit[8]; -extern const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT]; -extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; -extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; - - -/***************************************************************************** - * - * Namespace globals - * - ****************************************************************************/ - -#define NUM_NS_TYPES ACPI_TYPE_INVALID+1 - -#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) -#define NUM_PREDEFINED_NAMES 10 -#else -#define NUM_PREDEFINED_NAMES 9 -#endif - -ACPI_EXTERN struct acpi_namespace_node acpi_gbl_root_node_struct; -ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node; - -extern const u8 acpi_gbl_ns_properties[NUM_NS_TYPES]; -extern const struct acpi_predefined_names acpi_gbl_pre_defined_names [NUM_PREDEFINED_NAMES]; - -#ifdef ACPI_DEBUG_OUTPUT -ACPI_EXTERN u32 acpi_gbl_current_node_count; -ACPI_EXTERN u32 acpi_gbl_current_node_size; -ACPI_EXTERN u32 acpi_gbl_max_concurrent_node_count; -ACPI_EXTERN acpi_size acpi_gbl_entry_stack_pointer; -ACPI_EXTERN acpi_size acpi_gbl_lowest_stack_pointer; -ACPI_EXTERN u32 acpi_gbl_deepest_nesting; -#endif - -/***************************************************************************** - * - * Interpreter globals - * - ****************************************************************************/ - - -ACPI_EXTERN struct acpi_thread_state *acpi_gbl_current_walk_list; - -/* Control method single step flag */ - -ACPI_EXTERN u8 acpi_gbl_cm_single_step; - - -/***************************************************************************** - * - * Parser globals - * - ****************************************************************************/ - -ACPI_EXTERN union acpi_parse_object *acpi_gbl_parsed_namespace_root; - -/***************************************************************************** - * - * Hardware globals - * - ****************************************************************************/ - -extern struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG]; -ACPI_EXTERN u8 acpi_gbl_sleep_type_a; -ACPI_EXTERN u8 acpi_gbl_sleep_type_b; - - -/***************************************************************************** - * - * Event and GPE globals - * - ****************************************************************************/ - -extern struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS]; -ACPI_EXTERN struct acpi_fixed_event_handler acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS]; - -ACPI_EXTERN acpi_handle acpi_gbl_gpe_obj_handle; -ACPI_EXTERN u32 acpi_gbl_gpe_register_count; -ACPI_EXTERN u32 acpi_gbl_gpe_number_max; -ACPI_EXTERN struct acpi_gpe_register_info *acpi_gbl_gpe_register_info; -ACPI_EXTERN struct acpi_gpe_number_info *acpi_gbl_gpe_number_info; -ACPI_EXTERN struct acpi_gpe_block_info acpi_gbl_gpe_block_info[ACPI_MAX_GPE_BLOCKS]; - -/* - * GPE translation table - * Indexed by the GPE number, returns a valid index into the global GPE tables. - * - * This table is needed because the GPE numbers supported by block 1 do not - * have to be contiguous with the GPE numbers supported by block 0. - */ -ACPI_EXTERN struct acpi_gpe_index_info *acpi_gbl_gpe_number_to_index; - - -/***************************************************************************** - * - * Debugger globals - * - ****************************************************************************/ - - -ACPI_EXTERN u8 acpi_gbl_db_output_flags; - -#ifdef ACPI_DISASSEMBLER - -ACPI_EXTERN u8 acpi_gbl_db_opt_disasm; -ACPI_EXTERN u8 acpi_gbl_db_opt_verbose; -#endif - - -#ifdef ACPI_DEBUGGER - -extern u8 acpi_gbl_method_executing; -extern u8 acpi_gbl_abort_method; -extern u8 acpi_gbl_db_terminate_threads; - -ACPI_EXTERN int optind; -ACPI_EXTERN char *optarg; - -ACPI_EXTERN u8 acpi_gbl_db_opt_tables; -ACPI_EXTERN u8 acpi_gbl_db_opt_stats; -ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; - - -ACPI_EXTERN char *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]; -ACPI_EXTERN char acpi_gbl_db_line_buf[80]; -ACPI_EXTERN char acpi_gbl_db_parsed_buf[80]; -ACPI_EXTERN char acpi_gbl_db_scope_buf[40]; -ACPI_EXTERN char acpi_gbl_db_debug_filename[40]; -ACPI_EXTERN u8 acpi_gbl_db_output_to_file; -ACPI_EXTERN char *acpi_gbl_db_buffer; -ACPI_EXTERN char *acpi_gbl_db_filename; -ACPI_EXTERN u32 acpi_gbl_db_debug_level; -ACPI_EXTERN u32 acpi_gbl_db_console_debug_level; -ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr; -ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node; - -/* - * Statistic globals - */ -ACPI_EXTERN u16 acpi_gbl_obj_type_count[ACPI_TYPE_NS_NODE_MAX+1]; -ACPI_EXTERN u16 acpi_gbl_node_type_count[ACPI_TYPE_NS_NODE_MAX+1]; -ACPI_EXTERN u16 acpi_gbl_obj_type_count_misc; -ACPI_EXTERN u16 acpi_gbl_node_type_count_misc; -ACPI_EXTERN u32 acpi_gbl_num_nodes; -ACPI_EXTERN u32 acpi_gbl_num_objects; - - -ACPI_EXTERN u32 acpi_gbl_size_of_parse_tree; -ACPI_EXTERN u32 acpi_gbl_size_of_method_trees; -ACPI_EXTERN u32 acpi_gbl_size_of_node_entries; -ACPI_EXTERN u32 acpi_gbl_size_of_acpi_objects; - -#endif /* ACPI_DEBUGGER */ - - -#endif /* __ACGLOBAL_H__ */ diff -Nru a/drivers/acpi/include/achware.h b/drivers/acpi/include/achware.h --- a/drivers/acpi/include/achware.h Sun Feb 9 21:13:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,154 +0,0 @@ -/****************************************************************************** - * - * Name: achware.h -- hardware specific interfaces - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACHWARE_H__ -#define __ACHWARE_H__ - - -/* PM Timer ticks per second (HZ) */ -#define PM_TIMER_FREQUENCY 3579545 - - -/* Prototypes */ - - -acpi_status -acpi_hw_initialize ( - void); - -acpi_status -acpi_hw_shutdown ( - void); - -acpi_status -acpi_hw_initialize_system_info ( - void); - -acpi_status -acpi_hw_set_mode ( - u32 mode); - -u32 -acpi_hw_get_mode ( - void); - -u32 -acpi_hw_get_mode_capabilities ( - void); - -/* Register I/O Prototypes */ - -struct acpi_bit_register_info * -acpi_hw_get_bit_register_info ( - u32 register_id); - -acpi_status -acpi_hw_register_read ( - u8 use_lock, - u32 register_id, - u32 *return_value); - -acpi_status -acpi_hw_register_write ( - u8 use_lock, - u32 register_id, - u32 value); - -acpi_status -acpi_hw_low_level_read ( - u32 width, - u32 *value, - struct acpi_generic_address *reg, - u32 offset); - -acpi_status -acpi_hw_low_level_write ( - u32 width, - u32 value, - struct acpi_generic_address *reg, - u32 offset); - -acpi_status -acpi_hw_clear_acpi_status ( - void); - - -/* GPE support */ - -u8 -acpi_hw_get_gpe_bit_mask ( - u32 gpe_number); - -acpi_status -acpi_hw_enable_gpe ( - u32 gpe_number); - -void -acpi_hw_enable_gpe_for_wakeup ( - u32 gpe_number); - -acpi_status -acpi_hw_disable_gpe ( - u32 gpe_number); - -void -acpi_hw_disable_gpe_for_wakeup ( - u32 gpe_number); - -acpi_status -acpi_hw_clear_gpe ( - u32 gpe_number); - -acpi_status -acpi_hw_get_gpe_status ( - u32 gpe_number, - acpi_event_status *event_status); - -acpi_status -acpi_hw_disable_non_wakeup_gpes ( - void); - -acpi_status -acpi_hw_enable_non_wakeup_gpes ( - void); - - -/* ACPI Timer prototypes */ - -acpi_status -acpi_get_timer_resolution ( - u32 *resolution); - -acpi_status -acpi_get_timer ( - u32 *ticks); - -acpi_status -acpi_get_timer_duration ( - u32 start_ticks, - u32 end_ticks, - u32 *time_elapsed); - - -#endif /* __ACHWARE_H__ */ diff -Nru a/drivers/acpi/include/acinterp.h b/drivers/acpi/include/acinterp.h --- a/drivers/acpi/include/acinterp.h Sun Feb 9 21:13:35 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,717 +0,0 @@ -/****************************************************************************** - * - * Name: acinterp.h - Interpreter subcomponent prototypes and defines - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACINTERP_H__ -#define __ACINTERP_H__ - - -#define ACPI_WALK_OPERANDS (&(walk_state->operands [walk_state->num_operands -1])) - - -acpi_status -acpi_ex_resolve_operands ( - u16 opcode, - union acpi_operand_object **stack_ptr, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_check_object_type ( - acpi_object_type type_needed, - acpi_object_type this_type, - void *object); - -/* - * exxface - External interpreter interfaces - */ - -acpi_status -acpi_ex_load_table ( - acpi_table_type table_id); - -acpi_status -acpi_ex_execute_method ( - struct acpi_namespace_node *method_node, - union acpi_operand_object **params, - union acpi_operand_object **return_obj_desc); - - -/* - * exconvrt - object conversion - */ - -acpi_status -acpi_ex_convert_to_integer ( - union acpi_operand_object *obj_desc, - union acpi_operand_object **result_desc, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_convert_to_buffer ( - union acpi_operand_object *obj_desc, - union acpi_operand_object **result_desc, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_convert_to_string ( - union acpi_operand_object *obj_desc, - union acpi_operand_object **result_desc, - u32 base, - u32 max_length, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_convert_to_target_type ( - acpi_object_type destination_type, - union acpi_operand_object *source_desc, - union acpi_operand_object **result_desc, - struct acpi_walk_state *walk_state); - -u32 -acpi_ex_convert_to_ascii ( - acpi_integer integer, - u32 base, - u8 *string, - u8 max_length); - -/* - * exfield - ACPI AML (p-code) execution - field manipulation - */ - -acpi_status -acpi_ex_extract_from_field ( - union acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length); - -acpi_status -acpi_ex_insert_into_field ( - union acpi_operand_object *obj_desc, - void *buffer, - u32 buffer_length); - -acpi_status -acpi_ex_setup_region ( - union acpi_operand_object *obj_desc, - u32 field_datum_byte_offset); - -acpi_status -acpi_ex_access_region ( - union acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - acpi_integer *value, - u32 read_write); - -u8 -acpi_ex_register_overflow ( - union acpi_operand_object *obj_desc, - acpi_integer value); - -acpi_status -acpi_ex_field_datum_io ( - union acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - acpi_integer *value, - u32 read_write); - -acpi_status -acpi_ex_write_with_update_rule ( - union acpi_operand_object *obj_desc, - acpi_integer mask, - acpi_integer field_value, - u32 field_datum_byte_offset); - -void -acpi_ex_get_buffer_datum( - acpi_integer *datum, - void *buffer, - u32 byte_granularity, - u32 offset); - -void -acpi_ex_set_buffer_datum ( - acpi_integer merged_datum, - void *buffer, - u32 byte_granularity, - u32 offset); - -acpi_status -acpi_ex_read_data_from_field ( - struct acpi_walk_state *walk_state, - union acpi_operand_object *obj_desc, - union acpi_operand_object **ret_buffer_desc); - -acpi_status -acpi_ex_write_data_to_field ( - union acpi_operand_object *source_desc, - union acpi_operand_object *obj_desc, - union acpi_operand_object **result_desc); - -/* - * exmisc - ACPI AML (p-code) execution - specific opcodes - */ - -acpi_status -acpi_ex_opcode_3A_0T_0R ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_3A_1T_1R ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_6A_0T_1R ( - struct acpi_walk_state *walk_state); - -u8 -acpi_ex_do_match ( - u32 match_op, - acpi_integer package_value, - acpi_integer match_value); - -acpi_status -acpi_ex_get_object_reference ( - union acpi_operand_object *obj_desc, - union acpi_operand_object **return_desc, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_resolve_multiple ( - struct acpi_walk_state *walk_state, - union acpi_operand_object *operand, - acpi_object_type *return_type, - union acpi_operand_object **return_desc); - -acpi_status -acpi_ex_concat_template ( - union acpi_operand_object *obj_desc, - union acpi_operand_object *obj_desc2, - union acpi_operand_object **actual_return_desc, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_do_concatenate ( - union acpi_operand_object *obj_desc, - union acpi_operand_object *obj_desc2, - union acpi_operand_object **actual_return_desc, - struct acpi_walk_state *walk_state); - -u8 -acpi_ex_do_logical_op ( - u16 opcode, - acpi_integer operand0, - acpi_integer operand1); - -acpi_integer -acpi_ex_do_math_op ( - u16 opcode, - acpi_integer operand0, - acpi_integer operand1); - -acpi_status -acpi_ex_create_mutex ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_processor ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_power_resource ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_region ( - u8 *aml_start, - u32 aml_length, - u8 region_space, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_table_region ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_event ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_alias ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_create_method ( - u8 *aml_start, - u32 aml_length, - struct acpi_walk_state *walk_state); - - -/* - * exconfig - dynamic table load/unload - */ - -acpi_status -acpi_ex_add_table ( - struct acpi_table_header *table, - struct acpi_namespace_node *parent_node, - union acpi_operand_object **ddb_handle); - -acpi_status -acpi_ex_load_op ( - union acpi_operand_object *obj_desc, - union acpi_operand_object *target, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_load_table_op ( - struct acpi_walk_state *walk_state, - union acpi_operand_object **return_desc); - -acpi_status -acpi_ex_unload_table ( - union acpi_operand_object *ddb_handle); - - -/* - * exmutex - mutex support - */ - -acpi_status -acpi_ex_acquire_mutex ( - union acpi_operand_object *time_desc, - union acpi_operand_object *obj_desc, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_release_mutex ( - union acpi_operand_object *obj_desc, - struct acpi_walk_state *walk_state); - -void -acpi_ex_release_all_mutexes ( - struct acpi_thread_state *thread); - -void -acpi_ex_unlink_mutex ( - union acpi_operand_object *obj_desc); - -void -acpi_ex_link_mutex ( - union acpi_operand_object *obj_desc, - struct acpi_thread_state *thread); - -/* - * exprep - ACPI AML (p-code) execution - prep utilities - */ - -acpi_status -acpi_ex_prep_common_field_object ( - union acpi_operand_object *obj_desc, - u8 field_flags, - u8 field_attribute, - u32 field_bit_position, - u32 field_bit_length); - -acpi_status -acpi_ex_prep_field_value ( - struct acpi_create_field_info *info); - -/* - * exsystem - Interface to OS services - */ - -acpi_status -acpi_ex_system_do_notify_op ( - union acpi_operand_object *value, - union acpi_operand_object *obj_desc); - -acpi_status -acpi_ex_system_do_suspend( - u32 time); - -acpi_status -acpi_ex_system_do_stall ( - u32 time); - -acpi_status -acpi_ex_system_acquire_mutex( - union acpi_operand_object *time, - union acpi_operand_object *obj_desc); - -acpi_status -acpi_ex_system_release_mutex( - union acpi_operand_object *obj_desc); - -acpi_status -acpi_ex_system_signal_event( - union acpi_operand_object *obj_desc); - -acpi_status -acpi_ex_system_wait_event( - union acpi_operand_object *time, - union acpi_operand_object *obj_desc); - -acpi_status -acpi_ex_system_reset_event( - union acpi_operand_object *obj_desc); - -acpi_status -acpi_ex_system_wait_semaphore ( - acpi_handle semaphore, - u16 timeout); - - -/* - * exmonadic - ACPI AML (p-code) execution, monadic operators - */ - -acpi_status -acpi_ex_opcode_1A_0T_0R ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_1A_0T_1R ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_1A_1T_1R ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_1A_1T_0R ( - struct acpi_walk_state *walk_state); - -/* - * exdyadic - ACPI AML (p-code) execution, dyadic operators - */ - -acpi_status -acpi_ex_opcode_2A_0T_0R ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_2A_0T_1R ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_2A_1T_1R ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_opcode_2A_2T_1R ( - struct acpi_walk_state *walk_state); - - -/* - * exresolv - Object resolution and get value functions - */ - -acpi_status -acpi_ex_resolve_to_value ( - union acpi_operand_object **stack_ptr, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_resolve_node_to_value ( - struct acpi_namespace_node **stack_ptr, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_resolve_object_to_value ( - union acpi_operand_object **stack_ptr, - struct acpi_walk_state *walk_state); - - -/* - * exdump - Scanner debug output routines - */ - -void -acpi_ex_dump_operand ( - union acpi_operand_object *entry_desc); - -void -acpi_ex_dump_operands ( - union acpi_operand_object **operands, - acpi_interpreter_mode interpreter_mode, - char *ident, - u32 num_levels, - char *note, - char *module_name, - u32 line_number); - -void -acpi_ex_dump_object_descriptor ( - union acpi_operand_object *object, - u32 flags); - -void -acpi_ex_dump_node ( - struct acpi_namespace_node *node, - u32 flags); - -void -acpi_ex_out_string ( - char *title, - char *value); - -void -acpi_ex_out_pointer ( - char *title, - void *value); - -void -acpi_ex_out_integer ( - char *title, - u32 value); - -void -acpi_ex_out_address ( - char *title, - acpi_physical_address value); - - -/* - * exnames - interpreter/scanner name load/execute - */ - -char * -acpi_ex_allocate_name_string ( - u32 prefix_count, - u32 num_name_segs); - -u32 -acpi_ex_good_char ( - u32 character); - -acpi_status -acpi_ex_name_segment ( - u8 **in_aml_address, - char *name_string); - -acpi_status -acpi_ex_get_name_string ( - acpi_object_type data_type, - u8 *in_aml_address, - char **out_name_string, - u32 *out_name_length); - -acpi_status -acpi_ex_do_name ( - acpi_object_type data_type, - acpi_interpreter_mode load_exec_mode); - - -/* - * exstore - Object store support - */ - -acpi_status -acpi_ex_store ( - union acpi_operand_object *val_desc, - union acpi_operand_object *dest_desc, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_store_object_to_index ( - union acpi_operand_object *val_desc, - union acpi_operand_object *dest_desc, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_store_object_to_node ( - union acpi_operand_object *source_desc, - struct acpi_namespace_node *node, - struct acpi_walk_state *walk_state); - - -/* - * exstoren - */ - -acpi_status -acpi_ex_resolve_object ( - union acpi_operand_object **source_desc_ptr, - acpi_object_type target_type, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ex_store_object_to_object ( - union acpi_operand_object *source_desc, - union acpi_operand_object *dest_desc, - union acpi_operand_object **new_desc, - struct acpi_walk_state *walk_state); - - -/* - * excopy - object copy - */ - -acpi_status -acpi_ex_store_buffer_to_buffer ( - union acpi_operand_object *source_desc, - union acpi_operand_object *target_desc); - -acpi_status -acpi_ex_store_string_to_string ( - union acpi_operand_object *source_desc, - union acpi_operand_object *target_desc); - -acpi_status -acpi_ex_copy_integer_to_index_field ( - union acpi_operand_object *source_desc, - union acpi_operand_object *target_desc); - -acpi_status -acpi_ex_copy_integer_to_bank_field ( - union acpi_operand_object *source_desc, - union acpi_operand_object *target_desc); - -acpi_status -acpi_ex_copy_data_to_named_field ( - union acpi_operand_object *source_desc, - struct acpi_namespace_node *node); - -acpi_status -acpi_ex_copy_integer_to_buffer_field ( - union acpi_operand_object *source_desc, - union acpi_operand_object *target_desc); - -/* - * exutils - interpreter/scanner utilities - */ - -acpi_status -acpi_ex_enter_interpreter ( - void); - -void -acpi_ex_exit_interpreter ( - void); - -void -acpi_ex_truncate_for32bit_table ( - union acpi_operand_object *obj_desc); - -u8 -acpi_ex_acquire_global_lock ( - u32 rule); - -void -acpi_ex_release_global_lock ( - u8 locked); - -u32 -acpi_ex_digits_needed ( - acpi_integer value, - u32 base); - -void -acpi_ex_eisa_id_to_string ( - u32 numeric_id, - char *out_string); - -void -acpi_ex_unsigned_integer_to_string ( - acpi_integer value, - char *out_string); - - -/* - * exregion - default op_region handlers - */ - -acpi_status -acpi_ex_system_memory_space_handler ( - u32 function, - acpi_physical_address address, - u32 bit_width, - acpi_integer *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_system_io_space_handler ( - u32 function, - acpi_physical_address address, - u32 bit_width, - acpi_integer *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_pci_config_space_handler ( - u32 function, - acpi_physical_address address, - u32 bit_width, - acpi_integer *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_cmos_space_handler ( - u32 function, - acpi_physical_address address, - u32 bit_width, - acpi_integer *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_pci_bar_space_handler ( - u32 function, - acpi_physical_address address, - u32 bit_width, - acpi_integer *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_embedded_controller_space_handler ( - u32 function, - acpi_physical_address address, - u32 bit_width, - acpi_integer *value, - void *handler_context, - void *region_context); - -acpi_status -acpi_ex_sm_bus_space_handler ( - u32 function, - acpi_physical_address address, - u32 bit_width, - acpi_integer *value, - void *handler_context, - void *region_context); - - -acpi_status -acpi_ex_data_table_space_handler ( - u32 function, - acpi_physical_address address, - u32 bit_width, - acpi_integer *value, - void *handler_context, - void *region_context); - -#endif /* __INTERP_H__ */ diff -Nru a/drivers/acpi/include/aclocal.h b/drivers/acpi/include/aclocal.h --- a/drivers/acpi/include/aclocal.h Sun Feb 9 21:13:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,953 +0,0 @@ -/****************************************************************************** - * - * Name: aclocal.h - Internal data types used across the ACPI subsystem - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACLOCAL_H__ -#define __ACLOCAL_H__ - - -#define ACPI_WAIT_FOREVER 0xFFFF /* u16, as per ACPI spec */ - -typedef void * acpi_mutex; -typedef u32 acpi_mutex_handle; - - -/* Total number of aml opcodes defined */ - -#define AML_NUM_OPCODES 0x7E - - -/***************************************************************************** - * - * Mutex typedefs and structs - * - ****************************************************************************/ - - -/* - * Predefined handles for the mutex objects used within the subsystem - * All mutex objects are automatically created by acpi_ut_mutex_initialize. - * - * The acquire/release ordering protocol is implied via this list. Mutexes - * with a lower value must be acquired before mutexes with a higher value. - * - * NOTE: any changes here must be reflected in the acpi_gbl_mutex_names table also! - */ - -#define ACPI_MTX_EXECUTE 0 -#define ACPI_MTX_INTERPRETER 1 -#define ACPI_MTX_PARSER 2 -#define ACPI_MTX_DISPATCHER 3 -#define ACPI_MTX_TABLES 4 -#define ACPI_MTX_OP_REGIONS 5 -#define ACPI_MTX_NAMESPACE 6 -#define ACPI_MTX_EVENTS 7 -#define ACPI_MTX_HARDWARE 8 -#define ACPI_MTX_CACHES 9 -#define ACPI_MTX_MEMORY 10 -#define ACPI_MTX_DEBUG_CMD_COMPLETE 11 -#define ACPI_MTX_DEBUG_CMD_READY 12 - -#define MAX_MTX 12 -#define NUM_MTX MAX_MTX+1 - - -#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) -#ifdef DEFINE_ACPI_GLOBALS - -/* Names for the mutexes used in the subsystem */ - -static char *acpi_gbl_mutex_names[] = -{ - "ACPI_MTX_Execute", - "ACPI_MTX_Interpreter", - "ACPI_MTX_Parser", - "ACPI_MTX_Dispatcher", - "ACPI_MTX_Tables", - "ACPI_MTX_op_regions", - "ACPI_MTX_Namespace", - "ACPI_MTX_Events", - "ACPI_MTX_Hardware", - "ACPI_MTX_Caches", - "ACPI_MTX_Memory", - "ACPI_MTX_debug_cmd_complete", - "ACPI_MTX_debug_cmd_ready", -}; - -#endif -#endif - - -/* Table for the global mutexes */ - -struct acpi_mutex_info -{ - acpi_mutex mutex; - u32 use_count; - u32 owner_id; -}; - -/* This owner ID means that the mutex is not in use (unlocked) */ - -#define ACPI_MUTEX_NOT_ACQUIRED (u32) (-1) - - -/* Lock flag parameter for various interfaces */ - -#define ACPI_MTX_DO_NOT_LOCK 0 -#define ACPI_MTX_LOCK 1 - - -typedef u16 acpi_owner_id; -#define ACPI_OWNER_TYPE_TABLE 0x0 -#define ACPI_OWNER_TYPE_METHOD 0x1 -#define ACPI_FIRST_METHOD_ID 0x0000 -#define ACPI_FIRST_TABLE_ID 0x8000 - -/* TBD: [Restructure] get rid of the need for this! */ - -#define TABLE_ID_DSDT (acpi_owner_id) 0x8000 - - -/* Field access granularities */ - -#define ACPI_FIELD_BYTE_GRANULARITY 1 -#define ACPI_FIELD_WORD_GRANULARITY 2 -#define ACPI_FIELD_DWORD_GRANULARITY 4 -#define ACPI_FIELD_QWORD_GRANULARITY 8 - -/***************************************************************************** - * - * Namespace typedefs and structs - * - ****************************************************************************/ - - -/* Operational modes of the AML interpreter/scanner */ - -typedef enum -{ - ACPI_IMODE_LOAD_PASS1 = 0x01, - ACPI_IMODE_LOAD_PASS2 = 0x02, - ACPI_IMODE_EXECUTE = 0x0E - -} acpi_interpreter_mode; - - -/* - * The Node describes a named object that appears in the AML - * An acpi_node is used to store Nodes. - * - * data_type is used to differentiate between internal descriptors, and MUST - * be the first byte in this structure. - */ - -union acpi_name_union -{ - u32 integer; - char ascii[4]; -}; - -struct acpi_namespace_node -{ - u8 descriptor; /* Used to differentiate object descriptor types */ - u8 type; /* Type associated with this name */ - u16 owner_id; - union acpi_name_union name; /* ACPI Name, always 4 chars per ACPI spec */ - - - union acpi_operand_object *object; /* Pointer to attached ACPI object (optional) */ - struct acpi_namespace_node *child; /* first child */ - struct acpi_namespace_node *peer; /* Next peer*/ - u16 reference_count; /* Current count of references and children */ - u8 flags; -}; - - -#define ACPI_ENTRY_NOT_FOUND NULL - - -/* Node flags */ - -#define ANOBJ_RESERVED 0x01 -#define ANOBJ_END_OF_PEER_LIST 0x02 -#define ANOBJ_DATA_WIDTH_32 0x04 /* Parent table is 64-bits */ -#define ANOBJ_METHOD_ARG 0x08 -#define ANOBJ_METHOD_LOCAL 0x10 -#define ANOBJ_METHOD_NO_RETVAL 0x20 -#define ANOBJ_METHOD_SOME_NO_RETVAL 0x40 - -#define ANOBJ_IS_BIT_OFFSET 0x80 - - -/* - * ACPI Table Descriptor. One per ACPI table - */ -struct acpi_table_desc -{ - struct acpi_table_desc *prev; - struct acpi_table_desc *next; - struct acpi_table_desc *installed_desc; - struct acpi_table_header *pointer; - u8 *aml_start; - u64 physical_address; - u32 aml_length; - acpi_size length; - u32 count; - acpi_owner_id table_id; - u8 type; - u8 allocation; - u8 loaded_into_namespace; -}; - - -struct acpi_find_context -{ - char *search_for; - acpi_handle *list; - u32 *count; -}; - - -struct acpi_ns_search_data -{ - struct acpi_namespace_node *node; -}; - - -/* - * Predefined Namespace items - */ -struct acpi_predefined_names -{ - char *name; - u8 type; - char *val; -}; - - -/* Object types used during package copies */ - - -#define ACPI_COPY_TYPE_SIMPLE 0 -#define ACPI_COPY_TYPE_PACKAGE 1 - -/* Info structure used to convert external<->internal namestrings */ - -struct acpi_namestring_info -{ - char *external_name; - char *next_external_char; - char *internal_name; - u32 length; - u32 num_segments; - u32 num_carats; - u8 fully_qualified; -}; - - -/* Field creation info */ - -struct acpi_create_field_info -{ - struct acpi_namespace_node *region_node; - struct acpi_namespace_node *field_node; - struct acpi_namespace_node *register_node; - struct acpi_namespace_node *data_register_node; - u32 bank_value; - u32 field_bit_position; - u32 field_bit_length; - u8 field_flags; - u8 attribute; - u8 field_type; -}; - - -/***************************************************************************** - * - * Event typedefs and structs - * - ****************************************************************************/ - -/* Information about each GPE register block */ - -struct acpi_gpe_block_info -{ - struct acpi_generic_address *block_address; - u16 register_count; - u8 block_base_number; -}; - -/* Information about a particular GPE register pair */ - -struct acpi_gpe_register_info -{ - struct acpi_generic_address status_address; /* Address of status reg */ - struct acpi_generic_address enable_address; /* Address of enable reg */ - u8 status; /* Current value of status reg */ - u8 enable; /* Current value of enable reg */ - u8 wake_enable; /* Mask of bits to keep enabled when sleeping */ - u8 base_gpe_number; /* Base GPE number for this register */ -}; - - -#define ACPI_GPE_LEVEL_TRIGGERED 1 -#define ACPI_GPE_EDGE_TRIGGERED 2 - - -/* Information about each particular GPE level */ - -struct acpi_gpe_number_info -{ - struct acpi_namespace_node *method_node; /* Method node for this GPE level */ - acpi_gpe_handler handler; /* Address of handler, if any */ - void *context; /* Context to be passed to handler */ - u8 type; /* Level or Edge */ - u8 bit_mask; -}; - - -struct acpi_gpe_index_info -{ - u8 number_index; -}; - -/* Information about each particular fixed event */ - -struct acpi_fixed_event_handler -{ - acpi_event_handler handler; /* Address of handler. */ - void *context; /* Context to be passed to handler */ -}; - - -struct acpi_fixed_event_info -{ - u8 status_register_id; - u8 enable_register_id; - u16 status_bit_mask; - u16 enable_bit_mask; -}; - -/* Information used during field processing */ - -struct acpi_field_info -{ - u8 skip_field; - u8 field_flag; - u32 pkg_length; -}; - - -/***************************************************************************** - * - * Generic "state" object for stacks - * - ****************************************************************************/ - - -#define ACPI_CONTROL_NORMAL 0xC0 -#define ACPI_CONTROL_CONDITIONAL_EXECUTING 0xC1 -#define ACPI_CONTROL_PREDICATE_EXECUTING 0xC2 -#define ACPI_CONTROL_PREDICATE_FALSE 0xC3 -#define ACPI_CONTROL_PREDICATE_TRUE 0xC4 - - -/* Forward declarations */ -struct acpi_walk_state ; -struct acpi_obj_mutex; -union acpi_parse_object ; - - -#define ACPI_STATE_COMMON /* Two 32-bit fields and a pointer */\ - u8 data_type; /* To differentiate various internal objs */\ - u8 flags; \ - u16 value; \ - u16 state; \ - u16 reserved; \ - void *next; \ - -struct acpi_common_state -{ - ACPI_STATE_COMMON -}; - - -/* - * Update state - used to traverse complex objects such as packages - */ -struct acpi_update_state -{ - ACPI_STATE_COMMON - union acpi_operand_object *object; -}; - - -/* - * Pkg state - used to traverse nested package structures - */ -struct acpi_pkg_state -{ - ACPI_STATE_COMMON - union acpi_operand_object *source_object; - union acpi_operand_object *dest_object; - struct acpi_walk_state *walk_state; - void *this_target_obj; - u32 num_packages; - u16 index; -}; - - -/* - * Control state - one per if/else and while constructs. - * Allows nesting of these constructs - */ -struct acpi_control_state -{ - ACPI_STATE_COMMON - union acpi_parse_object *predicate_op; - u8 *aml_predicate_start; /* Start of if/while predicate */ - u8 *package_end; /* End of if/while block */ - u16 opcode; -}; - - -/* - * Scope state - current scope during namespace lookups - */ -struct acpi_scope_state -{ - ACPI_STATE_COMMON - struct acpi_namespace_node *node; -}; - - -struct acpi_pscope_state -{ - ACPI_STATE_COMMON - union acpi_parse_object *op; /* current op being parsed */ - u8 *arg_end; /* current argument end */ - u8 *pkg_end; /* current package end */ - u32 arg_list; /* next argument to parse */ - u32 arg_count; /* Number of fixed arguments */ -}; - - -/* - * Thread state - one per thread across multiple walk states. Multiple walk - * states are created when there are nested control methods executing. - */ -struct acpi_thread_state -{ - ACPI_STATE_COMMON - struct acpi_walk_state *walk_state_list; /* Head of list of walk_states for this thread */ - union acpi_operand_object *acquired_mutex_list; /* List of all currently acquired mutexes */ - u32 thread_id; /* Running thread ID */ - u16 current_sync_level; /* Mutex Sync (nested acquire) level */ -}; - - -/* - * Result values - used to accumulate the results of nested - * AML arguments - */ -struct acpi_result_values -{ - ACPI_STATE_COMMON - union acpi_operand_object *obj_desc [ACPI_OBJ_NUM_OPERANDS]; - u8 num_results; - u8 last_insert; -}; - - -typedef -acpi_status (*acpi_parse_downwards) ( - struct acpi_walk_state *walk_state, - union acpi_parse_object **out_op); - -typedef -acpi_status (*acpi_parse_upwards) ( - struct acpi_walk_state *walk_state); - - -/* - * Notify info - used to pass info to the deferred notify - * handler/dispatcher. - */ -struct acpi_notify_info -{ - ACPI_STATE_COMMON - struct acpi_namespace_node *node; - union acpi_operand_object *handler_obj; -}; - - -/* Generic state is union of structs above */ - -union acpi_generic_state -{ - struct acpi_common_state common; - struct acpi_control_state control; - struct acpi_update_state update; - struct acpi_scope_state scope; - struct acpi_pscope_state parse_scope; - struct acpi_pkg_state pkg; - struct acpi_thread_state thread; - struct acpi_result_values results; - struct acpi_notify_info notify; -}; - - -/***************************************************************************** - * - * Interpreter typedefs and structs - * - ****************************************************************************/ - -typedef -acpi_status (*ACPI_EXECUTE_OP) ( - struct acpi_walk_state *walk_state); - - -/***************************************************************************** - * - * Parser typedefs and structs - * - ****************************************************************************/ - -/* - * AML opcode, name, and argument layout - */ -struct acpi_opcode_info -{ -#if defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUG_OUTPUT) - char *name; /* Opcode name (disassembler/debug only) */ -#endif - u32 parse_args; /* Grammar/Parse time arguments */ - u32 runtime_args; /* Interpret time arguments */ - u32 flags; /* Misc flags */ - u8 object_type; /* Corresponding internal object type */ - u8 class; /* Opcode class */ - u8 type; /* Opcode type */ -}; - - -union acpi_parse_value -{ - acpi_integer integer; /* integer constant (Up to 64 bits) */ - struct uint64_struct integer64; /* Structure overlay for 2 32-bit Dwords */ - u32 integer32; /* integer constant, 32 bits only */ - u16 integer16; /* integer constant, 16 bits only */ - u8 integer8; /* integer constant, 8 bits only */ - u32 size; /* bytelist or field size */ - char *string; /* NULL terminated string */ - u8 *buffer; /* buffer or string */ - char *name; /* NULL terminated string */ - union acpi_parse_object *arg; /* arguments and contained ops */ -}; - - -#define ACPI_PARSE_COMMON \ - u8 data_type; /* To differentiate various internal objs */\ - u8 flags; /* Type of Op */\ - u16 aml_opcode; /* AML opcode */\ - u32 aml_offset; /* offset of declaration in AML */\ - union acpi_parse_object *parent; /* parent op */\ - union acpi_parse_object *next; /* next op */\ - ACPI_DISASM_ONLY_MEMBERS (\ - u8 disasm_flags; /* Used during AML disassembly */\ - u8 disasm_opcode; /* Subtype used for disassembly */\ - char aml_op_name[16]) /* op name (debug only) */\ - /* NON-DEBUG members below: */\ - struct acpi_namespace_node *node; /* for use by interpreter */\ - union acpi_parse_value value; /* Value or args associated with the opcode */\ - - -#define ACPI_DASM_BUFFER 0x00 -#define ACPI_DASM_RESOURCE 0x01 -#define ACPI_DASM_STRING 0x02 -#define ACPI_DASM_UNICODE 0x03 -#define ACPI_DASM_EISAID 0x04 -#define ACPI_DASM_MATCHOP 0x05 - -/* - * generic operation (for example: If, While, Store) - */ -struct acpi_parse_obj_common -{ - ACPI_PARSE_COMMON -}; - - -/* - * Extended Op for named ops (Scope, Method, etc.), deferred ops (Methods and op_regions), - * and bytelists. - */ -struct acpi_parse_obj_named -{ - ACPI_PARSE_COMMON - u8 *path; - u8 *data; /* AML body or bytelist data */ - u32 length; /* AML length */ - u32 name; /* 4-byte name or zero if no name */ -}; - - -/* The parse node is the fundamental element of the parse tree */ - -struct acpi_parse_obj_asl -{ - ACPI_PARSE_COMMON - union acpi_parse_object *child; - union acpi_parse_object *parent_method; - char *filename; - char *external_name; - char *namepath; - char name_seg[4]; - u32 extra_value; - u32 column; - u32 line_number; - u32 logical_line_number; - u32 logical_byte_offset; - u32 end_line; - u32 end_logical_line; - u32 acpi_btype; - u32 aml_length; - u32 aml_subtree_length; - u32 final_aml_length; - u32 final_aml_offset; - u32 compile_flags; - u16 parse_opcode; - u8 aml_opcode_length; - u8 aml_pkg_len_bytes; - u8 extra; - char parse_op_name[12]; -}; - - -union acpi_parse_object -{ - struct acpi_parse_obj_common common; - struct acpi_parse_obj_named named; - struct acpi_parse_obj_asl asl; -}; - - -/* - * Parse state - one state per parser invocation and each control - * method. - */ -struct acpi_parse_state -{ - u32 aml_size; - u8 *aml_start; /* first AML byte */ - u8 *aml; /* next AML byte */ - u8 *aml_end; /* (last + 1) AML byte */ - u8 *pkg_start; /* current package begin */ - u8 *pkg_end; /* current package end */ - union acpi_parse_object *start_op; /* root of parse tree */ - struct acpi_namespace_node *start_node; - union acpi_generic_state *scope; /* current scope */ - union acpi_parse_object *start_scope; -}; - - -/* Parse object flags */ - -#define ACPI_PARSEOP_GENERIC 0x01 -#define ACPI_PARSEOP_NAMED 0x02 -#define ACPI_PARSEOP_DEFERRED 0x04 -#define ACPI_PARSEOP_BYTELIST 0x08 -#define ACPI_PARSEOP_IN_CACHE 0x80 - -/* Parse object disasm_flags */ - -#define ACPI_PARSEOP_IGNORE 0x01 -#define ACPI_PARSEOP_PARAMLIST 0x02 -#define ACPI_PARSEOP_EMPTY_TERMLIST 0x04 -#define ACPI_PARSEOP_SPECIAL 0x10 - - -/***************************************************************************** - * - * Hardware (ACPI registers) and PNP - * - ****************************************************************************/ - -#define PCI_ROOT_HID_STRING "PNP0A03" - -struct acpi_bit_register_info -{ - u8 parent_register; - u8 bit_position; - u16 access_bit_mask; -}; - - -/* - * Register IDs - * These are the full ACPI registers - */ -#define ACPI_REGISTER_PM1_STATUS 0x01 -#define ACPI_REGISTER_PM1_ENABLE 0x02 -#define ACPI_REGISTER_PM1_CONTROL 0x03 -#define ACPI_REGISTER_PM1A_CONTROL 0x04 -#define ACPI_REGISTER_PM1B_CONTROL 0x05 -#define ACPI_REGISTER_PM2_CONTROL 0x06 -#define ACPI_REGISTER_PM_TIMER 0x07 -#define ACPI_REGISTER_PROCESSOR_BLOCK 0x08 -#define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x09 - - -/* Masks used to access the bit_registers */ - -#define ACPI_BITMASK_TIMER_STATUS 0x0001 -#define ACPI_BITMASK_BUS_MASTER_STATUS 0x0010 -#define ACPI_BITMASK_GLOBAL_LOCK_STATUS 0x0020 -#define ACPI_BITMASK_POWER_BUTTON_STATUS 0x0100 -#define ACPI_BITMASK_SLEEP_BUTTON_STATUS 0x0200 -#define ACPI_BITMASK_RT_CLOCK_STATUS 0x0400 -#define ACPI_BITMASK_WAKE_STATUS 0x8000 - -#define ACPI_BITMASK_ALL_FIXED_STATUS (ACPI_BITMASK_TIMER_STATUS | \ - ACPI_BITMASK_BUS_MASTER_STATUS | \ - ACPI_BITMASK_GLOBAL_LOCK_STATUS | \ - ACPI_BITMASK_POWER_BUTTON_STATUS | \ - ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ - ACPI_BITMASK_RT_CLOCK_STATUS | \ - ACPI_BITMASK_WAKE_STATUS) - -#define ACPI_BITMASK_TIMER_ENABLE 0x0001 -#define ACPI_BITMASK_GLOBAL_LOCK_ENABLE 0x0020 -#define ACPI_BITMASK_POWER_BUTTON_ENABLE 0x0100 -#define ACPI_BITMASK_SLEEP_BUTTON_ENABLE 0x0200 -#define ACPI_BITMASK_RT_CLOCK_ENABLE 0x0400 - -#define ACPI_BITMASK_SCI_ENABLE 0x0001 -#define ACPI_BITMASK_BUS_MASTER_RLD 0x0002 -#define ACPI_BITMASK_GLOBAL_LOCK_RELEASE 0x0004 -#define ACPI_BITMASK_SLEEP_TYPE_X 0x1C00 -#define ACPI_BITMASK_SLEEP_ENABLE 0x2000 - -#define ACPI_BITMASK_ARB_DISABLE 0x0001 - - -/* Raw bit position of each bit_register */ - -#define ACPI_BITPOSITION_TIMER_STATUS 0x00 -#define ACPI_BITPOSITION_BUS_MASTER_STATUS 0x04 -#define ACPI_BITPOSITION_GLOBAL_LOCK_STATUS 0x05 -#define ACPI_BITPOSITION_POWER_BUTTON_STATUS 0x08 -#define ACPI_BITPOSITION_SLEEP_BUTTON_STATUS 0x09 -#define ACPI_BITPOSITION_RT_CLOCK_STATUS 0x0A -#define ACPI_BITPOSITION_WAKE_STATUS 0x0F - -#define ACPI_BITPOSITION_TIMER_ENABLE 0x00 -#define ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE 0x05 -#define ACPI_BITPOSITION_POWER_BUTTON_ENABLE 0x08 -#define ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE 0x09 -#define ACPI_BITPOSITION_RT_CLOCK_ENABLE 0x0A - -#define ACPI_BITPOSITION_SCI_ENABLE 0x00 -#define ACPI_BITPOSITION_BUS_MASTER_RLD 0x01 -#define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE 0x02 -#define ACPI_BITPOSITION_SLEEP_TYPE_X 0x0A -#define ACPI_BITPOSITION_SLEEP_ENABLE 0x0D - -#define ACPI_BITPOSITION_ARB_DISABLE 0x00 - - -/***************************************************************************** - * - * Resource descriptors - * - ****************************************************************************/ - - -/* resource_type values */ - -#define ACPI_RESOURCE_TYPE_MEMORY_RANGE 0 -#define ACPI_RESOURCE_TYPE_IO_RANGE 1 -#define ACPI_RESOURCE_TYPE_BUS_NUMBER_RANGE 2 - -/* Resource descriptor types and masks */ - -#define ACPI_RDESC_TYPE_LARGE 0x80 -#define ACPI_RDESC_TYPE_SMALL 0x00 - -#define ACPI_RDESC_TYPE_MASK 0x80 -#define ACPI_RDESC_SMALL_MASK 0x78 /* Only bits 6:3 contain the type */ - - -/* - * Small resource descriptor types - * Note: The 3 length bits (2:0) must be zero - */ -#define ACPI_RDESC_TYPE_IRQ_FORMAT 0x20 -#define ACPI_RDESC_TYPE_DMA_FORMAT 0x28 -#define ACPI_RDESC_TYPE_START_DEPENDENT 0x30 -#define ACPI_RDESC_TYPE_END_DEPENDENT 0x38 -#define ACPI_RDESC_TYPE_IO_PORT 0x40 -#define ACPI_RDESC_TYPE_FIXED_IO_PORT 0x48 -#define ACPI_RDESC_TYPE_SMALL_VENDOR 0x70 -#define ACPI_RDESC_TYPE_END_TAG 0x78 - -/* - * Large resource descriptor types - */ - -#define ACPI_RDESC_TYPE_MEMORY_24 0x81 -#define ACPI_RDESC_TYPE_GENERAL_REGISTER 0x82 -#define ACPI_RDESC_TYPE_LARGE_VENDOR 0x84 -#define ACPI_RDESC_TYPE_MEMORY_32 0x85 -#define ACPI_RDESC_TYPE_FIXED_MEMORY_32 0x86 -#define ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE 0x87 -#define ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE 0x88 -#define ACPI_RDESC_TYPE_EXTENDED_XRUPT 0x89 -#define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE 0x8A - - -/* String version of device HIDs and UIDs */ - -#define ACPI_DEVICE_ID_LENGTH 0x09 - -struct acpi_device_id -{ - char buffer[ACPI_DEVICE_ID_LENGTH]; -}; - - -/***************************************************************************** - * - * Miscellaneous - * - ****************************************************************************/ - -#define ACPI_ASCII_ZERO 0x30 - - -/***************************************************************************** - * - * Debugger - * - ****************************************************************************/ - -struct acpi_db_method_info -{ - acpi_handle thread_gate; - char *name; - char **args; - u32 flags; - u32 num_loops; - char pathname[128]; -}; - -struct acpi_integrity_info -{ - u32 nodes; - u32 objects; -}; - - -#define ACPI_DB_REDIRECTABLE_OUTPUT 0x01 -#define ACPI_DB_CONSOLE_OUTPUT 0x02 -#define ACPI_DB_DUPLICATE_OUTPUT 0x03 - - -/***************************************************************************** - * - * Debug - * - ****************************************************************************/ - -struct acpi_debug_print_info -{ - u32 component_id; - char *proc_name; - char *module_name; -}; - - -/* Entry for a memory allocation (debug only) */ - -#define ACPI_MEM_MALLOC 0 -#define ACPI_MEM_CALLOC 1 -#define ACPI_MAX_MODULE_NAME 16 - -#define ACPI_COMMON_DEBUG_MEM_HEADER \ - struct acpi_debug_mem_block *previous; \ - struct acpi_debug_mem_block *next; \ - u32 size; \ - u32 component; \ - u32 line; \ - char module[ACPI_MAX_MODULE_NAME]; \ - u8 alloc_type; - -struct acpi_debug_mem_header -{ - ACPI_COMMON_DEBUG_MEM_HEADER -}; - -struct acpi_debug_mem_block -{ - ACPI_COMMON_DEBUG_MEM_HEADER - u64 user_space; -}; - - -#define ACPI_MEM_LIST_GLOBAL 0 -#define ACPI_MEM_LIST_NSNODE 1 - -#define ACPI_MEM_LIST_FIRST_CACHE_LIST 2 -#define ACPI_MEM_LIST_STATE 2 -#define ACPI_MEM_LIST_PSNODE 3 -#define ACPI_MEM_LIST_PSNODE_EXT 4 -#define ACPI_MEM_LIST_OPERAND 5 -#define ACPI_MEM_LIST_WALK 6 -#define ACPI_MEM_LIST_MAX 6 -#define ACPI_NUM_MEM_LISTS 7 - - -struct acpi_memory_list -{ - void *list_head; - u16 link_offset; - u16 max_cache_depth; - u16 cache_depth; - u16 object_size; - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - - /* Statistics for debug memory tracking only */ - - u32 total_allocated; - u32 total_freed; - u32 current_total_size; - u32 cache_requests; - u32 cache_hits; - char *list_name; -#endif -}; - - -#endif /* __ACLOCAL_H__ */ diff -Nru a/drivers/acpi/include/acmacros.h b/drivers/acpi/include/acmacros.h --- a/drivers/acpi/include/acmacros.h Sun Feb 9 21:13:32 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,578 +0,0 @@ -/****************************************************************************** - * - * Name: acmacros.h - C macros for the entire subsystem. - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACMACROS_H__ -#define __ACMACROS_H__ - - -/* - * Data manipulation macros - */ - -#define ACPI_LOWORD(l) ((u16)(u32)(l)) -#define ACPI_HIWORD(l) ((u16)((((u32)(l)) >> 16) & 0xFFFF)) -#define ACPI_LOBYTE(l) ((u8)(u16)(l)) -#define ACPI_HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF)) - - -#if ACPI_MACHINE_WIDTH == 16 - -/* - * For 16-bit addresses, we have to assume that the upper 32 bits - * are zero. - */ -#define ACPI_LODWORD(l) ((u32)(l)) -#define ACPI_HIDWORD(l) ((u32)(0)) - -#define ACPI_GET_ADDRESS(a) ((a).lo) -#define ACPI_STORE_ADDRESS(a,b) {(a).hi=0;(a).lo=(u32)(b);} -#define ACPI_VALID_ADDRESS(a) ((a).hi | (a).lo) - -#else -#ifdef ACPI_NO_INTEGER64_SUPPORT -/* - * acpi_integer is 32-bits, no 64-bit support on this platform - */ -#define ACPI_LODWORD(l) ((u32)(l)) -#define ACPI_HIDWORD(l) ((u32)(0)) - -#define ACPI_GET_ADDRESS(a) (a) -#define ACPI_STORE_ADDRESS(a,b) ((a)=(b)) -#define ACPI_VALID_ADDRESS(a) (a) - -#else - -/* - * Full 64-bit address/integer on both 32-bit and 64-bit platforms - */ -#define ACPI_LODWORD(l) ((u32)(u64)(l)) -#define ACPI_HIDWORD(l) ((u32)(((*(struct uint64_struct *)(void *)(&l))).hi)) - -#define ACPI_GET_ADDRESS(a) (a) -#define ACPI_STORE_ADDRESS(a,b) ((a)=(acpi_physical_address)(b)) -#define ACPI_VALID_ADDRESS(a) (a) -#endif -#endif - - /* - * Extract a byte of data using a pointer. Any more than a byte and we - * get into potential aligment issues -- see the STORE macros below - */ -#define ACPI_GET8(addr) (*(u8*)(addr)) - -/* Pointer arithmetic */ - -#define ACPI_PTR_ADD(t,a,b) (t *) (void *)((char *)(a) + (acpi_native_uint)(b)) -#define ACPI_PTR_DIFF(a,b) (acpi_native_uint) ((char *)(a) - (char *)(b)) - -/* Pointer/Integer type conversions */ - -#define ACPI_TO_POINTER(i) ACPI_PTR_ADD (void, (void *) NULL,(acpi_native_uint)i) -#define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p,(void *) NULL) -#define ACPI_OFFSET(d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL) -#define ACPI_FADT_OFFSET(f) ACPI_OFFSET (FADT_DESCRIPTOR, f) - -#define ACPI_CAST_PTR(t, p) ((t *)(void *)(p)) -#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **)(void *)(p)) - -#if ACPI_MACHINE_WIDTH == 16 -#define ACPI_STORE_POINTER(d,s) ACPI_MOVE_UNALIGNED32_TO_32(d,s) -#define ACPI_PHYSADDR_TO_PTR(i) (void *)(i) -#define ACPI_PTR_TO_PHYSADDR(i) (u32) (char *)(i) -#else -#define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i) -#define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i) -#endif - -/* - * Macros for moving data around to/from buffers that are possibly unaligned. - * If the hardware supports the transfer of unaligned data, just do the store. - * Otherwise, we have to move one byte at a time. - */ - -#ifdef _HW_ALIGNMENT_SUPPORT - -/* The hardware supports unaligned transfers, just do the move */ - -#define ACPI_MOVE_UNALIGNED16_TO_16(d,s) *(u16 *)(void *)(d) = *(u16 *)(void *)(s) -#define ACPI_MOVE_UNALIGNED32_TO_32(d,s) *(u32 *)(void *)(d) = *(u32 *)(void *)(s) -#define ACPI_MOVE_UNALIGNED16_TO_32(d,s) *(u32 *)(void *)(d) = *(u16 *)(void *)(s) -#define ACPI_MOVE_UNALIGNED64_TO_64(d,s) *(u64 *)(void *)(d) = *(u64 *)(void *)(s) - -#else -/* - * The hardware does not support unaligned transfers. We must move the - * data one byte at a time. These macros work whether the source or - * the destination (or both) is/are unaligned. - */ - -#define ACPI_MOVE_UNALIGNED16_TO_16(d,s) {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ - ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];} - -#define ACPI_MOVE_UNALIGNED32_TO_32(d,s) {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ - ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\ - ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\ - ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];} - -#define ACPI_MOVE_UNALIGNED16_TO_32(d,s) {(*(u32*)(void *)(d)) = 0; ACPI_MOVE_UNALIGNED16_TO_16(d,s);} - -#define ACPI_MOVE_UNALIGNED64_TO_64(d,s) {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ - ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\ - ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\ - ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];\ - ((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[4];\ - ((u8 *)(void *)(d))[5] = ((u8 *)(void *)(s))[5];\ - ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[6];\ - ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[7];} - -#endif - - -/* - * Fast power-of-two math macros for non-optimized compilers - */ - -#define _ACPI_DIV(value,power_of2) ((u32) ((value) >> (power_of2))) -#define _ACPI_MUL(value,power_of2) ((u32) ((value) << (power_of2))) -#define _ACPI_MOD(value,divisor) ((u32) ((value) & ((divisor) -1))) - -#define ACPI_DIV_2(a) _ACPI_DIV(a,1) -#define ACPI_MUL_2(a) _ACPI_MUL(a,1) -#define ACPI_MOD_2(a) _ACPI_MOD(a,2) - -#define ACPI_DIV_4(a) _ACPI_DIV(a,2) -#define ACPI_MUL_4(a) _ACPI_MUL(a,2) -#define ACPI_MOD_4(a) _ACPI_MOD(a,4) - -#define ACPI_DIV_8(a) _ACPI_DIV(a,3) -#define ACPI_MUL_8(a) _ACPI_MUL(a,3) -#define ACPI_MOD_8(a) _ACPI_MOD(a,8) - -#define ACPI_DIV_16(a) _ACPI_DIV(a,4) -#define ACPI_MUL_16(a) _ACPI_MUL(a,4) -#define ACPI_MOD_16(a) _ACPI_MOD(a,16) - - -/* - * Rounding macros (Power of two boundaries only) - */ -#define ACPI_ROUND_DOWN(value,boundary) (((acpi_native_uint)(value)) & (~(((acpi_native_uint) boundary)-1))) -#define ACPI_ROUND_UP(value,boundary) ((((acpi_native_uint)(value)) + (((acpi_native_uint) boundary)-1)) & (~(((acpi_native_uint) boundary)-1))) - -#define ACPI_ROUND_DOWN_TO_32_BITS(a) ACPI_ROUND_DOWN(a,4) -#define ACPI_ROUND_DOWN_TO_64_BITS(a) ACPI_ROUND_DOWN(a,8) -#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a) ACPI_ROUND_DOWN(a,ALIGNED_ADDRESS_BOUNDARY) - -#define ACPI_ROUND_UP_to_32_bITS(a) ACPI_ROUND_UP(a,4) -#define ACPI_ROUND_UP_to_64_bITS(a) ACPI_ROUND_UP(a,8) -#define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY) - - -#define ACPI_ROUND_BITS_UP_TO_BYTES(a) ACPI_DIV_8((a) + 7) -#define ACPI_ROUND_BITS_DOWN_TO_BYTES(a) ACPI_DIV_8((a)) - -#define ACPI_ROUND_UP_TO_1K(a) (((a) + 1023) >> 10) - -/* Generic (non-power-of-two) rounding */ - -#define ACPI_ROUND_UP_TO(value,boundary) (((value) + ((boundary)-1)) / (boundary)) - -/* - * Bitmask creation - * Bit positions start at zero. - * MASK_BITS_ABOVE creates a mask starting AT the position and above - * MASK_BITS_BELOW creates a mask starting one bit BELOW the position - */ -#define ACPI_MASK_BITS_ABOVE(position) (~((ACPI_INTEGER_MAX) << ((u32) (position)))) -#define ACPI_MASK_BITS_BELOW(position) ((ACPI_INTEGER_MAX) << ((u32) (position))) - -#define ACPI_IS_OCTAL_DIGIT(d) (((char)(d) >= '0') && ((char)(d) <= '7')) - -/* Macros for GAS addressing */ - -#if ACPI_MACHINE_WIDTH != 16 - -#define ACPI_PCI_DEVICE_MASK (u64) 0x0000FFFF00000000 -#define ACPI_PCI_FUNCTION_MASK (u64) 0x00000000FFFF0000 -#define ACPI_PCI_REGISTER_MASK (u64) 0x000000000000FFFF - -/* - * Obsolete - */ - -/* -#define ACPI_PCI_FUNCTION(a) (u16) ((((u64)((u64)(a) & ACPI_PCI_FUNCTION_MASK)) >> 16)) -#define ACPI_PCI_DEVICE(a) (u16) ((((u64)((u64)(a) & ACPI_PCI_DEVICE_MASK)) >> 32)) -#define ACPI_PCI_REGISTER(a) (u16) (((u64)((u64)(a) & ACPI_PCI_REGISTER_MASK))) -*/ - - -#define ACPI_PCI_DEVICE(a) (u16) ((ACPI_HIDWORD ((a))) & 0x0000FFFF) -#define ACPI_PCI_FUNCTION(a) (u16) ((ACPI_LODWORD ((a))) >> 16) -#define ACPI_PCI_REGISTER(a) (u16) ((ACPI_LODWORD ((a))) & 0x0000FFFF) - -#else - -/* No support for GAS and PCI IDs in 16-bit mode */ - -#define ACPI_PCI_FUNCTION(a) (u16) ((a) & 0xFFFF0000) -#define ACPI_PCI_DEVICE(a) (u16) ((a) & 0x0000FFFF) -#define ACPI_PCI_REGISTER(a) (u16) ((a) & 0x0000FFFF) - -#endif - - -/* Bitfields within ACPI registers */ - -#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) ((val << pos) & mask) -#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask) - -/* - * An struct acpi_namespace_node * can appear in some contexts, - * where a pointer to an union acpi_operand_object can also - * appear. This macro is used to distinguish them. - * - * The "Descriptor" field is the first field in both structures. - */ -#define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->descriptor_id) -#define ACPI_SET_DESCRIPTOR_TYPE(d,t) (((union acpi_descriptor *)(void *)(d))->descriptor_id = t) - - -/* Macro to test the object type */ - -#define ACPI_GET_OBJECT_TYPE(d) (((union acpi_operand_object *)(void *)(d))->common.type) - -/* Macro to check the table flags for SINGLE or MULTIPLE tables are allowed */ - -#define ACPI_IS_SINGLE_TABLE(x) (((x) & 0x01) == ACPI_TABLE_SINGLE ? 1 : 0) - -/* - * Macros for the master AML opcode table - */ -#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT) -#define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags) {name,(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type} -#else -#define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags) {(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type} -#endif - -#ifdef ACPI_DISASSEMBLER -#define ACPI_DISASM_ONLY_MEMBERS(a) a; -#else -#define ACPI_DISASM_ONLY_MEMBERS(a) -#endif - -#define ARG_TYPE_WIDTH 5 -#define ARG_1(x) ((u32)(x)) -#define ARG_2(x) ((u32)(x) << (1 * ARG_TYPE_WIDTH)) -#define ARG_3(x) ((u32)(x) << (2 * ARG_TYPE_WIDTH)) -#define ARG_4(x) ((u32)(x) << (3 * ARG_TYPE_WIDTH)) -#define ARG_5(x) ((u32)(x) << (4 * ARG_TYPE_WIDTH)) -#define ARG_6(x) ((u32)(x) << (5 * ARG_TYPE_WIDTH)) - -#define ARGI_LIST1(a) (ARG_1(a)) -#define ARGI_LIST2(a,b) (ARG_1(b)|ARG_2(a)) -#define ARGI_LIST3(a,b,c) (ARG_1(c)|ARG_2(b)|ARG_3(a)) -#define ARGI_LIST4(a,b,c,d) (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a)) -#define ARGI_LIST5(a,b,c,d,e) (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a)) -#define ARGI_LIST6(a,b,c,d,e,f) (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a)) - -#define ARGP_LIST1(a) (ARG_1(a)) -#define ARGP_LIST2(a,b) (ARG_1(a)|ARG_2(b)) -#define ARGP_LIST3(a,b,c) (ARG_1(a)|ARG_2(b)|ARG_3(c)) -#define ARGP_LIST4(a,b,c,d) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)) -#define ARGP_LIST5(a,b,c,d,e) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)) -#define ARGP_LIST6(a,b,c,d,e,f) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f)) - -#define GET_CURRENT_ARG_TYPE(list) (list & ((u32) 0x1F)) -#define INCREMENT_ARG_LIST(list) (list >>= ((u32) ARG_TYPE_WIDTH)) - - -/* - * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions) - * - * 1) Address space - * 2) Length in bytes -- convert to length in bits - * 3) Bit offset is zero - * 4) Reserved field is zero - * 5) Expand address to 64 bits - */ -#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d) do {a.address_space_id = (u8) d;\ - a.register_bit_width = (u8) ACPI_MUL_8 (b);\ - a.register_bit_offset = 0;\ - a.reserved = 0;\ - ACPI_STORE_ADDRESS (a.address,(acpi_physical_address) c);} while (0) - -/* ACPI V1.0 entries -- address space is always I/O */ - -#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c) ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ACPI_ADR_SPACE_SYSTEM_IO) - - -/* - * Reporting macros that are never compiled out - */ - -#define ACPI_PARAM_LIST(pl) pl - -/* - * Error reporting. These versions add callers module and line#. Since - * _THIS_MODULE gets compiled out when ACPI_DEBUG_OUTPUT isn't defined, only - * use it in debug mode. - */ - -#ifdef ACPI_DEBUG_OUTPUT - -#define ACPI_REPORT_INFO(fp) {acpi_ut_report_info(_THIS_MODULE,__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_ERROR(fp) {acpi_ut_report_error(_THIS_MODULE,__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_WARNING(fp) {acpi_ut_report_warning(_THIS_MODULE,__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_NSERROR(s,e) acpi_ns_report_error(_THIS_MODULE,__LINE__,_COMPONENT, s, e); - -#define ACPI_REPORT_METHOD_ERROR(s,n,p,e) acpi_ns_report_method_error(_THIS_MODULE,__LINE__,_COMPONENT, s, n, p, e); - -#else - -#define ACPI_REPORT_INFO(fp) {acpi_ut_report_info("ACPI",__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_ERROR(fp) {acpi_ut_report_error("ACPI",__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_WARNING(fp) {acpi_ut_report_warning("ACPI",__LINE__,_COMPONENT); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define ACPI_REPORT_NSERROR(s,e) acpi_ns_report_error("ACPI",__LINE__,_COMPONENT, s, e); - -#define ACPI_REPORT_METHOD_ERROR(s,n,p,e) acpi_ns_report_method_error("ACPI",__LINE__,_COMPONENT, s, n, p, e); - -#endif - -/* Error reporting. These versions pass thru the module and line# */ - -#define _ACPI_REPORT_INFO(a,b,c,fp) {acpi_ut_report_info(a,b,c); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define _ACPI_REPORT_ERROR(a,b,c,fp) {acpi_ut_report_error(a,b,c); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} -#define _ACPI_REPORT_WARNING(a,b,c,fp) {acpi_ut_report_warning(a,b,c); \ - acpi_os_printf ACPI_PARAM_LIST(fp);} - -/* - * Debug macros that are conditionally compiled - */ - -#ifdef ACPI_DEBUG_OUTPUT - -#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR *_THIS_MODULE = name; - -/* - * Function entry tracing. - * The first parameter should be the procedure name as a quoted string. This is declared - * as a local string ("_proc_name) so that it can be also used by the function exit macros below. - */ - -#define ACPI_FUNCTION_NAME(a) struct acpi_debug_print_info _dbg; \ - _dbg.component_id = _COMPONENT; \ - _dbg.proc_name = a; \ - _dbg.module_name = _THIS_MODULE; - -#define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a)\ - acpi_ut_trace(__LINE__,&_dbg) -#define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a)\ - acpi_ut_trace_ptr(__LINE__,&_dbg,(void *)b) -#define ACPI_FUNCTION_TRACE_U32(a,b) ACPI_FUNCTION_NAME(a)\ - acpi_ut_trace_u32(__LINE__,&_dbg,(u32)b) -#define ACPI_FUNCTION_TRACE_STR(a,b) ACPI_FUNCTION_NAME(a)\ - acpi_ut_trace_str(__LINE__,&_dbg,(char *)b) - -#define ACPI_FUNCTION_ENTRY() acpi_ut_track_stack_ptr() - -/* - * Function exit tracing. - * WARNING: These macros include a return statement. This is usually considered - * bad form, but having a separate exit macro is very ugly and difficult to maintain. - * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros - * so that "_proc_name" is defined. - */ -#ifdef ACPI_USE_DO_WHILE_0 -#define ACPI_DO_WHILE0(a) do a while(0) -#else -#define ACPI_DO_WHILE0(a) a -#endif - -#define return_VOID ACPI_DO_WHILE0 ({acpi_ut_exit(__LINE__,&_dbg);return;}) -#define return_ACPI_STATUS(s) ACPI_DO_WHILE0 ({acpi_ut_status_exit(__LINE__,&_dbg,(s));return((s));}) -#define return_VALUE(s) ACPI_DO_WHILE0 ({acpi_ut_value_exit(__LINE__,&_dbg,(acpi_integer)(s));return((s));}) -#define return_PTR(s) ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(__LINE__,&_dbg,(u8 *)(s));return((s));}) - -/* Conditional execution */ - -#define ACPI_DEBUG_EXEC(a) a -#define ACPI_NORMAL_EXEC(a) - -#define ACPI_DEBUG_DEFINE(a) a; -#define ACPI_DEBUG_ONLY_MEMBERS(a) a; -#define _VERBOSE_STRUCTURES - - -/* Stack and buffer dumping */ - -#define ACPI_DUMP_STACK_ENTRY(a) acpi_ex_dump_operand(a) -#define ACPI_DUMP_OPERANDS(a,b,c,d,e) acpi_ex_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__) - - -#define ACPI_DUMP_ENTRY(a,b) acpi_ns_dump_entry (a,b) -#define ACPI_DUMP_TABLES(a,b) acpi_ns_dump_tables(a,b) -#define ACPI_DUMP_PATHNAME(a,b,c,d) acpi_ns_dump_pathname(a,b,c,d) -#define ACPI_DUMP_RESOURCE_LIST(a) acpi_rs_dump_resource_list(a) -#define ACPI_DUMP_BUFFER(a,b) acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT) -#define ACPI_BREAK_MSG(a) acpi_os_signal (ACPI_SIGNAL_BREAKPOINT,(a)) - - -/* - * Generate INT3 on ACPI_ERROR (Debug only!) - */ - -#define ACPI_ERROR_BREAK -#ifdef ACPI_ERROR_BREAK -#define ACPI_BREAK_ON_ERROR(lvl) if ((lvl)&ACPI_ERROR) \ - acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,"Fatal error encountered\n") -#else -#define ACPI_BREAK_ON_ERROR(lvl) -#endif - -/* - * Master debug print macros - * Print iff: - * 1) Debug print for the current component is enabled - * 2) Debug error level or trace level for the print statement is enabled - */ - -#define ACPI_DEBUG_PRINT(pl) acpi_ut_debug_print ACPI_PARAM_LIST(pl) -#define ACPI_DEBUG_PRINT_RAW(pl) acpi_ut_debug_print_raw ACPI_PARAM_LIST(pl) - - -#else -/* - * This is the non-debug case -- make everything go away, - * leaving no executable debug code! - */ - -#define ACPI_MODULE_NAME(name) -#define _THIS_MODULE "" - -#define ACPI_DEBUG_EXEC(a) -#define ACPI_NORMAL_EXEC(a) a; - -#define ACPI_DEBUG_DEFINE(a) -#define ACPI_DEBUG_ONLY_MEMBERS(a) -#define ACPI_FUNCTION_NAME(a) -#define ACPI_FUNCTION_TRACE(a) -#define ACPI_FUNCTION_TRACE_PTR(a,b) -#define ACPI_FUNCTION_TRACE_U32(a,b) -#define ACPI_FUNCTION_TRACE_STR(a,b) -#define ACPI_FUNCTION_EXIT -#define ACPI_FUNCTION_STATUS_EXIT(s) -#define ACPI_FUNCTION_VALUE_EXIT(s) -#define ACPI_FUNCTION_ENTRY() -#define ACPI_DUMP_STACK_ENTRY(a) -#define ACPI_DUMP_OPERANDS(a,b,c,d,e) -#define ACPI_DUMP_ENTRY(a,b) -#define ACPI_DUMP_TABLES(a,b) -#define ACPI_DUMP_PATHNAME(a,b,c,d) -#define ACPI_DUMP_RESOURCE_LIST(a) -#define ACPI_DUMP_BUFFER(a,b) -#define ACPI_DEBUG_PRINT(pl) -#define ACPI_DEBUG_PRINT_RAW(pl) -#define ACPI_BREAK_MSG(a) - -#define return_VOID return -#define return_ACPI_STATUS(s) return(s) -#define return_VALUE(s) return(s) -#define return_PTR(s) return(s) - -#endif - -/* - * Some code only gets executed when the debugger is built in. - * Note that this is entirely independent of whether the - * DEBUG_PRINT stuff (set by ACPI_DEBUG_OUTPUT) is on, or not. - */ -#ifdef ACPI_DEBUGGER -#define ACPI_DEBUGGER_EXEC(a) a -#else -#define ACPI_DEBUGGER_EXEC(a) -#endif - - -/* - * For 16-bit code, we want to shrink some things even though - * we are using ACPI_DEBUG_OUTPUT to get the debug output - */ -#if ACPI_MACHINE_WIDTH == 16 -#undef ACPI_DEBUG_ONLY_MEMBERS -#undef _VERBOSE_STRUCTURES -#define ACPI_DEBUG_ONLY_MEMBERS(a) -#endif - - -#ifdef ACPI_DEBUG_OUTPUT -/* - * 1) Set name to blanks - * 2) Copy the object name - */ -#define ACPI_ADD_OBJECT_NAME(a,b) ACPI_MEMSET (a->common.name, ' ', sizeof (a->common.name));\ - ACPI_STRNCPY (a->common.name, acpi_gbl_ns_type_names[b], sizeof (a->common.name)) -#else - -#define ACPI_ADD_OBJECT_NAME(a,b) -#endif - - -/* - * Memory allocation tracking (DEBUG ONLY) - */ - -#ifndef ACPI_DBG_TRACK_ALLOCATIONS - -/* Memory allocation */ - -#define ACPI_MEM_ALLOCATE(a) acpi_ut_allocate((acpi_size)(a),_COMPONENT,_THIS_MODULE,__LINE__) -#define ACPI_MEM_CALLOCATE(a) acpi_ut_callocate((acpi_size)(a), _COMPONENT,_THIS_MODULE,__LINE__) -#define ACPI_MEM_FREE(a) acpi_os_free(a) -#define ACPI_MEM_TRACKING(a) - - -#else - -/* Memory allocation */ - -#define ACPI_MEM_ALLOCATE(a) acpi_ut_allocate_and_track((acpi_size)(a),_COMPONENT,_THIS_MODULE,__LINE__) -#define ACPI_MEM_CALLOCATE(a) acpi_ut_callocate_and_track((acpi_size)(a), _COMPONENT,_THIS_MODULE,__LINE__) -#define ACPI_MEM_FREE(a) acpi_ut_free_and_track(a,_COMPONENT,_THIS_MODULE,__LINE__) -#define ACPI_MEM_TRACKING(a) a - -#endif /* ACPI_DBG_TRACK_ALLOCATIONS */ - - -#define ACPI_GET_STACK_POINTER _asm {mov eax, ebx} - -#endif /* ACMACROS_H */ diff -Nru a/drivers/acpi/include/acnamesp.h b/drivers/acpi/include/acnamesp.h --- a/drivers/acpi/include/acnamesp.h Sun Feb 9 21:13:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,489 +0,0 @@ -/****************************************************************************** - * - * Name: acnamesp.h - Namespace subcomponent prototypes and defines - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACNAMESP_H__ -#define __ACNAMESP_H__ - - -/* To search the entire name space, pass this as search_base */ - -#define ACPI_NS_ALL ((acpi_handle)0) - -/* - * Elements of acpi_ns_properties are bit significant - * and should be one-to-one with values of acpi_object_type - */ -#define ACPI_NS_NORMAL 0 -#define ACPI_NS_NEWSCOPE 1 /* a definition of this type opens a name scope */ -#define ACPI_NS_LOCAL 2 /* suppress search of enclosing scopes */ - - -/* Definitions of the predefined namespace names */ - -#define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */ -#define ACPI_ROOT_NAME (u32) 0x5F5F5F5C /* Root name is "\___" */ -#define ACPI_SYS_BUS_NAME (u32) 0x5F53425F /* Sys bus name is "_SB_" */ - -#define ACPI_NS_ROOT_PATH "\\" -#define ACPI_NS_SYSTEM_BUS "_SB_" - - -/* Flags for acpi_ns_lookup, acpi_ns_search_and_enter */ - -#define ACPI_NS_NO_UPSEARCH 0 -#define ACPI_NS_SEARCH_PARENT 0x01 -#define ACPI_NS_DONT_OPEN_SCOPE 0x02 -#define ACPI_NS_NO_PEER_SEARCH 0x04 -#define ACPI_NS_ERROR_IF_FOUND 0x08 - -#define ACPI_NS_WALK_UNLOCK TRUE -#define ACPI_NS_WALK_NO_UNLOCK FALSE - - -acpi_status -acpi_ns_load_namespace ( - void); - -acpi_status -acpi_ns_initialize_objects ( - void); - -acpi_status -acpi_ns_initialize_devices ( - void); - - -/* Namespace init - nsxfinit */ - -acpi_status -acpi_ns_init_one_device ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value); - -acpi_status -acpi_ns_init_one_object ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value); - - -acpi_status -acpi_ns_walk_namespace ( - acpi_object_type type, - acpi_handle start_object, - u32 max_depth, - u8 unlock_before_callback, - acpi_walk_callback user_function, - void *context, - void **return_value); - -struct acpi_namespace_node * -acpi_ns_get_next_node ( - acpi_object_type type, - struct acpi_namespace_node *parent, - struct acpi_namespace_node *child); - -void -acpi_ns_delete_namespace_by_owner ( - u16 table_id); - - -/* Namespace loading - nsload */ - -acpi_status -acpi_ns_one_complete_parse ( - u32 pass_number, - struct acpi_table_desc *table_desc); - -acpi_status -acpi_ns_parse_table ( - struct acpi_table_desc *table_desc, - struct acpi_namespace_node *scope); - -acpi_status -acpi_ns_load_table ( - struct acpi_table_desc *table_desc, - struct acpi_namespace_node *node); - -acpi_status -acpi_ns_load_table_by_type ( - acpi_table_type table_type); - - -/* - * Top-level namespace access - nsaccess - */ - -acpi_status -acpi_ns_root_initialize ( - void); - -acpi_status -acpi_ns_lookup ( - union acpi_generic_state *scope_info, - char *name, - acpi_object_type type, - acpi_interpreter_mode interpreter_mode, - u32 flags, - struct acpi_walk_state *walk_state, - struct acpi_namespace_node **ret_node); - - -/* - * Named object allocation/deallocation - nsalloc - */ - -struct acpi_namespace_node * -acpi_ns_create_node ( - u32 name); - -void -acpi_ns_delete_node ( - struct acpi_namespace_node *node); - -void -acpi_ns_delete_namespace_subtree ( - struct acpi_namespace_node *parent_handle); - -void -acpi_ns_detach_object ( - struct acpi_namespace_node *node); - -void -acpi_ns_delete_children ( - struct acpi_namespace_node *parent); - -int -acpi_ns_compare_names ( - char *name1, - char *name2); - -/* - * Namespace modification - nsmodify - */ - -acpi_status -acpi_ns_unload_namespace ( - acpi_handle handle); - -acpi_status -acpi_ns_delete_subtree ( - acpi_handle start_handle); - - -/* - * Namespace dump/print utilities - nsdump - */ - -void -acpi_ns_dump_tables ( - acpi_handle search_base, - u32 max_depth); - -void -acpi_ns_dump_entry ( - acpi_handle handle, - u32 debug_level); - -void -acpi_ns_dump_pathname ( - acpi_handle handle, - char *msg, - u32 level, - u32 component); - -void -acpi_ns_print_pathname ( - u32 num_segments, - char *pathname); - -acpi_status -acpi_ns_dump_one_device ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value); - -void -acpi_ns_dump_root_devices ( - void); - -acpi_status -acpi_ns_dump_one_object ( - acpi_handle obj_handle, - u32 level, - void *context, - void **return_value); - -void -acpi_ns_dump_objects ( - acpi_object_type type, - u8 display_type, - u32 max_depth, - u32 ownder_id, - acpi_handle start_handle); - - -/* - * Namespace evaluation functions - nseval - */ - -acpi_status -acpi_ns_evaluate_by_handle ( - struct acpi_namespace_node *prefix_node, - union acpi_operand_object **params, - union acpi_operand_object **return_object); - -acpi_status -acpi_ns_evaluate_by_name ( - char *pathname, - union acpi_operand_object **params, - union acpi_operand_object **return_object); - -acpi_status -acpi_ns_evaluate_relative ( - struct acpi_namespace_node *prefix_node, - char *pathname, - union acpi_operand_object **params, - union acpi_operand_object **return_object); - -acpi_status -acpi_ns_execute_control_method ( - struct acpi_namespace_node *method_node, - union acpi_operand_object **params, - union acpi_operand_object **return_obj_desc); - -acpi_status -acpi_ns_get_object_value ( - struct acpi_namespace_node *object_node, - union acpi_operand_object **return_obj_desc); - - -/* - * Parent/Child/Peer utility functions - */ - -acpi_name -acpi_ns_find_parent_name ( - struct acpi_namespace_node *node_to_search); - - -/* - * Name and Scope manipulation - nsnames - */ - -u32 -acpi_ns_opens_scope ( - acpi_object_type type); - -void -acpi_ns_build_external_path ( - struct acpi_namespace_node *node, - acpi_size size, - char *name_buffer); - -char * -acpi_ns_get_external_pathname ( - struct acpi_namespace_node *node); - -char * -acpi_ns_name_of_current_scope ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ns_handle_to_pathname ( - acpi_handle target_handle, - struct acpi_buffer *buffer); - -u8 -acpi_ns_pattern_match ( - struct acpi_namespace_node *obj_node, - char *search_for); - -acpi_status -acpi_ns_get_node_by_path ( - char *external_pathname, - struct acpi_namespace_node *in_prefix_node, - u32 flags, - struct acpi_namespace_node **out_node); - -acpi_size -acpi_ns_get_pathname_length ( - struct acpi_namespace_node *node); - - -/* - * Object management for namespace nodes - nsobject - */ - -acpi_status -acpi_ns_attach_object ( - struct acpi_namespace_node *node, - union acpi_operand_object *object, - acpi_object_type type); - -union acpi_operand_object * -acpi_ns_get_attached_object ( - struct acpi_namespace_node *node); - -union acpi_operand_object * -acpi_ns_get_secondary_object ( - union acpi_operand_object *obj_desc); - -acpi_status -acpi_ns_attach_data ( - struct acpi_namespace_node *node, - acpi_object_handler handler, - void *data); - -acpi_status -acpi_ns_detach_data ( - struct acpi_namespace_node *node, - acpi_object_handler handler); - -acpi_status -acpi_ns_get_attached_data ( - struct acpi_namespace_node *node, - acpi_object_handler handler, - void **data); - - -/* - * Namespace searching and entry - nssearch - */ - -acpi_status -acpi_ns_search_and_enter ( - u32 entry_name, - struct acpi_walk_state *walk_state, - struct acpi_namespace_node *node, - acpi_interpreter_mode interpreter_mode, - acpi_object_type type, - u32 flags, - struct acpi_namespace_node **ret_node); - -acpi_status -acpi_ns_search_node ( - u32 entry_name, - struct acpi_namespace_node *node, - acpi_object_type type, - struct acpi_namespace_node **ret_node); - -void -acpi_ns_install_node ( - struct acpi_walk_state *walk_state, - struct acpi_namespace_node *parent_node, - struct acpi_namespace_node *node, - acpi_object_type type); - - -/* - * Utility functions - nsutils - */ - -u8 -acpi_ns_valid_root_prefix ( - char prefix); - -u8 -acpi_ns_valid_path_separator ( - char sep); - -acpi_object_type -acpi_ns_get_type ( - struct acpi_namespace_node *node); - -u32 -acpi_ns_local ( - acpi_object_type type); - -void -acpi_ns_report_error ( - char *module_name, - u32 line_number, - u32 component_id, - char *internal_name, - acpi_status lookup_status); - -void -acpi_ns_report_method_error ( - char *module_name, - u32 line_number, - u32 component_id, - char *message, - struct acpi_namespace_node *node, - char *path, - acpi_status lookup_status); - -void -acpi_ns_print_node_pathname ( - struct acpi_namespace_node *node, - char *msg); - -acpi_status -acpi_ns_build_internal_name ( - struct acpi_namestring_info *info); - -void -acpi_ns_get_internal_name_length ( - struct acpi_namestring_info *info); - -acpi_status -acpi_ns_internalize_name ( - char *dotted_name, - char **converted_name); - -acpi_status -acpi_ns_externalize_name ( - u32 internal_name_length, - char *internal_name, - u32 *converted_name_length, - char **converted_name); - -struct acpi_namespace_node * -acpi_ns_map_handle_to_node ( - acpi_handle handle); - -acpi_handle -acpi_ns_convert_entry_to_handle( - struct acpi_namespace_node *node); - -void -acpi_ns_terminate ( - void); - -struct acpi_namespace_node * -acpi_ns_get_parent_node ( - struct acpi_namespace_node *node); - - -struct acpi_namespace_node * -acpi_ns_get_next_valid_node ( - struct acpi_namespace_node *node); - - -#endif /* __ACNAMESP_H__ */ diff -Nru a/drivers/acpi/include/acobject.h b/drivers/acpi/include/acobject.h --- a/drivers/acpi/include/acobject.h Sun Feb 9 21:13:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,473 +0,0 @@ - -/****************************************************************************** - * - * Name: acobject.h - Definition of union acpi_operand_object (Internal object only) - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef _ACOBJECT_H -#define _ACOBJECT_H - - -/* - * The union acpi_operand_object is used to pass AML operands from the dispatcher - * to the interpreter, and to keep track of the various handlers such as - * address space handlers and notify handlers. The object is a constant - * size in order to allow it to be cached and reused. - */ - -/******************************************************************************* - * - * Common Descriptors - * - ******************************************************************************/ - -/* - * Common area for all objects. - * - * data_type is used to differentiate between internal descriptors, and MUST - * be the first byte in this structure. - */ -#define ACPI_OBJECT_COMMON_HEADER /* SIZE/ALIGNMENT: 32 bits, one ptr plus trailing 8-bit flag */\ - u8 descriptor; /* To differentiate various internal objs */\ - u8 type; /* acpi_object_type */\ - u16 reference_count; /* For object deletion management */\ - union acpi_operand_object *next_object; /* Objects linked to parent NS node */\ - u8 flags; \ - -/* Values for flag byte above */ - -#define AOPOBJ_AML_CONSTANT 0x01 -#define AOPOBJ_STATIC_POINTER 0x02 -#define AOPOBJ_DATA_VALID 0x04 -#define AOPOBJ_OBJECT_INITIALIZED 0x08 -#define AOPOBJ_SETUP_COMPLETE 0x10 -#define AOPOBJ_SINGLE_DATUM 0x20 - - -/* - * Common bitfield for the field objects - * "Field Datum" -- a datum from the actual field object - * "Buffer Datum" -- a datum from a user buffer, read from or to be written to the field - */ -#define ACPI_COMMON_FIELD_INFO /* SIZE/ALIGNMENT: 24 bits + three 32-bit values */\ - u8 field_flags; /* Access, update, and lock bits */\ - u8 attribute; /* From access_as keyword */\ - u8 access_byte_width; /* Read/Write size in bytes */\ - u32 bit_length; /* Length of field in bits */\ - u32 base_byte_offset; /* Byte offset within containing object */\ - u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\ - u8 datum_valid_bits; /* Valid bit in first "Field datum" */\ - u8 end_field_valid_bits; /* Valid bits in the last "field datum" */\ - u8 end_buffer_valid_bits; /* Valid bits in the last "buffer datum" */\ - u32 value; /* Value to store into the Bank or Index register */\ - struct acpi_namespace_node *node; /* Link back to parent node */ - - -/* - * Fields common to both Strings and Buffers - */ -#define ACPI_COMMON_BUFFER_INFO \ - u32 length; - - -/* - * Common fields for objects that support ASL notifications - */ -#define ACPI_COMMON_NOTIFY_INFO \ - union acpi_operand_object *sys_handler; /* Handler for system notifies */\ - union acpi_operand_object *drv_handler; /* Handler for driver notifies */\ - union acpi_operand_object *addr_handler; /* Handler for Address space */ - - -/****************************************************************************** - * - * Basic data types - * - *****************************************************************************/ - -struct acpi_object_common -{ - ACPI_OBJECT_COMMON_HEADER -}; - - -struct acpi_object_integer -{ - ACPI_OBJECT_COMMON_HEADER - acpi_integer value; -}; - - -struct acpi_object_string /* Null terminated, ASCII characters only */ -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_BUFFER_INFO - char *pointer; /* String in AML stream or allocated string */ -}; - - -struct acpi_object_buffer -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_BUFFER_INFO - u8 *pointer; /* Buffer in AML stream or allocated buffer */ - struct acpi_namespace_node *node; /* Link back to parent node */ - u8 *aml_start; - u32 aml_length; -}; - - -struct acpi_object_package -{ - ACPI_OBJECT_COMMON_HEADER - - u32 count; /* # of elements in package */ - u32 aml_length; - u8 *aml_start; - struct acpi_namespace_node *node; /* Link back to parent node */ - union acpi_operand_object **elements; /* Array of pointers to acpi_objects */ -}; - - -/****************************************************************************** - * - * Complex data types - * - *****************************************************************************/ - -struct acpi_object_event -{ - ACPI_OBJECT_COMMON_HEADER - void *semaphore; -}; - - -#define INFINITE_CONCURRENCY 0xFF - -struct acpi_object_method -{ - ACPI_OBJECT_COMMON_HEADER - u8 method_flags; - u8 param_count; - u32 aml_length; - void *semaphore; - u8 *aml_start; - u8 concurrency; - u8 thread_count; - acpi_owner_id owning_id; -}; - - -struct acpi_object_mutex -{ - ACPI_OBJECT_COMMON_HEADER - u16 sync_level; - u16 acquisition_depth; - struct acpi_thread_state *owner_thread; - void *semaphore; - union acpi_operand_object *prev; /* Link for list of acquired mutexes */ - union acpi_operand_object *next; /* Link for list of acquired mutexes */ - struct acpi_namespace_node *node; /* containing object */ -}; - - -struct acpi_object_region -{ - ACPI_OBJECT_COMMON_HEADER - - u8 space_id; - union acpi_operand_object *addr_handler; /* Handler for system notifies */ - struct acpi_namespace_node *node; /* containing object */ - union acpi_operand_object *next; - u32 length; - acpi_physical_address address; -}; - - -/****************************************************************************** - * - * Objects that can be notified. All share a common notify_info area. - * - *****************************************************************************/ - -struct acpi_object_notify_common /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */ -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_NOTIFY_INFO -}; - - -struct acpi_object_device -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_NOTIFY_INFO -}; - - -struct acpi_object_power_resource -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_NOTIFY_INFO - u32 system_level; - u32 resource_order; -}; - - -struct acpi_object_processor -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_NOTIFY_INFO - u32 proc_id; - u32 length; - acpi_io_address address; -}; - - -struct acpi_object_thermal_zone -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_NOTIFY_INFO -}; - - -/****************************************************************************** - * - * Fields. All share a common header/info field. - * - *****************************************************************************/ - -struct acpi_object_field_common /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */ -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_FIELD_INFO - union acpi_operand_object *region_obj; /* Containing Operation Region object */ - /* (REGION/BANK fields only) */ -}; - - -struct acpi_object_region_field -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_FIELD_INFO - union acpi_operand_object *region_obj; /* Containing op_region object */ -}; - - -struct acpi_object_bank_field -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_FIELD_INFO - union acpi_operand_object *region_obj; /* Containing op_region object */ - union acpi_operand_object *bank_obj; /* bank_select Register object */ -}; - - -struct acpi_object_index_field -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_FIELD_INFO - - /* - * No "region_obj" pointer needed since the Index and Data registers - * are each field definitions unto themselves. - */ - union acpi_operand_object *index_obj; /* Index register */ - union acpi_operand_object *data_obj; /* Data register */ -}; - - -/* The buffer_field is different in that it is part of a Buffer, not an op_region */ - -struct acpi_object_buffer_field -{ - ACPI_OBJECT_COMMON_HEADER - ACPI_COMMON_FIELD_INFO - union acpi_operand_object *buffer_obj; /* Containing Buffer object */ -}; - - -/****************************************************************************** - * - * Objects for handlers - * - *****************************************************************************/ - -struct acpi_object_notify_handler -{ - ACPI_OBJECT_COMMON_HEADER - struct acpi_namespace_node *node; /* Parent device */ - acpi_notify_handler handler; - void *context; -}; - - -/* Flags for address handler */ - -#define ACPI_ADDR_HANDLER_DEFAULT_INSTALLED 0x1 - - -struct acpi_object_addr_handler -{ - ACPI_OBJECT_COMMON_HEADER - u8 space_id; - u16 hflags; - acpi_adr_space_handler handler; - struct acpi_namespace_node *node; /* Parent device */ - void *context; - acpi_adr_space_setup setup; - union acpi_operand_object *region_list; /* regions using this handler */ - union acpi_operand_object *next; -}; - - -/****************************************************************************** - * - * Special internal objects - * - *****************************************************************************/ - -/* - * The Reference object type is used for these opcodes: - * Arg[0-6], Local[0-7], index_op, name_op, zero_op, one_op, ones_op, debug_op - */ -struct acpi_object_reference -{ - ACPI_OBJECT_COMMON_HEADER - u8 target_type; /* Used for index_op */ - u16 opcode; - u32 offset; /* Used for arg_op, local_op, and index_op */ - void *object; /* name_op=>HANDLE to obj, index_op=>union acpi_operand_object */ - struct acpi_namespace_node *node; - union acpi_operand_object **where; -}; - - -/* - * Extra object is used as additional storage for types that - * have AML code in their declarations (term_args) that must be - * evaluated at run time. - * - * Currently: Region and field_unit types - */ -struct acpi_object_extra -{ - ACPI_OBJECT_COMMON_HEADER - u8 byte_fill1; - u16 word_fill1; - u32 aml_length; - u8 *aml_start; - struct acpi_namespace_node *method_REG; /* _REG method for this region (if any) */ - void *region_context; /* Region-specific data */ -}; - - -/* Additional data that can be attached to namespace nodes */ - -struct acpi_object_data -{ - ACPI_OBJECT_COMMON_HEADER - acpi_object_handler handler; - void *pointer; -}; - - -/* Structure used when objects are cached for reuse */ - -struct acpi_object_cache_list -{ - ACPI_OBJECT_COMMON_HEADER - union acpi_operand_object *next; /* Link for object cache and internal lists*/ -}; - - -/****************************************************************************** - * - * union acpi_operand_object Descriptor - a giant union of all of the above - * - *****************************************************************************/ - -union acpi_operand_object -{ - struct acpi_object_common common; - struct acpi_object_integer integer; - struct acpi_object_string string; - struct acpi_object_buffer buffer; - struct acpi_object_package package; - struct acpi_object_event event; - struct acpi_object_method method; - struct acpi_object_mutex mutex; - struct acpi_object_region region; - struct acpi_object_notify_common common_notify; - struct acpi_object_device device; - struct acpi_object_power_resource power_resource; - struct acpi_object_processor processor; - struct acpi_object_thermal_zone thermal_zone; - struct acpi_object_field_common common_field; - struct acpi_object_region_field field; - struct acpi_object_buffer_field buffer_field; - struct acpi_object_bank_field bank_field; - struct acpi_object_index_field index_field; - struct acpi_object_notify_handler notify_handler; - struct acpi_object_addr_handler addr_handler; - struct acpi_object_reference reference; - struct acpi_object_extra extra; - struct acpi_object_data data; - struct acpi_object_cache_list cache; -}; - - -/****************************************************************************** - * - * union acpi_descriptor - objects that share a common descriptor identifier - * - *****************************************************************************/ - - -/* Object descriptor types */ - -#define ACPI_DESC_TYPE_CACHED 0x11 /* Used only when object is cached */ -#define ACPI_DESC_TYPE_STATE 0x20 -#define ACPI_DESC_TYPE_STATE_UPDATE 0x21 -#define ACPI_DESC_TYPE_STATE_PACKAGE 0x22 -#define ACPI_DESC_TYPE_STATE_CONTROL 0x23 -#define ACPI_DESC_TYPE_STATE_RPSCOPE 0x24 -#define ACPI_DESC_TYPE_STATE_PSCOPE 0x25 -#define ACPI_DESC_TYPE_STATE_WSCOPE 0x26 -#define ACPI_DESC_TYPE_STATE_RESULT 0x27 -#define ACPI_DESC_TYPE_STATE_NOTIFY 0x28 -#define ACPI_DESC_TYPE_STATE_THREAD 0x29 -#define ACPI_DESC_TYPE_WALK 0x44 -#define ACPI_DESC_TYPE_PARSER 0x66 -#define ACPI_DESC_TYPE_OPERAND 0x88 -#define ACPI_DESC_TYPE_NAMED 0xAA - - -union acpi_descriptor -{ - u8 descriptor_id; /* To differentiate various internal objs */\ - union acpi_operand_object object; - struct acpi_namespace_node node; - union acpi_parse_object op; -}; - - -#endif /* _ACOBJECT_H */ diff -Nru a/drivers/acpi/include/acoutput.h b/drivers/acpi/include/acoutput.h --- a/drivers/acpi/include/acoutput.h Sun Feb 9 21:13:31 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,166 +0,0 @@ -/****************************************************************************** - * - * Name: acoutput.h -- debug output - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACOUTPUT_H__ -#define __ACOUTPUT_H__ - -/* - * Debug levels and component IDs. These are used to control the - * granularity of the output of the DEBUG_PRINT macro -- on a per- - * component basis and a per-exception-type basis. - */ - -/* Component IDs are used in the global "debug_layer" */ - -#define ACPI_UTILITIES 0x00000001 -#define ACPI_HARDWARE 0x00000002 -#define ACPI_EVENTS 0x00000004 -#define ACPI_TABLES 0x00000008 -#define ACPI_NAMESPACE 0x00000010 -#define ACPI_PARSER 0x00000020 -#define ACPI_DISPATCHER 0x00000040 -#define ACPI_EXECUTER 0x00000080 -#define ACPI_RESOURCES 0x00000100 -#define ACPI_CA_DEBUGGER 0x00000200 -#define ACPI_OS_SERVICES 0x00000400 -#define ACPI_CA_DISASSEMBLER 0x00000800 - -/* Component IDs for ACPI tools and utilities */ - -#define ACPI_COMPILER 0x00001000 -#define ACPI_TOOLS 0x00002000 - -#define ACPI_ALL_COMPONENTS 0x00003FFF -#define ACPI_COMPONENT_DEFAULT (ACPI_ALL_COMPONENTS) - - -/* Component IDs reserved for ACPI drivers */ - -#define ACPI_ALL_DRIVERS 0xFFFF0000 - - -/* - * Raw debug output levels, do not use these in the DEBUG_PRINT macros - */ -#define ACPI_LV_ERROR 0x00000001 -#define ACPI_LV_WARN 0x00000002 -#define ACPI_LV_INIT 0x00000004 -#define ACPI_LV_DEBUG_OBJECT 0x00000008 -#define ACPI_LV_INFO 0x00000010 -#define ACPI_LV_ALL_EXCEPTIONS 0x0000001F - -/* Trace verbosity level 1 [Standard Trace Level] */ - -#define ACPI_LV_INIT_NAMES 0x00000020 -#define ACPI_LV_PARSE 0x00000040 -#define ACPI_LV_LOAD 0x00000080 -#define ACPI_LV_DISPATCH 0x00000100 -#define ACPI_LV_EXEC 0x00000200 -#define ACPI_LV_NAMES 0x00000400 -#define ACPI_LV_OPREGION 0x00000800 -#define ACPI_LV_BFIELD 0x00001000 -#define ACPI_LV_TABLES 0x00002000 -#define ACPI_LV_VALUES 0x00004000 -#define ACPI_LV_OBJECTS 0x00008000 -#define ACPI_LV_RESOURCES 0x00010000 -#define ACPI_LV_USER_REQUESTS 0x00020000 -#define ACPI_LV_PACKAGE 0x00040000 -#define ACPI_LV_VERBOSITY1 0x0007FF40 | ACPI_LV_ALL_EXCEPTIONS - -/* Trace verbosity level 2 [Function tracing and memory allocation] */ - -#define ACPI_LV_ALLOCATIONS 0x00100000 -#define ACPI_LV_FUNCTIONS 0x00200000 -#define ACPI_LV_OPTIMIZATIONS 0x00400000 -#define ACPI_LV_VERBOSITY2 0x00700000 | ACPI_LV_VERBOSITY1 -#define ACPI_LV_ALL ACPI_LV_VERBOSITY2 - -/* Trace verbosity level 3 [Threading, I/O, and Interrupts] */ - -#define ACPI_LV_MUTEX 0x01000000 -#define ACPI_LV_THREADS 0x02000000 -#define ACPI_LV_IO 0x04000000 -#define ACPI_LV_INTERRUPTS 0x08000000 -#define ACPI_LV_VERBOSITY3 0x0F000000 | ACPI_LV_VERBOSITY2 - -/* Exceptionally verbose output -- also used in the global "debug_level" */ - -#define ACPI_LV_AML_DISASSEMBLE 0x10000000 -#define ACPI_LV_VERBOSE_INFO 0x20000000 -#define ACPI_LV_FULL_TABLES 0x40000000 -#define ACPI_LV_EVENTS 0x80000000 - -#define ACPI_LV_VERBOSE 0xF0000000 - - -/* - * Debug level macros that are used in the DEBUG_PRINT macros - */ -#define ACPI_DEBUG_LEVEL(dl) (u32) dl,__LINE__,&_dbg - -/* Exception level -- used in the global "debug_level" */ - -#define ACPI_DB_ERROR ACPI_DEBUG_LEVEL (ACPI_LV_ERROR) -#define ACPI_DB_WARN ACPI_DEBUG_LEVEL (ACPI_LV_WARN) -#define ACPI_DB_INIT ACPI_DEBUG_LEVEL (ACPI_LV_INIT) -#define ACPI_DB_DEBUG_OBJECT ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT) -#define ACPI_DB_INFO ACPI_DEBUG_LEVEL (ACPI_LV_INFO) -#define ACPI_DB_ALL_EXCEPTIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS) - - -/* Trace level -- also used in the global "debug_level" */ - -#define ACPI_DB_INIT_NAMES ACPI_DEBUG_LEVEL (ACPI_LV_INIT_NAMES) -#define ACPI_DB_THREADS ACPI_DEBUG_LEVEL (ACPI_LV_THREADS) -#define ACPI_DB_PARSE ACPI_DEBUG_LEVEL (ACPI_LV_PARSE) -#define ACPI_DB_DISPATCH ACPI_DEBUG_LEVEL (ACPI_LV_DISPATCH) -#define ACPI_DB_LOAD ACPI_DEBUG_LEVEL (ACPI_LV_LOAD) -#define ACPI_DB_EXEC ACPI_DEBUG_LEVEL (ACPI_LV_EXEC) -#define ACPI_DB_NAMES ACPI_DEBUG_LEVEL (ACPI_LV_NAMES) -#define ACPI_DB_OPREGION ACPI_DEBUG_LEVEL (ACPI_LV_OPREGION) -#define ACPI_DB_BFIELD ACPI_DEBUG_LEVEL (ACPI_LV_BFIELD) -#define ACPI_DB_TABLES ACPI_DEBUG_LEVEL (ACPI_LV_TABLES) -#define ACPI_DB_FUNCTIONS ACPI_DEBUG_LEVEL (ACPI_LV_FUNCTIONS) -#define ACPI_DB_OPTIMIZATIONS ACPI_DEBUG_LEVEL (ACPI_LV_OPTIMIZATIONS) -#define ACPI_DB_VALUES ACPI_DEBUG_LEVEL (ACPI_LV_VALUES) -#define ACPI_DB_OBJECTS ACPI_DEBUG_LEVEL (ACPI_LV_OBJECTS) -#define ACPI_DB_ALLOCATIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALLOCATIONS) -#define ACPI_DB_RESOURCES ACPI_DEBUG_LEVEL (ACPI_LV_RESOURCES) -#define ACPI_DB_IO ACPI_DEBUG_LEVEL (ACPI_LV_IO) -#define ACPI_DB_INTERRUPTS ACPI_DEBUG_LEVEL (ACPI_LV_INTERRUPTS) -#define ACPI_DB_USER_REQUESTS ACPI_DEBUG_LEVEL (ACPI_LV_USER_REQUESTS) -#define ACPI_DB_PACKAGE ACPI_DEBUG_LEVEL (ACPI_LV_PACKAGE) -#define ACPI_DB_MUTEX ACPI_DEBUG_LEVEL (ACPI_LV_MUTEX) - -#define ACPI_DB_ALL ACPI_DEBUG_LEVEL (ACPI_LV_ALL) - - -/* Defaults for debug_level, debug and normal */ - -#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) -#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) -#define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) - - -#endif /* __ACOUTPUT_H__ */ diff -Nru a/drivers/acpi/include/acparser.h b/drivers/acpi/include/acparser.h --- a/drivers/acpi/include/acparser.h Sun Feb 9 21:13:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,328 +0,0 @@ -/****************************************************************************** - * - * Module Name: acparser.h - AML Parser subcomponent prototypes and defines - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - - -#ifndef __ACPARSER_H__ -#define __ACPARSER_H__ - - -#define OP_HAS_RETURN_VALUE 1 - -/* variable # arguments */ - -#define ACPI_VAR_ARGS ACPI_UINT32_MAX - - -#define ACPI_PARSE_DELETE_TREE 0x0001 -#define ACPI_PARSE_NO_TREE_DELETE 0x0000 -#define ACPI_PARSE_TREE_MASK 0x0001 - -#define ACPI_PARSE_LOAD_PASS1 0x0010 -#define ACPI_PARSE_LOAD_PASS2 0x0020 -#define ACPI_PARSE_EXECUTE 0x0030 -#define ACPI_PARSE_MODE_MASK 0x0030 - -#define ACPI_PARSE_DEFERRED_OP 0x0100 - -/* Parser external interfaces */ - -acpi_status -acpi_psx_load_table ( - u8 *pcode_addr, - u32 pcode_length); - -acpi_status -acpi_psx_execute ( - struct acpi_namespace_node *method_node, - union acpi_operand_object **params, - union acpi_operand_object **return_obj_desc); - - -/****************************************************************************** - * - * Parser interfaces - * - *****************************************************************************/ - - -/* psargs - Parse AML opcode arguments */ - -u8 * -acpi_ps_get_next_package_end ( - struct acpi_parse_state *parser_state); - -u32 -acpi_ps_get_next_package_length ( - struct acpi_parse_state *parser_state); - -char * -acpi_ps_get_next_namestring ( - struct acpi_parse_state *parser_state); - -void -acpi_ps_get_next_simple_arg ( - struct acpi_parse_state *parser_state, - u32 arg_type, - union acpi_parse_object *arg); - -acpi_status -acpi_ps_get_next_namepath ( - struct acpi_walk_state *walk_state, - struct acpi_parse_state *parser_state, - union acpi_parse_object *arg, - u8 method_call); - -union acpi_parse_object * -acpi_ps_get_next_field ( - struct acpi_parse_state *parser_state); - -acpi_status -acpi_ps_get_next_arg ( - struct acpi_walk_state *walk_state, - struct acpi_parse_state *parser_state, - u32 arg_type, - union acpi_parse_object **return_arg); - - -/* psfind */ - -union acpi_parse_object * -acpi_ps_find_name ( - union acpi_parse_object *scope, - u32 name, - u32 opcode); - -union acpi_parse_object* -acpi_ps_get_parent ( - union acpi_parse_object *op); - - -/* psopcode - AML Opcode information */ - -const struct acpi_opcode_info * -acpi_ps_get_opcode_info ( - u16 opcode); - -char * -acpi_ps_get_opcode_name ( - u16 opcode); - - -/* psparse - top level parsing routines */ - -u32 -acpi_ps_get_opcode_size ( - u32 opcode); - -void -acpi_ps_complete_this_op ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op); - -acpi_status -acpi_ps_next_parse_state ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op, - acpi_status callback_status); - -acpi_status -acpi_ps_find_object ( - struct acpi_walk_state *walk_state, - union acpi_parse_object **out_op); - -void -acpi_ps_delete_parse_tree ( - union acpi_parse_object *root); - -acpi_status -acpi_ps_parse_loop ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ps_parse_aml ( - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ps_parse_table ( - u8 *aml, - u32 aml_size, - acpi_parse_downwards descending_callback, - acpi_parse_upwards ascending_callback, - union acpi_parse_object **root_object); - -u16 -acpi_ps_peek_opcode ( - struct acpi_parse_state *state); - - -/* psscope - Scope stack management routines */ - - -acpi_status -acpi_ps_init_scope ( - struct acpi_parse_state *parser_state, - union acpi_parse_object *root); - -union acpi_parse_object * -acpi_ps_get_parent_scope ( - struct acpi_parse_state *state); - -u8 -acpi_ps_has_completed_scope ( - struct acpi_parse_state *parser_state); - -void -acpi_ps_pop_scope ( - struct acpi_parse_state *parser_state, - union acpi_parse_object **op, - u32 *arg_list, - u32 *arg_count); - -acpi_status -acpi_ps_push_scope ( - struct acpi_parse_state *parser_state, - union acpi_parse_object *op, - u32 remaining_args, - u32 arg_count); - -void -acpi_ps_cleanup_scope ( - struct acpi_parse_state *state); - - -/* pstree - parse tree manipulation routines */ - -void -acpi_ps_append_arg( - union acpi_parse_object *op, - union acpi_parse_object *arg); - -union acpi_parse_object* -acpi_ps_find ( - union acpi_parse_object *scope, - char *path, - u16 opcode, - u32 create); - -union acpi_parse_object * -acpi_ps_get_arg( - union acpi_parse_object *op, - u32 argn); - -union acpi_parse_object * -acpi_ps_get_child ( - union acpi_parse_object *op); - -union acpi_parse_object * -acpi_ps_get_depth_next ( - union acpi_parse_object *origin, - union acpi_parse_object *op); - - -/* pswalk - parse tree walk routines */ - -acpi_status -acpi_ps_walk_parsed_aml ( - union acpi_parse_object *start_op, - union acpi_parse_object *end_op, - union acpi_operand_object *mth_desc, - struct acpi_namespace_node *start_node, - union acpi_operand_object **params, - union acpi_operand_object **caller_return_desc, - acpi_owner_id owner_id, - acpi_parse_downwards descending_callback, - acpi_parse_upwards ascending_callback); - -acpi_status -acpi_ps_get_next_walk_op ( - struct acpi_walk_state *walk_state, - union acpi_parse_object *op, - acpi_parse_upwards ascending_callback); - -acpi_status -acpi_ps_delete_completed_op ( - struct acpi_walk_state *walk_state); - - -/* psutils - parser utilities */ - -union acpi_parse_object * -acpi_ps_create_scope_op ( - void); - -void -acpi_ps_init_op ( - union acpi_parse_object *op, - u16 opcode); - -union acpi_parse_object * -acpi_ps_alloc_op ( - u16 opcode); - -void -acpi_ps_free_op ( - union acpi_parse_object *op); - -void -acpi_ps_delete_parse_cache ( - void); - -u8 -acpi_ps_is_leading_char ( - u32 c); - -u8 -acpi_ps_is_prefix_char ( - u32 c); - -u32 -acpi_ps_get_name( - union acpi_parse_object *op); - -void -acpi_ps_set_name( - union acpi_parse_object *op, - u32 name); - - -/* psdump - display parser tree */ - -u32 -acpi_ps_sprint_path ( - char *buffer_start, - u32 buffer_size, - union acpi_parse_object *op); - -u32 -acpi_ps_sprint_op ( - char *buffer_start, - u32 buffer_size, - union acpi_parse_object *op); - -void -acpi_ps_show ( - union acpi_parse_object *op); - - -#endif /* __ACPARSER_H__ */ diff -Nru a/drivers/acpi/include/acpi.h b/drivers/acpi/include/acpi.h --- a/drivers/acpi/include/acpi.h Sun Feb 9 21:13:32 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,50 +0,0 @@ -/****************************************************************************** - * - * Name: acpi.h - Master include file, Publics and external data. - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACPI_H__ -#define __ACPI_H__ - -/* - * Common includes for all ACPI driver files - * 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 */ - - -#endif /* __ACPI_H__ */ diff -Nru a/drivers/acpi/include/acpiosxf.h b/drivers/acpi/include/acpiosxf.h --- a/drivers/acpi/include/acpiosxf.h Sun Feb 9 21:13:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,337 +0,0 @@ - -/****************************************************************************** - * - * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL). These - * interfaces must be implemented by OSL to interface the - * ACPI components to the host operating system. - * - *****************************************************************************/ - - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACPIOSXF_H__ -#define __ACPIOSXF_H__ - -#include "platform/acenv.h" -#include "actypes.h" - - -/* Priorities for acpi_os_queue_for_execution */ - -#define OSD_PRIORITY_GPE 1 -#define OSD_PRIORITY_HIGH 2 -#define OSD_PRIORITY_MED 3 -#define OSD_PRIORITY_LO 4 - -#define ACPI_NO_UNIT_LIMIT ((u32) -1) -#define ACPI_MUTEX_SEM 1 - - -/* Functions for acpi_os_signal */ - -#define ACPI_SIGNAL_FATAL 0 -#define ACPI_SIGNAL_BREAKPOINT 1 - -struct acpi_signal_fatal_info -{ - u32 type; - u32 code; - u32 argument; -}; - - -/* - * Types specific to the OS service interfaces - */ - -typedef u32 -(ACPI_SYSTEM_XFACE *OSD_HANDLER) ( - void *context); - -typedef void -(ACPI_SYSTEM_XFACE *OSD_EXECUTION_CALLBACK) ( - void *context); - - -/* - * OSL Initialization and shutdown primitives - */ - -acpi_status -acpi_os_initialize ( - void); - -acpi_status -acpi_os_terminate ( - void); - - -/* - * ACPI Table interfaces - */ - -acpi_status -acpi_os_get_root_pointer ( - u32 flags, - struct acpi_pointer *address); - -acpi_status -acpi_os_table_override ( - struct acpi_table_header *existing_table, - struct acpi_table_header **new_table); - - -/* - * Synchronization primitives - */ - -acpi_status -acpi_os_create_semaphore ( - u32 max_units, - u32 initial_units, - acpi_handle *out_handle); - -acpi_status -acpi_os_delete_semaphore ( - acpi_handle handle); - -acpi_status -acpi_os_wait_semaphore ( - acpi_handle handle, - u32 units, - u16 timeout); - -acpi_status -acpi_os_signal_semaphore ( - acpi_handle handle, - u32 units); - - -/* - * Memory allocation and mapping - */ - -void * -acpi_os_allocate ( - acpi_size size); - -void -acpi_os_free ( - void * memory); - -acpi_status -acpi_os_map_memory ( - acpi_physical_address physical_address, - acpi_size size, - void **logical_address); - -void -acpi_os_unmap_memory ( - void *logical_address, - acpi_size size); - -acpi_status -acpi_os_get_physical_address ( - void *logical_address, - acpi_physical_address *physical_address); - - -/* - * Interrupt handlers - */ - -acpi_status -acpi_os_install_interrupt_handler ( - u32 interrupt_number, - OSD_HANDLER service_routine, - void *context); - -acpi_status -acpi_os_remove_interrupt_handler ( - u32 interrupt_number, - OSD_HANDLER service_routine); - - -/* - * Threads and Scheduling - */ - -u32 -acpi_os_get_thread_id ( - void); - -acpi_status -acpi_os_queue_for_execution ( - u32 priority, - OSD_EXECUTION_CALLBACK function, - void *context); - -void -acpi_os_sleep ( - u32 seconds, - u32 milliseconds); - -void -acpi_os_stall ( - u32 microseconds); - - -/* - * Platform and hardware-independent I/O interfaces - */ - -acpi_status -acpi_os_read_port ( - acpi_io_address address, - void *value, - u32 width); - -acpi_status -acpi_os_write_port ( - acpi_io_address address, - acpi_integer value, - u32 width); - - -/* - * Platform and hardware-independent physical memory interfaces - */ - -acpi_status -acpi_os_read_memory ( - acpi_physical_address address, - void *value, - u32 width); - -acpi_status -acpi_os_write_memory ( - acpi_physical_address address, - acpi_integer value, - u32 width); - - -/* - * Platform and hardware-independent PCI configuration space access - */ - -acpi_status -acpi_os_read_pci_configuration ( - struct acpi_pci_id *pci_id, - u32 register, - void *value, - u32 width); - -acpi_status -acpi_os_write_pci_configuration ( - struct acpi_pci_id *pci_id, - u32 register, - acpi_integer value, - u32 width); - -/* - * Interim function needed for PCI IRQ routing - */ -void -acpi_os_derive_pci_id( - acpi_handle rhandle, - acpi_handle chandle, - struct acpi_pci_id **pci_id); - -/* - * Miscellaneous - */ - -u8 -acpi_os_readable ( - void *pointer, - u32 length); - -u8 -acpi_os_writable ( - void *pointer, - u32 length); - -u32 -acpi_os_get_timer ( - void); - -acpi_status -acpi_os_signal ( - u32 function, - void *info); - -/* - * Debug print routines - */ - -void ACPI_INTERNAL_VAR_XFACE -acpi_os_printf ( - const char *format, - ...); - -void -acpi_os_vprintf ( - const char *format, - va_list args); - -void -acpi_os_redirect_output ( - void *destination); - - -/* - * Debug input - */ - -u32 -acpi_os_get_line ( - char *buffer); - - -/* - * Directory manipulation - */ - -void * -acpi_os_open_directory ( - char *pathname, - char *wildcard_spec); - -char * -acpi_os_get_next_filename ( - void *dir_handle); - -void -acpi_os_close_directory ( - void *dir_handle); - -/* - * Debug - */ - -void -acpi_os_dbg_assert( - void *failed_assertion, - void *file_name, - u32 line_number, - char *message); - - -#endif /* __ACPIOSXF_H__ */ diff -Nru a/drivers/acpi/include/acpixf.h b/drivers/acpi/include/acpixf.h --- a/drivers/acpi/include/acpixf.h Sun Feb 9 21:13:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,387 +0,0 @@ - -/****************************************************************************** - * - * Name: acpixf.h - External interfaces to the ACPI subsystem - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - - -#ifndef __ACXFACE_H__ -#define __ACXFACE_H__ - -#include "actypes.h" -#include "actbl.h" - - - /* - * Global interfaces - */ - -acpi_status -acpi_initialize_subsystem ( - void); - -acpi_status -acpi_enable_subsystem ( - u32 flags); - -acpi_status -acpi_initialize_objects ( - u32 flags); - -acpi_status -acpi_terminate ( - void); - -acpi_status -acpi_subsystem_status ( - void); - -acpi_status -acpi_enable ( - void); - -acpi_status -acpi_disable ( - void); - -acpi_status -acpi_get_system_info ( - struct acpi_buffer *ret_buffer); - -const char * -acpi_format_exception ( - acpi_status exception); - -acpi_status -acpi_purge_cached_objects ( - void); - -acpi_status -acpi_install_initialization_handler ( - acpi_init_handler handler, - u32 function); - -/* - * ACPI Memory manager - */ - -void * -acpi_allocate ( - u32 size); - -void * -acpi_callocate ( - u32 size); - -void -acpi_free ( - void *address); - - -/* - * ACPI table manipulation interfaces - */ - -acpi_status -acpi_find_root_pointer ( - u32 flags, - struct acpi_pointer *rsdp_address); - -acpi_status -acpi_load_tables ( - void); - -acpi_status -acpi_load_table ( - struct acpi_table_header *table_ptr); - -acpi_status -acpi_unload_table ( - acpi_table_type table_type); - -acpi_status -acpi_get_table_header ( - acpi_table_type table_type, - u32 instance, - struct acpi_table_header *out_table_header); - -acpi_status -acpi_get_table ( - acpi_table_type table_type, - u32 instance, - struct acpi_buffer *ret_buffer); - -acpi_status -acpi_get_firmware_table ( - acpi_string signature, - u32 instance, - u32 flags, - struct acpi_table_header **table_pointer); - - -/* - * Namespace and name interfaces - */ - -acpi_status -acpi_walk_namespace ( - acpi_object_type type, - acpi_handle start_object, - u32 max_depth, - acpi_walk_callback user_function, - void *context, - void **return_value); - -acpi_status -acpi_get_devices ( - char *HID, - acpi_walk_callback user_function, - void *context, - void **return_value); - -acpi_status -acpi_get_name ( - acpi_handle handle, - u32 name_type, - struct acpi_buffer *ret_path_ptr); - -acpi_status -acpi_get_handle ( - acpi_handle parent, - acpi_string pathname, - acpi_handle *ret_handle); - -acpi_status -acpi_attach_data ( - acpi_handle obj_handle, - acpi_object_handler handler, - void *data); - -acpi_status -acpi_detach_data ( - acpi_handle obj_handle, - acpi_object_handler handler); - -acpi_status -acpi_get_data ( - acpi_handle obj_handle, - acpi_object_handler handler, - void **data); - - -/* - * Object manipulation and enumeration - */ - -acpi_status -acpi_evaluate_object ( - acpi_handle object, - acpi_string pathname, - struct acpi_object_list *parameter_objects, - struct acpi_buffer *return_object_buffer); - -acpi_status -acpi_evaluate_object_typed ( - acpi_handle object, - acpi_string pathname, - struct acpi_object_list *external_params, - struct acpi_buffer *return_buffer, - acpi_object_type return_type); - -acpi_status -acpi_get_object_info ( - acpi_handle device, - struct acpi_device_info *info); - -acpi_status -acpi_get_next_object ( - acpi_object_type type, - acpi_handle parent, - acpi_handle child, - acpi_handle *out_handle); - -acpi_status -acpi_get_type ( - acpi_handle object, - acpi_object_type *out_type); - -acpi_status -acpi_get_parent ( - acpi_handle object, - acpi_handle *out_handle); - - -/* - * Event handler interfaces - */ - -acpi_status -acpi_install_fixed_event_handler ( - u32 acpi_event, - acpi_event_handler handler, - void *context); - -acpi_status -acpi_remove_fixed_event_handler ( - u32 acpi_event, - acpi_event_handler handler); - -acpi_status -acpi_install_notify_handler ( - acpi_handle device, - u32 handler_type, - acpi_notify_handler handler, - void *context); - -acpi_status -acpi_remove_notify_handler ( - acpi_handle device, - u32 handler_type, - acpi_notify_handler handler); - -acpi_status -acpi_install_address_space_handler ( - acpi_handle device, - acpi_adr_space_type space_id, - acpi_adr_space_handler handler, - acpi_adr_space_setup setup, - void *context); - -acpi_status -acpi_remove_address_space_handler ( - acpi_handle device, - acpi_adr_space_type space_id, - acpi_adr_space_handler handler); - -acpi_status -acpi_install_gpe_handler ( - u32 gpe_number, - u32 type, - acpi_gpe_handler handler, - void *context); - -acpi_status -acpi_acquire_global_lock ( - u16 timeout, - u32 *handle); - -acpi_status -acpi_release_global_lock ( - u32 handle); - -acpi_status -acpi_remove_gpe_handler ( - u32 gpe_number, - acpi_gpe_handler handler); - -acpi_status -acpi_enable_event ( - u32 acpi_event, - u32 type, - u32 flags); - -acpi_status -acpi_disable_event ( - u32 acpi_event, - u32 type, - u32 flags); - -acpi_status -acpi_clear_event ( - u32 acpi_event, - u32 type); - -acpi_status -acpi_get_event_status ( - u32 acpi_event, - u32 type, - acpi_event_status *event_status); - -/* - * Resource interfaces - */ - -acpi_status -acpi_get_current_resources( - acpi_handle device_handle, - struct acpi_buffer *ret_buffer); - -acpi_status -acpi_get_possible_resources( - acpi_handle device_handle, - struct acpi_buffer *ret_buffer); - -acpi_status -acpi_set_current_resources ( - acpi_handle device_handle, - struct acpi_buffer *in_buffer); - -acpi_status -acpi_get_irq_routing_table ( - acpi_handle bus_device_handle, - struct acpi_buffer *ret_buffer); - - -/* - * Hardware (ACPI device) interfaces - */ - -acpi_status -acpi_get_register ( - u32 register_id, - u32 *return_value, - u32 flags); - -acpi_status -acpi_set_register ( - u32 register_id, - u32 value, - u32 flags); - -acpi_status -acpi_set_firmware_waking_vector ( - acpi_physical_address physical_address); - -acpi_status -acpi_get_firmware_waking_vector ( - acpi_physical_address *physical_address); - -acpi_status -acpi_get_sleep_type_data ( - u8 sleep_state, - u8 *slp_typ_a, - u8 *slp_typ_b); - -acpi_status -acpi_enter_sleep_state_prep ( - u8 sleep_state); - -acpi_status -acpi_enter_sleep_state ( - u8 sleep_state); - -acpi_status -acpi_leave_sleep_state ( - u8 sleep_state); - - -#endif /* __ACXFACE_H__ */ diff -Nru a/drivers/acpi/include/acresrc.h b/drivers/acpi/include/acresrc.h --- a/drivers/acpi/include/acresrc.h Sun Feb 9 21:13:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,366 +0,0 @@ -/****************************************************************************** - * - * Name: acresrc.h - Resource Manager function prototypes - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACRESRC_H__ -#define __ACRESRC_H__ - - -/* - * Function prototypes called from Acpi* APIs - */ - -acpi_status -acpi_rs_get_prt_method_data ( - acpi_handle handle, - struct acpi_buffer *ret_buffer); - - -acpi_status -acpi_rs_get_crs_method_data ( - acpi_handle handle, - struct acpi_buffer *ret_buffer); - -acpi_status -acpi_rs_get_prs_method_data ( - acpi_handle handle, - struct acpi_buffer *ret_buffer); - -acpi_status -acpi_rs_set_srs_method_data ( - acpi_handle handle, - struct acpi_buffer *ret_buffer); - -acpi_status -acpi_rs_create_resource_list ( - union acpi_operand_object *byte_stream_buffer, - struct acpi_buffer *output_buffer); - -acpi_status -acpi_rs_create_byte_stream ( - struct acpi_resource *linked_list_buffer, - struct acpi_buffer *output_buffer); - -acpi_status -acpi_rs_create_pci_routing_table ( - union acpi_operand_object *package_object, - struct acpi_buffer *output_buffer); - - -/* - * Function prototypes called from acpi_rs_create* - */ -void -acpi_rs_dump_irq ( - union acpi_resource_data *data); - -void -acpi_rs_dump_address16 ( - union acpi_resource_data *data); - -void -acpi_rs_dump_address32 ( - union acpi_resource_data *data); - -void -acpi_rs_dump_address64 ( - union acpi_resource_data *data); - -void -acpi_rs_dump_dma ( - union acpi_resource_data *data); - -void -acpi_rs_dump_io ( - union acpi_resource_data *data); - -void -acpi_rs_dump_extended_irq ( - union acpi_resource_data *data); - -void -acpi_rs_dump_fixed_io ( - union acpi_resource_data *data); - -void -acpi_rs_dump_fixed_memory32 ( - union acpi_resource_data *data); - -void -acpi_rs_dump_memory24 ( - union acpi_resource_data *data); - -void -acpi_rs_dump_memory32 ( - union acpi_resource_data *data); - -void -acpi_rs_dump_start_depend_fns ( - union acpi_resource_data *data); - -void -acpi_rs_dump_vendor_specific ( - union acpi_resource_data *data); - -void -acpi_rs_dump_resource_list ( - struct acpi_resource *resource); - -void -acpi_rs_dump_irq_list ( - u8 *route_table); - -acpi_status -acpi_rs_get_byte_stream_start ( - u8 *byte_stream_buffer, - u8 **byte_stream_start, - u32 *size); - -acpi_status -acpi_rs_get_list_length ( - u8 *byte_stream_buffer, - u32 byte_stream_buffer_length, - acpi_size *size_needed); - -acpi_status -acpi_rs_get_byte_stream_length ( - struct acpi_resource *linked_list_buffer, - acpi_size *size_needed); - -acpi_status -acpi_rs_get_pci_routing_table_length ( - union acpi_operand_object *package_object, - acpi_size *buffer_size_needed); - -acpi_status -acpi_rs_byte_stream_to_list ( - u8 *byte_stream_buffer, - u32 byte_stream_buffer_length, - u8 *output_buffer); - -acpi_status -acpi_rs_list_to_byte_stream ( - struct acpi_resource *linked_list, - acpi_size byte_stream_size_needed, - u8 *output_buffer); - -acpi_status -acpi_rs_io_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_fixed_io_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_io_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_fixed_io_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_irq_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_irq_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_dma_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_dma_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_address16_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_address16_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_address32_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_address32_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_address64_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_address64_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_start_depend_fns_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_end_depend_fns_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_start_depend_fns_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_end_depend_fns_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_memory24_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_memory24_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_memory32_range_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_fixed_memory32_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_memory32_range_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_fixed_memory32_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_extended_irq_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_extended_irq_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_end_tag_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_end_tag_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -acpi_status -acpi_rs_vendor_resource ( - u8 *byte_stream_buffer, - acpi_size *bytes_consumed, - u8 **output_buffer, - acpi_size *structure_size); - -acpi_status -acpi_rs_vendor_stream ( - struct acpi_resource *linked_list, - u8 **output_buffer, - acpi_size *bytes_consumed); - -u8 -acpi_rs_get_resource_type ( - u8 resource_start_byte); - -#endif /* __ACRESRC_H__ */ diff -Nru a/drivers/acpi/include/acstruct.h b/drivers/acpi/include/acstruct.h --- a/drivers/acpi/include/acstruct.h Sun Feb 9 21:13:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,183 +0,0 @@ -/****************************************************************************** - * - * Name: acstruct.h - Internal structs - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACSTRUCT_H__ -#define __ACSTRUCT_H__ - - -/***************************************************************************** - * - * Tree walking typedefs and structs - * - ****************************************************************************/ - - -/* - * Walk state - current state of a parse tree walk. Used for both a leisurely stroll through - * the tree (for whatever reason), and for control method execution. - */ - -#define ACPI_NEXT_OP_DOWNWARD 1 -#define ACPI_NEXT_OP_UPWARD 2 - -#define ACPI_WALK_NON_METHOD 0 -#define ACPI_WALK_METHOD 1 -#define ACPI_WALK_METHOD_RESTART 2 -#define ACPI_WALK_CONST_REQUIRED 3 -#define ACPI_WALK_CONST_OPTIONAL 4 - -struct acpi_walk_state -{ - u8 data_type; /* To differentiate various internal objs MUST BE FIRST!*/\ - acpi_owner_id owner_id; /* Owner of objects created during the walk */ - u8 last_predicate; /* Result of last predicate */ - u8 current_result; /* */ - u8 next_op_info; /* Info about next_op */ - u8 num_operands; /* Stack pointer for Operands[] array */ - u8 return_used; - u8 walk_type; - u16 opcode; /* Current AML opcode */ - u8 scope_depth; - u8 reserved1; - u32 arg_count; /* push for fixed or var args */ - u32 aml_offset; - u32 arg_types; - u32 method_breakpoint; /* For single stepping */ - u32 user_breakpoint; /* User AML breakpoint */ - u32 parse_flags; - u32 prev_arg_types; - - u8 *aml_last_while; - struct acpi_namespace_node arguments[ACPI_METHOD_NUM_ARGS]; /* Control method arguments */ - union acpi_operand_object **caller_return_desc; - union acpi_generic_state *control_state; /* List of control states (nested IFs) */ - struct acpi_namespace_node local_variables[ACPI_METHOD_NUM_LOCALS]; /* Control method locals */ - struct acpi_namespace_node *method_call_node; /* Called method Node*/ - union acpi_parse_object *method_call_op; /* method_call Op if running a method */ - union acpi_operand_object *method_desc; /* Method descriptor if running a method */ - struct acpi_namespace_node *method_node; /* Method Node if running a method */ - union acpi_parse_object *op; /* Current parser op */ - union acpi_operand_object *operands[ACPI_OBJ_NUM_OPERANDS+1]; /* Operands passed to the interpreter (+1 for NULL terminator) */ - const struct acpi_opcode_info *op_info; /* Info on current opcode */ - union acpi_parse_object *origin; /* Start of walk [Obsolete] */ - union acpi_operand_object **params; - struct acpi_parse_state parser_state; /* Current state of parser */ - union acpi_operand_object *result_obj; - union acpi_generic_state *results; /* Stack of accumulated results */ - union acpi_operand_object *return_desc; /* Return object, if any */ - union acpi_generic_state *scope_info; /* Stack of nested scopes */ - - union acpi_parse_object *prev_op; /* Last op that was processed */ - union acpi_parse_object *next_op; /* next op to be processed */ - acpi_parse_downwards descending_callback; - acpi_parse_upwards ascending_callback; - struct acpi_thread_state *thread; - struct acpi_walk_state *next; /* Next walk_state in list */ -}; - - -/* Info used by acpi_ps_init_objects */ - -struct acpi_init_walk_info -{ - u16 method_count; - u16 device_count; - u16 op_region_count; - u16 field_count; - u16 buffer_count; - u16 package_count; - u16 op_region_init; - u16 field_init; - u16 buffer_init; - u16 package_init; - u16 object_count; - struct acpi_table_desc *table_desc; -}; - - -/* Info used by acpi_ns_initialize_devices */ - -struct acpi_device_walk_info -{ - u16 device_count; - u16 num_STA; - u16 num_INI; - struct acpi_table_desc *table_desc; -}; - - -/* TBD: [Restructure] Merge with struct above */ - -struct acpi_walk_info -{ - u32 debug_level; - u32 owner_id; - u8 display_type; -}; - -/* Display Types */ - -#define ACPI_DISPLAY_SUMMARY 0 -#define ACPI_DISPLAY_OBJECTS 1 - -struct acpi_get_devices_info -{ - acpi_walk_callback user_function; - void *context; - char *hid; -}; - - -union acpi_aml_operands -{ - union acpi_operand_object *operands[7]; - - struct - { - struct acpi_object_integer *type; - struct acpi_object_integer *code; - struct acpi_object_integer *argument; - - } fatal; - - struct - { - union acpi_operand_object *source; - struct acpi_object_integer *index; - union acpi_operand_object *target; - - } index; - - struct - { - union acpi_operand_object *source; - struct acpi_object_integer *index; - struct acpi_object_integer *length; - union acpi_operand_object *target; - - } mid; -}; - - -#endif diff -Nru a/drivers/acpi/include/actables.h b/drivers/acpi/include/actables.h --- a/drivers/acpi/include/actables.h Sun Feb 9 21:13:30 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,218 +0,0 @@ -/****************************************************************************** - * - * Name: actables.h - ACPI table management - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACTABLES_H__ -#define __ACTABLES_H__ - - -/* Used in acpi_tb_map_acpi_table for size parameter if table header is to be used */ - -#define SIZE_IN_HEADER 0 - - -acpi_status -acpi_tb_handle_to_object ( - u16 table_id, - struct acpi_table_desc **table_desc); - -/* - * tbconvrt - Table conversion routines - */ - -acpi_status -acpi_tb_convert_to_xsdt ( - struct acpi_table_desc *table_info); - -acpi_status -acpi_tb_convert_table_fadt ( - void); - -acpi_status -acpi_tb_build_common_facs ( - struct acpi_table_desc *table_info); - -u32 -acpi_tb_get_table_count ( - struct rsdp_descriptor *RSDP, - struct acpi_table_header *RSDT); - -/* - * tbget - Table "get" routines - */ - -acpi_status -acpi_tb_get_table ( - struct acpi_pointer *address, - struct acpi_table_desc *table_info); - -acpi_status -acpi_tb_get_table_header ( - struct acpi_pointer *address, - struct acpi_table_header *return_header); - -acpi_status -acpi_tb_get_table_body ( - struct acpi_pointer *address, - struct acpi_table_header *header, - struct acpi_table_desc *table_info); - -acpi_status -acpi_tb_get_this_table ( - struct acpi_pointer *address, - struct acpi_table_header *header, - struct acpi_table_desc *table_info); - -acpi_status -acpi_tb_table_override ( - struct acpi_table_header *header, - struct acpi_table_desc *table_info); - -acpi_status -acpi_tb_get_table_ptr ( - acpi_table_type table_type, - u32 instance, - struct acpi_table_header **table_ptr_loc); - -acpi_status -acpi_tb_verify_rsdp ( - struct acpi_pointer *address); - -void -acpi_tb_get_rsdt_address ( - struct acpi_pointer *out_address); - -acpi_status -acpi_tb_validate_rsdt ( - struct acpi_table_header *table_ptr); - -acpi_status -acpi_tb_get_required_tables ( - void); - -acpi_status -acpi_tb_get_primary_table ( - struct acpi_pointer *address, - struct acpi_table_desc *table_info); - -acpi_status -acpi_tb_get_secondary_table ( - struct acpi_pointer *address, - acpi_string signature, - struct acpi_table_desc *table_info); - -/* - * tbinstall - Table installation - */ - -acpi_status -acpi_tb_install_table ( - struct acpi_table_desc *table_info); - -acpi_status -acpi_tb_match_signature ( - char *signature, - struct acpi_table_desc *table_info, - u8 search_type); - -acpi_status -acpi_tb_recognize_table ( - struct acpi_table_desc *table_info, - u8 search_type); - -acpi_status -acpi_tb_init_table_descriptor ( - acpi_table_type table_type, - struct acpi_table_desc *table_info); - - -/* - * tbremove - Table removal and deletion - */ - -void -acpi_tb_delete_acpi_tables ( - void); - -void -acpi_tb_delete_acpi_table ( - acpi_table_type type); - -void -acpi_tb_delete_single_table ( - struct acpi_table_desc *table_desc); - -struct acpi_table_desc * -acpi_tb_uninstall_table ( - struct acpi_table_desc *table_desc); - -void -acpi_tb_free_acpi_tables_of_type ( - struct acpi_table_desc *table_info); - - -/* - * tbrsd - RSDP, RSDT utilities - */ - -acpi_status -acpi_tb_get_table_rsdt ( - void); - -u8 * -acpi_tb_scan_memory_for_rsdp ( - u8 *start_address, - u32 length); - -acpi_status -acpi_tb_find_rsdp ( - struct acpi_table_desc *table_info, - u32 flags); - - -/* - * tbutils - common table utilities - */ - -acpi_status -acpi_tb_find_table ( - char *signature, - char *oem_id, - char *oem_table_id, - struct acpi_table_header **table_ptr); - -acpi_status -acpi_tb_verify_table_checksum ( - struct acpi_table_header *table_header); - -u8 -acpi_tb_checksum ( - void *buffer, - u32 length); - -acpi_status -acpi_tb_validate_table_header ( - struct acpi_table_header *table_header); - - -#endif /* __ACTABLES_H__ */ diff -Nru a/drivers/acpi/include/actbl.h b/drivers/acpi/include/actbl.h --- a/drivers/acpi/include/actbl.h Sun Feb 9 21:13:32 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,208 +0,0 @@ -/****************************************************************************** - * - * Name: actbl.h - Table data structures defined in ACPI specification - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACTBL_H__ -#define __ACTBL_H__ - - -/* - * Values for description table header signatures - */ -#define RSDP_NAME "RSDP" -#define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */ -#define APIC_SIG "APIC" /* Multiple APIC Description Table */ -#define DSDT_SIG "DSDT" /* Differentiated System Description Table */ -#define FADT_SIG "FACP" /* Fixed ACPI Description Table */ -#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */ -#define PSDT_SIG "PSDT" /* Persistent System Description Table */ -#define RSDT_SIG "RSDT" /* Root System Description Table */ -#define XSDT_SIG "XSDT" /* Extended System Description Table */ -#define SSDT_SIG "SSDT" /* Secondary System Description Table */ -#define SBST_SIG "SBST" /* Smart Battery Specification Table */ -#define SPIC_SIG "SPIC" /* IOSAPIC table */ -#define BOOT_SIG "BOOT" /* Boot table */ - - -#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */ - -/* values of Mapic.Model */ - -#define DUAL_PIC 0 -#define MULTIPLE_APIC 1 - -/* values of Type in struct apic_header */ - -#define APIC_PROC 0 -#define APIC_IO 1 - - -/* - * Common table types. The base code can remain - * constant if the underlying tables are changed - */ -#define RSDT_DESCRIPTOR struct rsdt_descriptor_rev2 -#define XSDT_DESCRIPTOR struct xsdt_descriptor_rev2 -#define FACS_DESCRIPTOR struct facs_descriptor_rev2 -#define FADT_DESCRIPTOR struct fadt_descriptor_rev2 - - -#pragma pack(1) - -/* - * Architecture-independent tables - * The architecture dependent tables are in separate files - */ -struct rsdp_descriptor /* Root System Descriptor Pointer */ -{ - char signature [8]; /* ACPI signature, contains "RSD PTR " */ - u8 checksum; /* To make sum of struct == 0 */ - char oem_id [6]; /* OEM identification */ - u8 revision; /* Must be 0 for 1.0, 2 for 2.0 */ - u32 rsdt_physical_address; /* 32-bit physical address of RSDT */ - u32 length; /* XSDT Length in bytes including hdr */ - u64 xsdt_physical_address; /* 64-bit physical address of XSDT */ - u8 extended_checksum; /* Checksum of entire table */ - char reserved [3]; /* Reserved field must be 0 */ -}; - - -struct acpi_table_header /* ACPI common table header */ -{ - char signature [4]; /* ACPI signature (4 ASCII characters) */ - u32 length; /* Length of table, in bytes, including header */ - u8 revision; /* ACPI Specification minor version # */ - u8 checksum; /* To make sum of entire table == 0 */ - char oem_id [6]; /* OEM identification */ - char oem_table_id [8]; /* OEM table identification */ - u32 oem_revision; /* OEM revision number */ - char asl_compiler_id [4]; /* ASL compiler vendor ID */ - u32 asl_compiler_revision; /* ASL compiler revision number */ -}; - - -struct acpi_common_facs /* Common FACS for internal use */ -{ - u32 *global_lock; - u64 *firmware_waking_vector; - u8 vector_width; -}; - - -struct apic_table -{ - struct acpi_table_header header; /* ACPI table header */ - u32 local_apic_address; /* Physical address for accessing local APICs */ - u32 PCATcompat : 1; /* a one indicates system also has dual 8259s */ - u32 reserved1 : 31; -}; - - -struct apic_header -{ - u8 type; /* APIC type. Either APIC_PROC or APIC_IO */ - u8 length; /* Length of APIC structure */ -}; - - -struct processor_apic -{ - struct apic_header header; - u8 processor_apic_id; /* ACPI processor id */ - u8 local_apic_id; /* Processor's local APIC id */ - u32 processor_enabled: 1; /* Processor is usable if set */ - u32 reserved1 : 31; -}; - - -struct io_apic -{ - struct apic_header header; - u8 io_apic_id; /* I/O APIC ID */ - u8 reserved; /* Reserved - must be zero */ - u32 io_apic_address; /* APIC's physical address */ - u32 vector; /* Interrupt vector index where INTI - * lines start */ -}; - - -/* - * IA64 TBD: Add SAPIC Tables - */ - -/* - * IA64 TBD: Modify Smart Battery Description to comply with ACPI IA64 - * extensions. - */ -struct smart_battery_description_table -{ - struct acpi_table_header header; - u32 warning_level; - u32 low_level; - u32 critical_level; -}; - - -#pragma pack() - - -/* - * ACPI Table information. We save the table address, length, - * and type of memory allocation (mapped or allocated) for each - * table for 1) when we exit, and 2) if a new table is installed - */ -#define ACPI_MEM_NOT_ALLOCATED 0 -#define ACPI_MEM_ALLOCATED 1 -#define ACPI_MEM_MAPPED 2 - -/* Definitions for the Flags bitfield member of struct acpi_table_support */ - -#define ACPI_TABLE_SINGLE 0x00 -#define ACPI_TABLE_MULTIPLE 0x01 -#define ACPI_TABLE_EXECUTABLE 0x02 - -#define ACPI_TABLE_ROOT 0x00 -#define ACPI_TABLE_PRIMARY 0x10 -#define ACPI_TABLE_SECONDARY 0x20 -#define ACPI_TABLE_OTHER 0x30 -#define ACPI_TABLE_TYPE_MASK 0x30 - -/* Data about each known table type */ - -struct acpi_table_support -{ - char *name; - char *signature; - void **global_ptr; - u8 sig_length; - u8 flags; -}; - - -/* - * Get the architecture-specific tables - */ -#include "actbl1.h" /* Acpi 1.0 table definitions */ -#include "actbl2.h" /* Acpi 2.0 table definitions */ - -#endif /* __ACTBL_H__ */ diff -Nru a/drivers/acpi/include/actbl1.h b/drivers/acpi/include/actbl1.h --- a/drivers/acpi/include/actbl1.h Sun Feb 9 21:13:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,117 +0,0 @@ -/****************************************************************************** - * - * Name: actbl1.h - ACPI 1.0 tables - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACTBL1_H__ -#define __ACTBL1_H__ - -#pragma pack(1) - -/* - * ACPI 1.0 Root System Description Table (RSDT) - */ -struct rsdt_descriptor_rev1 -{ - struct acpi_table_header header; /* ACPI Table header */ - u32 table_offset_entry [1]; /* Array of pointers to other */ - /* ACPI tables */ -}; - - -/* - * ACPI 1.0 Firmware ACPI Control Structure (FACS) - */ -struct facs_descriptor_rev1 -{ - char signature[4]; /* ACPI Signature */ - u32 length; /* Length of structure, in bytes */ - u32 hardware_signature; /* Hardware configuration signature */ - u32 firmware_waking_vector; /* ACPI OS waking vector */ - u32 global_lock; /* Global Lock */ - u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */ - u32 reserved1 : 31; /* Must be 0 */ - u8 resverved3 [40]; /* Reserved - must be zero */ -}; - - -/* - * ACPI 1.0 Fixed ACPI Description Table (FADT) - */ -struct fadt_descriptor_rev1 -{ - struct acpi_table_header header; /* ACPI Table header */ - u32 firmware_ctrl; /* Physical address of FACS */ - u32 dsdt; /* Physical address of DSDT */ - u8 model; /* System Interrupt Model */ - u8 reserved1; /* Reserved */ - u16 sci_int; /* System vector of SCI interrupt */ - u32 smi_cmd; /* Port address of SMI command port */ - u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ - u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ - u8 reserved2; /* Reserved - must be zero */ - u32 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ - u32 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ - u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - u32 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ - u32 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ - u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ - u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ - u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ - u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ - u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ - u8 reserved3; /* Reserved */ - u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ - u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ - u16 flush_size; /* Size of area read to flush caches */ - u16 flush_stride; /* Stride used in flushing caches */ - u8 duty_offset; /* Bit location of duty cycle field in p_cnt reg */ - u8 duty_width; /* Bit width of duty cycle field in p_cnt reg */ - u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ - u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* Index to century in RTC CMOS RAM */ - u8 reserved4; /* Reserved */ - u8 reserved4a; /* Reserved */ - u8 reserved4b; /* Reserved */ - u32 wb_invd : 1; /* The wbinvd instruction works properly */ - u32 wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */ - u32 proc_c1 : 1; /* All processors support C1 state */ - u32 plvl2_up : 1; /* C2 state works on MP system */ - u32 pwr_button : 1; /* Power button is handled as a generic feature */ - u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ - u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ - u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ - u32 tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */ - u32 reserved5 : 23; /* Reserved - must be zero */ -}; - -#pragma pack() - -#endif /* __ACTBL1_H__ */ - - diff -Nru a/drivers/acpi/include/actbl2.h b/drivers/acpi/include/actbl2.h --- a/drivers/acpi/include/actbl2.h Sun Feb 9 21:13:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,182 +0,0 @@ -/****************************************************************************** - * - * Name: actbl2.h - ACPI Specification Revision 2.0 Tables - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACTBL2_H__ -#define __ACTBL2_H__ - -/* - * Prefered Power Management Profiles - */ -#define PM_UNSPECIFIED 0 -#define PM_DESKTOP 1 -#define PM_MOBILE 2 -#define PM_WORKSTATION 3 -#define PM_ENTERPRISE_SERVER 4 -#define PM_SOHO_SERVER 5 -#define PM_APPLIANCE_PC 6 - -/* - * ACPI Boot Arch Flags - */ -#define BAF_LEGACY_DEVICES 0x0001 -#define BAF_8042_KEYBOARD_CONTROLLER 0x0002 - -#define FADT2_REVISION_ID 3 - - -#pragma pack(1) - -/* - * ACPI 2.0 Root System Description Table (RSDT) - */ -struct rsdt_descriptor_rev2 -{ - struct acpi_table_header header; /* ACPI table header */ - u32 table_offset_entry [1]; /* Array of pointers to */ - /* ACPI table headers */ -}; - - -/* - * ACPI 2.0 Extended System Description Table (XSDT) - */ -struct xsdt_descriptor_rev2 -{ - struct acpi_table_header header; /* ACPI table header */ - u64 table_offset_entry [1]; /* Array of pointers to */ - /* ACPI table headers */ -}; - - -/* - * ACPI 2.0 Firmware ACPI Control Structure (FACS) - */ -struct facs_descriptor_rev2 -{ - char signature[4]; /* ACPI signature */ - u32 length; /* Length of structure, in bytes */ - u32 hardware_signature; /* Hardware configuration signature */ - u32 firmware_waking_vector; /* 32bit physical address of the Firmware Waking Vector. */ - u32 global_lock; /* Global Lock used to synchronize access to shared hardware resources */ - u32 S4bios_f : 1; /* S4Bios_f - Indicates if S4BIOS support is present */ - u32 reserved1 : 31; /* Must be 0 */ - u64 xfirmware_waking_vector; /* 64bit physical address of the Firmware Waking Vector. */ - u8 version; /* Version of this table */ - u8 reserved3 [31]; /* Reserved - must be zero */ -}; - - -/* - * ACPI 2.0 Generic Address Structure (GAS) - */ -struct acpi_generic_address -{ - u8 address_space_id; /* Address space where struct or register exists. */ - u8 register_bit_width; /* Size in bits of given register */ - u8 register_bit_offset; /* Bit offset within the register */ - u8 reserved; /* Must be 0 */ - u64 address; /* 64-bit address of struct or register */ -}; - - -/* - * ACPI 2.0 Fixed ACPI Description Table (FADT) - */ -struct fadt_descriptor_rev2 -{ - struct acpi_table_header header; /* ACPI table header */ - u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ - u32 V1_dsdt; /* 32-bit physical address of DSDT */ - u8 reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/ - u8 prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */ - u16 sci_int; /* System vector of SCI interrupt */ - u32 smi_cmd; /* Port address of SMI command port */ - u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ - u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ - u8 pstate_cnt; /* Processor performance state control*/ - u32 V1_pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ - u32 V1_pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ - u32 V1_pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - u32 V1_pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - u32 V1_pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - u32 V1_pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - u32 V1_gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ - u32 V1_gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ - u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ - u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ - u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ - u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ - u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ - u8 cst_cnt; /* Support for the _CST object and C States change notification.*/ - u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ - u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ - u16 flush_size; /* Number of flush strides that need to be read */ - u16 flush_stride; /* Processor's memory cache line width, in bytes */ - u8 duty_offset; /* Processor's duty cycle index in processor's P_CNT reg*/ - u8 duty_width; /* Processor's duty cycle value bit width in P_CNT register.*/ - u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ - u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* Index to century in RTC CMOS RAM */ - u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/ - u8 reserved2; /* Reserved */ - u32 wb_invd : 1; /* The wbinvd instruction works properly */ - u32 wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */ - u32 proc_c1 : 1; /* All processors support C1 state */ - u32 plvl2_up : 1; /* C2 state works on MP system */ - u32 pwr_button : 1; /* Power button is handled as a generic feature */ - u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ - u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ - u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ - u32 tmr_val_ext : 1; /* Indicates tmr_val is 32 bits 0=24-bits*/ - u32 dock_cap : 1; /* Supports Docking */ - u32 reset_reg_sup : 1; /* Indicates system supports system reset via the FADT RESET_REG*/ - u32 sealed_case : 1; /* Indicates system has no internal expansion capabilities and case is sealed. */ - u32 headless : 1; /* Indicates system does not have local video capabilities or local input devices.*/ - u32 cpu_sw_sleep : 1; /* Indicates to OSPM that a processor native instruction */ - /* Must be executed after writing the SLP_TYPx register. */ - u32 reserved6 : 18; /* Reserved - must be zero */ - - struct acpi_generic_address reset_register; /* Reset register address in GAS format */ - u8 reset_value; /* Value to write to the reset_register port to reset the system. */ - u8 reserved7[3]; /* These three bytes must be zero */ - u64 xfirmware_ctrl; /* 64-bit physical address of FACS */ - u64 Xdsdt; /* 64-bit physical address of DSDT */ - struct acpi_generic_address xpm1a_evt_blk; /* Extended Power Mgt 1a acpi_event Reg Blk address */ - struct acpi_generic_address xpm1b_evt_blk; /* Extended Power Mgt 1b acpi_event Reg Blk address */ - struct acpi_generic_address xpm1a_cnt_blk; /* Extended Power Mgt 1a Control Reg Blk address */ - struct acpi_generic_address xpm1b_cnt_blk; /* Extended Power Mgt 1b Control Reg Blk address */ - struct acpi_generic_address xpm2_cnt_blk; /* Extended Power Mgt 2 Control Reg Blk address */ - struct acpi_generic_address xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */ - struct acpi_generic_address xgpe0_blk; /* Extended General Purpose acpi_event 0 Reg Blk address */ - struct acpi_generic_address xgpe1_blk; /* Extended General Purpose acpi_event 1 Reg Blk address */ -}; - - -#pragma pack() - -#endif /* __ACTBL2_H__ */ - diff -Nru a/drivers/acpi/include/actbl71.h b/drivers/acpi/include/actbl71.h --- a/drivers/acpi/include/actbl71.h Sun Feb 9 21:13:31 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,144 +0,0 @@ -/****************************************************************************** - * - * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71 - * This file includes tables specific to this - * specification revision. - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACTBL71_H__ -#define __ACTBL71_H__ - - -/* 0.71 FADT address_space data item bitmasks defines */ -/* If the associated bit is zero then it is in memory space else in io space */ - -#define SMI_CMD_ADDRESS_SPACE 0x01 -#define PM1_BLK_ADDRESS_SPACE 0x02 -#define PM2_CNT_BLK_ADDRESS_SPACE 0x04 -#define PM_TMR_BLK_ADDRESS_SPACE 0x08 -#define GPE0_BLK_ADDRESS_SPACE 0x10 -#define GPE1_BLK_ADDRESS_SPACE 0x20 - -/* Only for clarity in declarations */ - -typedef u64 IO_ADDRESS; - - -#pragma pack(1) -struct /* Root System Descriptor Pointer */ -{ - NATIVE_CHAR signature [8]; /* contains "RSD PTR " */ - u8 checksum; /* to make sum of struct == 0 */ - NATIVE_CHAR oem_id [6]; /* OEM identification */ - u8 reserved; /* Must be 0 for 1.0, 2 for 2.0 */ - u64 rsdt_physical_address; /* 64-bit physical address of RSDT */ -}; - - -/*****************************************/ -/* IA64 Extensions to ACPI Spec Rev 0.71 */ -/* for the Root System Description Table */ -/*****************************************/ -struct -{ - struct acpi_table_header header; /* Table header */ - u32 reserved_pad; /* IA64 alignment, must be 0 */ - u64 table_offset_entry [1]; /* Array of pointers to other */ - /* tables' headers */ -}; - - -/*******************************************/ -/* IA64 Extensions to ACPI Spec Rev 0.71 */ -/* for the Firmware ACPI Control Structure */ -/*******************************************/ -struct -{ - NATIVE_CHAR signature[4]; /* signature "FACS" */ - u32 length; /* length of structure, in bytes */ - u32 hardware_signature; /* hardware configuration signature */ - u32 reserved4; /* must be 0 */ - u64 firmware_waking_vector; /* ACPI OS waking vector */ - u64 global_lock; /* Global Lock */ - u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */ - u32 reserved1 : 31; /* must be 0 */ - u8 reserved3 [28]; /* reserved - must be zero */ -}; - - -/******************************************/ -/* IA64 Extensions to ACPI Spec Rev 0.71 */ -/* for the Fixed ACPI Description Table */ -/******************************************/ -struct -{ - struct acpi_table_header header; /* table header */ - u32 reserved_pad; /* IA64 alignment, must be 0 */ - u64 firmware_ctrl; /* 64-bit Physical address of FACS */ - u64 dsdt; /* 64-bit Physical address of DSDT */ - u8 model; /* System Interrupt Model */ - u8 address_space; /* Address Space Bitmask */ - u16 sci_int; /* System vector of SCI interrupt */ - u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ - u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ - u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ - u8 reserved2; /* reserved - must be zero */ - u64 smi_cmd; /* Port address of SMI command port */ - u64 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ - u64 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ - u64 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ - u64 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ - u64 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ - u64 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ - u64 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ - u64 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ - u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ - u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ - u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ - u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ - u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ - u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ - u8 gpe1_base; /* offset in gpe model where gpe1 events start */ - u8 reserved3; /* reserved */ - u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ - u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ - u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ - u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ - u8 century; /* index to century in RTC CMOS RAM */ - u8 reserved4; /* reserved */ - u32 flush_cash : 1; /* PAL_FLUSH_CACHE is correctly supported */ - u32 reserved5 : 1; /* reserved - must be zero */ - u32 proc_c1 : 1; /* all processors support C1 state */ - u32 plvl2_up : 1; /* C2 state works on MP system */ - u32 pwr_button : 1; /* Power button is handled as a generic feature */ - u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ - u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ - u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ - u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ - u32 dock_cap : 1; /* Supports Docking */ - u32 reserved6 : 22; /* reserved - must be zero */ -}; - -#pragma pack() - -#endif /* __ACTBL71_H__ */ - diff -Nru a/drivers/acpi/include/actypes.h b/drivers/acpi/include/actypes.h --- a/drivers/acpi/include/actypes.h Sun Feb 9 21:13:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1189 +0,0 @@ -/****************************************************************************** - * - * Name: actypes.h - Common data types for the entire ACPI subsystem - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACTYPES_H__ -#define __ACTYPES_H__ - -/*! [Begin] no source code translation (keep the typedefs) */ - - - -/* - * Data type ranges - */ -#define ACPI_UINT8_MAX (UINT8) 0xFF -#define ACPI_UINT16_MAX (UINT16) 0xFFFF -#define ACPI_UINT32_MAX (UINT32) 0xFFFFFFFF -#define ACPI_UINT64_MAX (UINT64) 0xFFFFFFFFFFFFFFFF -#define ACPI_ASCII_MAX 0x7F - - -#ifdef DEFINE_ALTERNATE_TYPES -/* - * Types used only in translated source, defined here to enable - * cross-platform compilation only. - */ -typedef int s32; -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef COMPILER_DEPENDENT_UINT64 u64; - -#endif - - -/* - * Data types - Fixed across all compilation models (16/32/64) - * - * BOOLEAN Logical Boolean. - * INT8 8-bit (1 byte) signed value - * UINT8 8-bit (1 byte) unsigned value - * INT16 16-bit (2 byte) signed value - * UINT16 16-bit (2 byte) unsigned value - * INT32 32-bit (4 byte) signed value - * UINT32 32-bit (4 byte) unsigned value - * INT64 64-bit (8 byte) signed value - * UINT64 64-bit (8 byte) unsigned value - * ACPI_NATIVE_INT 32-bit on IA-32, 64-bit on IA-64 signed value - * ACPI_NATIVE_UINT 32-bit on IA-32, 64-bit on IA-64 unsigned value - */ - -#ifndef ACPI_MACHINE_WIDTH -#error ACPI_MACHINE_WIDTH not defined -#endif - -#if ACPI_MACHINE_WIDTH == 64 - -/*! [Begin] no source code translation (keep the typedefs) */ - -/* - * 64-bit type definitions - */ -typedef unsigned char UINT8; -typedef unsigned char BOOLEAN; -typedef unsigned short UINT16; -typedef int INT32; -typedef unsigned int UINT32; -typedef COMPILER_DEPENDENT_INT64 INT64; -typedef COMPILER_DEPENDENT_UINT64 UINT64; - -/*! [End] no source code translation !*/ - -typedef s64 acpi_native_int; -typedef u64 acpi_native_uint; - -typedef u64 acpi_table_ptr; -typedef u64 acpi_io_address; -typedef u64 acpi_physical_address; -typedef u64 acpi_size; - -#define ALIGNED_ADDRESS_BOUNDARY 0x00000008 /* No hardware alignment support in IA64 */ -#define ACPI_USE_NATIVE_DIVIDE /* Native 64-bit integer support */ -#define ACPI_MAX_PTR ACPI_UINT64_MAX -#define ACPI_SIZE_MAX ACPI_UINT64_MAX - - -#elif ACPI_MACHINE_WIDTH == 16 - -/*! [Begin] no source code translation (keep the typedefs) */ - -/* - * 16-bit type definitions - */ -typedef unsigned char UINT8; -typedef unsigned char BOOLEAN; -typedef unsigned int UINT16; -typedef long INT32; -typedef int INT16; -typedef unsigned long UINT32; - -struct -{ - UINT32 Lo; - UINT32 Hi; -}; - -/*! [End] no source code translation !*/ - -typedef u16 acpi_native_uint; -typedef s16 acpi_native_int; - -typedef u32 acpi_table_ptr; -typedef u32 acpi_io_address; -typedef char *acpi_physical_address; -typedef u16 acpi_size; - -#define ALIGNED_ADDRESS_BOUNDARY 0x00000002 -#define _HW_ALIGNMENT_SUPPORT -#define ACPI_USE_NATIVE_DIVIDE /* No 64-bit integers, ok to use native divide */ -#define ACPI_MAX_PTR ACPI_UINT16_MAX -#define ACPI_SIZE_MAX ACPI_UINT16_MAX - -/* - * (16-bit only) internal integers must be 32-bits, so - * 64-bit integers cannot be supported - */ -#define ACPI_NO_INTEGER64_SUPPORT - - -#elif ACPI_MACHINE_WIDTH == 32 - -/*! [Begin] no source code translation (keep the typedefs) */ - -/* - * 32-bit type definitions (default) - */ -typedef unsigned char UINT8; -typedef unsigned char BOOLEAN; -typedef unsigned short UINT16; -typedef int INT32; -typedef unsigned int UINT32; -typedef COMPILER_DEPENDENT_INT64 INT64; -typedef COMPILER_DEPENDENT_UINT64 UINT64; - -/*! [End] no source code translation !*/ - -typedef s32 acpi_native_int; -typedef u32 acpi_native_uint; - -typedef u64 acpi_table_ptr; -typedef u32 acpi_io_address; -typedef u64 acpi_physical_address; -typedef u32 acpi_size; - -#define ALIGNED_ADDRESS_BOUNDARY 0x00000004 -#define _HW_ALIGNMENT_SUPPORT -#define ACPI_MAX_PTR ACPI_UINT32_MAX -#define ACPI_SIZE_MAX ACPI_UINT32_MAX - -#else -#error unknown ACPI_MACHINE_WIDTH -#endif - - -/* - * Miscellaneous common types - */ -typedef u32 UINT32_BIT; -typedef acpi_native_uint ACPI_PTRDIFF; - -/* - * Pointer overlays to avoid lots of typecasting for - * code that accepts both physical and logical pointers. - */ -union acpi_pointers -{ - acpi_physical_address physical; - void *logical; - acpi_table_ptr value; -}; - -struct acpi_pointer -{ - u32 pointer_type; - union acpi_pointers pointer; -}; - -/* pointer_types for above */ - -#define ACPI_PHYSICAL_POINTER 0x01 -#define ACPI_LOGICAL_POINTER 0x02 - -/* Processor mode */ - -#define ACPI_PHYSICAL_ADDRESSING 0x04 -#define ACPI_LOGICAL_ADDRESSING 0x08 -#define ACPI_MEMORY_MODE 0x0C - -#define ACPI_PHYSMODE_PHYSPTR ACPI_PHYSICAL_ADDRESSING | ACPI_PHYSICAL_POINTER -#define ACPI_LOGMODE_PHYSPTR ACPI_LOGICAL_ADDRESSING | ACPI_PHYSICAL_POINTER -#define ACPI_LOGMODE_LOGPTR ACPI_LOGICAL_ADDRESSING | ACPI_LOGICAL_POINTER - - -/* - * Useful defines - */ -#ifdef FALSE -#undef FALSE -#endif -#define FALSE (1 == 0) - -#ifdef TRUE -#undef TRUE -#endif -#define TRUE (1 == 1) - -#ifndef NULL -#define NULL (void *) 0 -#endif - - -/* - * Local datatypes - */ -typedef u32 acpi_status; /* All ACPI Exceptions */ -typedef u32 acpi_name; /* 4-byte ACPI name */ -typedef char * acpi_string; /* Null terminated ASCII string */ -typedef void * acpi_handle; /* Actually a ptr to an Node */ - -struct uint64_struct -{ - u32 lo; - u32 hi; -}; - -union uint64_overlay -{ - u64 full; - struct uint64_struct part; -}; - -struct uint32_struct -{ - u32 lo; - u32 hi; -}; - - -/* - * Acpi integer width. In ACPI version 1, integers are - * 32 bits. In ACPI version 2, integers are 64 bits. - * Note that this pertains to the ACPI integer type only, not - * other integers used in the implementation of the ACPI CA - * subsystem. - */ -#ifdef ACPI_NO_INTEGER64_SUPPORT - -/* 32-bit integers only, no 64-bit support */ - -typedef u32 acpi_integer; -#define ACPI_INTEGER_MAX ACPI_UINT32_MAX -#define ACPI_INTEGER_BIT_SIZE 32 -#define ACPI_MAX_BCD_VALUE 99999999 -#define ACPI_MAX_BCD_DIGITS 8 -#define ACPI_MAX_DECIMAL_DIGITS 10 - -#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 32-bit divide */ - - -#else - -/* 64-bit integers */ - -typedef u64 acpi_integer; -#define ACPI_INTEGER_MAX ACPI_UINT64_MAX -#define ACPI_INTEGER_BIT_SIZE 64 -#define ACPI_MAX_BCD_VALUE 9999999999999999 -#define ACPI_MAX_BCD_DIGITS 16 -#define ACPI_MAX_DECIMAL_DIGITS 19 - -#if ACPI_MACHINE_WIDTH == 64 -#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 64-bit divide */ -#endif -#endif - - -/* - * Constants with special meanings - */ -#define ACPI_ROOT_OBJECT (acpi_handle) ACPI_PTR_ADD (char, NULL, ACPI_MAX_PTR) - - -/* - * Initialization sequence - */ -#define ACPI_FULL_INITIALIZATION 0x00 -#define ACPI_NO_ADDRESS_SPACE_INIT 0x01 -#define ACPI_NO_HARDWARE_INIT 0x02 -#define ACPI_NO_EVENT_INIT 0x04 -#define ACPI_NO_HANDLER_INIT 0x08 -#define ACPI_NO_ACPI_ENABLE 0x10 -#define ACPI_NO_DEVICE_INIT 0x20 -#define ACPI_NO_OBJECT_INIT 0x40 - -/* - * Initialization state - */ -#define ACPI_INITIALIZED_OK 0x01 - -/* - * Power state values - */ - -#define ACPI_STATE_UNKNOWN (u8) 0xFF - -#define ACPI_STATE_S0 (u8) 0 -#define ACPI_STATE_S1 (u8) 1 -#define ACPI_STATE_S2 (u8) 2 -#define ACPI_STATE_S3 (u8) 3 -#define ACPI_STATE_S4 (u8) 4 -#define ACPI_STATE_S5 (u8) 5 -#define ACPI_S_STATES_MAX ACPI_STATE_S5 -#define ACPI_S_STATE_COUNT 6 - -#define ACPI_STATE_D0 (u8) 0 -#define ACPI_STATE_D1 (u8) 1 -#define ACPI_STATE_D2 (u8) 2 -#define ACPI_STATE_D3 (u8) 3 -#define ACPI_D_STATES_MAX ACPI_STATE_D3 -#define ACPI_D_STATE_COUNT 4 - -#define ACPI_STATE_C0 (u8) 0 -#define ACPI_STATE_C1 (u8) 1 -#define ACPI_STATE_C2 (u8) 2 -#define ACPI_STATE_C3 (u8) 3 -#define ACPI_C_STATES_MAX ACPI_STATE_C3 -#define ACPI_C_STATE_COUNT 4 - -/* - * Sleep type invalid value - */ -#define ACPI_SLEEP_TYPE_MAX 0x7 -#define ACPI_SLEEP_TYPE_INVALID 0xFF - -/* - * Standard notify values - */ -#define ACPI_NOTIFY_BUS_CHECK (u8) 0 -#define ACPI_NOTIFY_DEVICE_CHECK (u8) 1 -#define ACPI_NOTIFY_DEVICE_WAKE (u8) 2 -#define ACPI_NOTIFY_EJECT_REQUEST (u8) 3 -#define ACPI_NOTIFY_DEVICE_CHECK_LIGHT (u8) 4 -#define ACPI_NOTIFY_FREQUENCY_MISMATCH (u8) 5 -#define ACPI_NOTIFY_BUS_MODE_MISMATCH (u8) 6 -#define ACPI_NOTIFY_POWER_FAULT (u8) 7 - - -/* - * Table types. These values are passed to the table related APIs - */ -typedef u32 acpi_table_type; - -#define ACPI_TABLE_RSDP (acpi_table_type) 0 -#define ACPI_TABLE_DSDT (acpi_table_type) 1 -#define ACPI_TABLE_FADT (acpi_table_type) 2 -#define ACPI_TABLE_FACS (acpi_table_type) 3 -#define ACPI_TABLE_PSDT (acpi_table_type) 4 -#define ACPI_TABLE_SSDT (acpi_table_type) 5 -#define ACPI_TABLE_XSDT (acpi_table_type) 6 -#define ACPI_TABLE_MAX 6 -#define NUM_ACPI_TABLES (ACPI_TABLE_MAX+1) - - -/* - * Types associated with ACPI names and objects. The first group of - * values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition - * of the ACPI object_type() operator (See the ACPI Spec). Therefore, - * only add to the first group if the spec changes. - * - * Types must be kept in sync with the global acpi_ns_properties - * and acpi_ns_type_names arrays. - */ -typedef u32 acpi_object_type; - -#define ACPI_TYPE_ANY 0x00 -#define ACPI_TYPE_INTEGER 0x01 /* Byte/Word/Dword/Zero/One/Ones */ -#define ACPI_TYPE_STRING 0x02 -#define ACPI_TYPE_BUFFER 0x03 -#define ACPI_TYPE_PACKAGE 0x04 /* byte_const, multiple data_term/Constant/super_name */ -#define ACPI_TYPE_FIELD_UNIT 0x05 -#define ACPI_TYPE_DEVICE 0x06 /* Name, multiple Node */ -#define ACPI_TYPE_EVENT 0x07 -#define ACPI_TYPE_METHOD 0x08 /* Name, byte_const, multiple Code */ -#define ACPI_TYPE_MUTEX 0x09 -#define ACPI_TYPE_REGION 0x0A -#define ACPI_TYPE_POWER 0x0B /* Name,byte_const,word_const,multi Node */ -#define ACPI_TYPE_PROCESSOR 0x0C /* Name,byte_const,Dword_const,byte_const,multi nm_o */ -#define ACPI_TYPE_THERMAL 0x0D /* Name, multiple Node */ -#define ACPI_TYPE_BUFFER_FIELD 0x0E -#define ACPI_TYPE_DDB_HANDLE 0x0F -#define ACPI_TYPE_DEBUG_OBJECT 0x10 - -#define ACPI_TYPE_EXTERNAL_MAX 0x10 - -/* - * These are object types that do not map directly to the ACPI - * object_type() operator. They are used for various internal purposes only. - * If new predefined ACPI_TYPEs are added (via the ACPI specification), these - * internal types must move upwards. (There is code that depends on these - * values being contiguous with the external types above.) - */ -#define ACPI_TYPE_LOCAL_REGION_FIELD 0x11 -#define ACPI_TYPE_LOCAL_BANK_FIELD 0x12 -#define ACPI_TYPE_LOCAL_INDEX_FIELD 0x13 -#define ACPI_TYPE_LOCAL_REFERENCE 0x14 /* Arg#, Local#, Name, Debug, ref_of, Index */ -#define ACPI_TYPE_LOCAL_ALIAS 0x15 -#define ACPI_TYPE_LOCAL_NOTIFY 0x16 -#define ACPI_TYPE_LOCAL_ADDRESS_HANDLER 0x17 -#define ACPI_TYPE_LOCAL_RESOURCE 0x18 -#define ACPI_TYPE_LOCAL_RESOURCE_FIELD 0x19 -#define ACPI_TYPE_LOCAL_SCOPE 0x1A /* 1 Name, multiple object_list Nodes */ - -#define ACPI_TYPE_NS_NODE_MAX 0x1A /* Last typecode used within a NS Node */ - -/* - * These are special object types that never appear in - * a Namespace node, only in an union acpi_operand_object - */ -#define ACPI_TYPE_LOCAL_EXTRA 0x1B -#define ACPI_TYPE_LOCAL_DATA 0x1C - -#define ACPI_TYPE_LOCAL_MAX 0x1C - -/* All types above here are invalid */ - -#define ACPI_TYPE_INVALID 0x1D -#define ACPI_TYPE_NOT_FOUND 0xFF - - -/* - * Bitmapped ACPI types. Used internally only - */ -#define ACPI_BTYPE_ANY 0x00000000 -#define ACPI_BTYPE_INTEGER 0x00000001 -#define ACPI_BTYPE_STRING 0x00000002 -#define ACPI_BTYPE_BUFFER 0x00000004 -#define ACPI_BTYPE_PACKAGE 0x00000008 -#define ACPI_BTYPE_FIELD_UNIT 0x00000010 -#define ACPI_BTYPE_DEVICE 0x00000020 -#define ACPI_BTYPE_EVENT 0x00000040 -#define ACPI_BTYPE_METHOD 0x00000080 -#define ACPI_BTYPE_MUTEX 0x00000100 -#define ACPI_BTYPE_REGION 0x00000200 -#define ACPI_BTYPE_POWER 0x00000400 -#define ACPI_BTYPE_PROCESSOR 0x00000800 -#define ACPI_BTYPE_THERMAL 0x00001000 -#define ACPI_BTYPE_BUFFER_FIELD 0x00002000 -#define ACPI_BTYPE_DDB_HANDLE 0x00004000 -#define ACPI_BTYPE_DEBUG_OBJECT 0x00008000 -#define ACPI_BTYPE_REFERENCE 0x00010000 -#define ACPI_BTYPE_RESOURCE 0x00020000 - -#define ACPI_BTYPE_COMPUTE_DATA (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER) - -#define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_PACKAGE) -#define ACPI_BTYPE_DATA_REFERENCE (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE) -#define ACPI_BTYPE_DEVICE_OBJECTS (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR) -#define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001FFFF /* ARG or LOCAL */ -#define ACPI_BTYPE_ALL_OBJECTS 0x0000FFFF - -/* - * All I/O - */ -#define ACPI_READ 0 -#define ACPI_WRITE 1 -#define ACPI_IO_MASK 1 - - -/* - * acpi_event Types: Fixed & General Purpose - */ -typedef u32 acpi_event_type; - -#define ACPI_EVENT_FIXED 0 -#define ACPI_EVENT_GPE 1 - -/* - * Fixed events - */ -#define ACPI_EVENT_PMTIMER 0 -#define ACPI_EVENT_GLOBAL 1 -#define ACPI_EVENT_POWER_BUTTON 2 -#define ACPI_EVENT_SLEEP_BUTTON 3 -#define ACPI_EVENT_RTC 4 -#define ACPI_EVENT_MAX 4 -#define ACPI_NUM_FIXED_EVENTS ACPI_EVENT_MAX + 1 - -#define ACPI_GPE_INVALID 0xFF -#define ACPI_GPE_MAX 0xFF -#define ACPI_NUM_GPE 256 - -#define ACPI_EVENT_LEVEL_TRIGGERED 1 -#define ACPI_EVENT_EDGE_TRIGGERED 2 - -/* - * GPEs - */ -#define ACPI_EVENT_WAKE_ENABLE 0x1 -#define ACPI_EVENT_WAKE_DISABLE 0x1 - - -/* - * acpi_event Status: - * ------------- - * The encoding of acpi_event_status is illustrated below. - * Note that a set bit (1) indicates the property is TRUE - * (e.g. if bit 0 is set then the event is enabled). - * +-------------+-+-+-+ - * | Bits 31:3 |2|1|0| - * +-------------+-+-+-+ - * | | | | - * | | | +- Enabled? - * | | +--- Enabled for wake? - * | +----- Set? - * +----------- - */ -typedef u32 acpi_event_status; - -#define ACPI_EVENT_FLAG_DISABLED (acpi_event_status) 0x00 -#define ACPI_EVENT_FLAG_ENABLED (acpi_event_status) 0x01 -#define ACPI_EVENT_FLAG_WAKE_ENABLED (acpi_event_status) 0x02 -#define ACPI_EVENT_FLAG_SET (acpi_event_status) 0x04 - - -/* Notify types */ - -#define ACPI_SYSTEM_NOTIFY 0 -#define ACPI_DEVICE_NOTIFY 1 -#define ACPI_MAX_NOTIFY_HANDLER_TYPE 1 - -#define ACPI_MAX_SYS_NOTIFY 0x7f - - -/* Address Space (Operation Region) Types */ - -typedef u8 acpi_adr_space_type; - -#define ACPI_ADR_SPACE_SYSTEM_MEMORY (acpi_adr_space_type) 0 -#define ACPI_ADR_SPACE_SYSTEM_IO (acpi_adr_space_type) 1 -#define ACPI_ADR_SPACE_PCI_CONFIG (acpi_adr_space_type) 2 -#define ACPI_ADR_SPACE_EC (acpi_adr_space_type) 3 -#define ACPI_ADR_SPACE_SMBUS (acpi_adr_space_type) 4 -#define ACPI_ADR_SPACE_CMOS (acpi_adr_space_type) 5 -#define ACPI_ADR_SPACE_PCI_BAR_TARGET (acpi_adr_space_type) 6 -#define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 7 -#define ACPI_ADR_SPACE_FIXED_HARDWARE (acpi_adr_space_type) 127 - - -/* - * bit_register IDs - * These are bitfields defined within the full ACPI registers - */ -#define ACPI_BITREG_TIMER_STATUS 0x00 -#define ACPI_BITREG_BUS_MASTER_STATUS 0x01 -#define ACPI_BITREG_GLOBAL_LOCK_STATUS 0x02 -#define ACPI_BITREG_POWER_BUTTON_STATUS 0x03 -#define ACPI_BITREG_SLEEP_BUTTON_STATUS 0x04 -#define ACPI_BITREG_RT_CLOCK_STATUS 0x05 -#define ACPI_BITREG_WAKE_STATUS 0x06 - -#define ACPI_BITREG_TIMER_ENABLE 0x07 -#define ACPI_BITREG_GLOBAL_LOCK_ENABLE 0x08 -#define ACPI_BITREG_POWER_BUTTON_ENABLE 0x09 -#define ACPI_BITREG_SLEEP_BUTTON_ENABLE 0x0A -#define ACPI_BITREG_RT_CLOCK_ENABLE 0x0B -#define ACPI_BITREG_WAKE_ENABLE 0x0C - -#define ACPI_BITREG_SCI_ENABLE 0x0D -#define ACPI_BITREG_BUS_MASTER_RLD 0x0E -#define ACPI_BITREG_GLOBAL_LOCK_RELEASE 0x0F -#define ACPI_BITREG_SLEEP_TYPE_A 0x10 -#define ACPI_BITREG_SLEEP_TYPE_B 0x11 -#define ACPI_BITREG_SLEEP_ENABLE 0x12 - -#define ACPI_BITREG_ARB_DISABLE 0x13 - -#define ACPI_BITREG_MAX 0x13 -#define ACPI_NUM_BITREG ACPI_BITREG_MAX + 1 - - -/* - * External ACPI object definition - */ -union acpi_object -{ - acpi_object_type type; /* See definition of acpi_ns_type for values */ - struct - { - acpi_object_type type; - acpi_integer value; /* The actual number */ - } integer; - - struct - { - acpi_object_type type; - u32 length; /* # of bytes in string, excluding trailing null */ - char *pointer; /* points to the string value */ - } string; - - struct - { - acpi_object_type type; - u32 length; /* # of bytes in buffer */ - u8 *pointer; /* points to the buffer */ - } buffer; - - struct - { - acpi_object_type type; - u32 fill1; - acpi_handle handle; /* object reference */ - } reference; - - struct - { - acpi_object_type type; - u32 count; /* # of elements in package */ - union acpi_object *elements; /* Pointer to an array of ACPI_OBJECTs */ - } package; - - struct - { - acpi_object_type type; - u32 proc_id; - acpi_io_address pblk_address; - u32 pblk_length; - } processor; - - struct - { - acpi_object_type type; - u32 system_level; - u32 resource_order; - } power_resource; -}; - - -/* - * List of objects, used as a parameter list for control method evaluation - */ -struct acpi_object_list -{ - u32 count; - union acpi_object *pointer; -}; - - -/* - * Miscellaneous common Data Structures used by the interfaces - */ -#define ACPI_NO_BUFFER 0 -#define ACPI_ALLOCATE_BUFFER (acpi_size) (-1) -#define ACPI_ALLOCATE_LOCAL_BUFFER (acpi_size) (-2) - -struct acpi_buffer -{ - acpi_size length; /* Length in bytes of the buffer */ - void *pointer; /* pointer to buffer */ -}; - - -/* - * name_type for acpi_get_name - */ -#define ACPI_FULL_PATHNAME 0 -#define ACPI_SINGLE_NAME 1 -#define ACPI_NAME_TYPE_MAX 1 - - -/* - * Structure and flags for acpi_get_system_info - */ -#define ACPI_SYS_MODE_UNKNOWN 0x0000 -#define ACPI_SYS_MODE_ACPI 0x0001 -#define ACPI_SYS_MODE_LEGACY 0x0002 -#define ACPI_SYS_MODES_MASK 0x0003 - - -/* - * ACPI Table Info. One per ACPI table _type_ - */ -struct acpi_table_info -{ - u32 count; -}; - - -/* - * System info returned by acpi_get_system_info() - */ -struct acpi_system_info -{ - u32 acpi_ca_version; - u32 flags; - u32 timer_resolution; - u32 reserved1; - u32 reserved2; - u32 debug_level; - u32 debug_layer; - u32 num_table_types; - struct acpi_table_info table_info [NUM_ACPI_TABLES]; -}; - - -/* - * Various handlers and callback procedures - */ -typedef -u32 (*acpi_event_handler) ( - void *context); - -typedef -void (*acpi_gpe_handler) ( - void *context); - -typedef -void (*acpi_notify_handler) ( - acpi_handle device, - u32 value, - void *context); - -typedef -void (*acpi_object_handler) ( - acpi_handle object, - u32 function, - void *data); - -typedef -acpi_status (*acpi_init_handler) ( - acpi_handle object, - u32 function); - -#define ACPI_INIT_DEVICE_INI 1 - - -/* Address Spaces (Operation Regions */ - -typedef -acpi_status (*acpi_adr_space_handler) ( - u32 function, - acpi_physical_address address, - u32 bit_width, - acpi_integer *value, - void *handler_context, - void *region_context); - -#define ACPI_DEFAULT_HANDLER NULL - - -typedef -acpi_status (*acpi_adr_space_setup) ( - acpi_handle region_handle, - u32 function, - void *handler_context, - void **region_context); - -#define ACPI_REGION_ACTIVATE 0 -#define ACPI_REGION_DEACTIVATE 1 - -typedef -acpi_status (*acpi_walk_callback) ( - acpi_handle obj_handle, - u32 nesting_level, - void *context, - void **return_value); - - -/* Interrupt handler return values */ - -#define ACPI_INTERRUPT_NOT_HANDLED 0x00 -#define ACPI_INTERRUPT_HANDLED 0x01 - - -/* Structure and flags for acpi_get_device_info */ - -#define ACPI_VALID_HID 0x1 -#define ACPI_VALID_UID 0x2 -#define ACPI_VALID_ADR 0x4 -#define ACPI_VALID_STA 0x8 - - -#define ACPI_COMMON_OBJ_INFO \ - acpi_object_type type; /* ACPI object type */ \ - acpi_name name /* ACPI object Name */ - - -struct acpi_obj_info_header -{ - ACPI_COMMON_OBJ_INFO; -}; - - -struct acpi_device_info -{ - ACPI_COMMON_OBJ_INFO; - - u32 valid; /* Are the next bits legit? */ - char hardware_id[9]; /* _HID value if any */ - char unique_id[9]; /* _UID value if any */ - acpi_integer address; /* _ADR value if any */ - u32 current_status; /* _STA value */ -}; - - -/* Context structs for address space handlers */ - -struct acpi_pci_id -{ - u16 segment; - u16 bus; - u16 device; - u16 function; -}; - - -struct acpi_mem_space_context -{ - u32 length; - acpi_physical_address address; - acpi_physical_address mapped_physical_address; - u8 *mapped_logical_address; - acpi_size mapped_length; -}; - - -/* - * Definitions for Resource Attributes - */ - -/* - * Memory Attributes - */ -#define ACPI_READ_ONLY_MEMORY (u8) 0x00 -#define ACPI_READ_WRITE_MEMORY (u8) 0x01 - -#define ACPI_NON_CACHEABLE_MEMORY (u8) 0x00 -#define ACPI_CACHABLE_MEMORY (u8) 0x01 -#define ACPI_WRITE_COMBINING_MEMORY (u8) 0x02 -#define ACPI_PREFETCHABLE_MEMORY (u8) 0x03 - -/* - * IO Attributes - * The ISA Io ranges are: n000-n0_ffh, n400-n4_ffh, n800-n8_ffh, n_c00-n_cFFh. - * The non-ISA Io ranges are: n100-n3_ffh, n500-n7_ffh, n900-n_bFfh, n_cd0-n_fFFh. - */ -#define ACPI_NON_ISA_ONLY_RANGES (u8) 0x01 -#define ACPI_ISA_ONLY_RANGES (u8) 0x02 -#define ACPI_ENTIRE_RANGE (ACPI_NON_ISA_ONLY_RANGES | ACPI_ISA_ONLY_RANGES) - -/* - * IO Port Descriptor Decode - */ -#define ACPI_DECODE_10 (u8) 0x00 /* 10-bit IO address decode */ -#define ACPI_DECODE_16 (u8) 0x01 /* 16-bit IO address decode */ - -/* - * IRQ Attributes - */ -#define ACPI_EDGE_SENSITIVE (u8) 0x00 -#define ACPI_LEVEL_SENSITIVE (u8) 0x01 - -#define ACPI_ACTIVE_HIGH (u8) 0x00 -#define ACPI_ACTIVE_LOW (u8) 0x01 - -#define ACPI_EXCLUSIVE (u8) 0x00 -#define ACPI_SHARED (u8) 0x01 - -/* - * DMA Attributes - */ -#define ACPI_COMPATIBILITY (u8) 0x00 -#define ACPI_TYPE_A (u8) 0x01 -#define ACPI_TYPE_B (u8) 0x02 -#define ACPI_TYPE_F (u8) 0x03 - -#define ACPI_NOT_BUS_MASTER (u8) 0x00 -#define ACPI_BUS_MASTER (u8) 0x01 - -#define ACPI_TRANSFER_8 (u8) 0x00 -#define ACPI_TRANSFER_8_16 (u8) 0x01 -#define ACPI_TRANSFER_16 (u8) 0x02 - -/* - * Start Dependent Functions Priority definitions - */ -#define ACPI_GOOD_CONFIGURATION (u8) 0x00 -#define ACPI_ACCEPTABLE_CONFIGURATION (u8) 0x01 -#define ACPI_SUB_OPTIMAL_CONFIGURATION (u8) 0x02 - -/* - * 16, 32 and 64-bit Address Descriptor resource types - */ -#define ACPI_MEMORY_RANGE (u8) 0x00 -#define ACPI_IO_RANGE (u8) 0x01 -#define ACPI_BUS_NUMBER_RANGE (u8) 0x02 - -#define ACPI_ADDRESS_NOT_FIXED (u8) 0x00 -#define ACPI_ADDRESS_FIXED (u8) 0x01 - -#define ACPI_POS_DECODE (u8) 0x00 -#define ACPI_SUB_DECODE (u8) 0x01 - -#define ACPI_PRODUCER (u8) 0x00 -#define ACPI_CONSUMER (u8) 0x01 - - -/* - * Structures used to describe device resources - */ -struct acpi_resource_irq -{ - u32 edge_level; - u32 active_high_low; - u32 shared_exclusive; - u32 number_of_interrupts; - u32 interrupts[1]; -}; - -struct acpi_resource_dma -{ - u32 type; - u32 bus_master; - u32 transfer; - u32 number_of_channels; - u32 channels[1]; -}; - -struct acpi_resource_start_dpf -{ - u32 compatibility_priority; - u32 performance_robustness; -}; - -/* - * END_DEPENDENT_FUNCTIONS_RESOURCE struct is not - * needed because it has no fields - */ - -struct acpi_resource_io -{ - u32 io_decode; - u32 min_base_address; - u32 max_base_address; - u32 alignment; - u32 range_length; -}; - -struct acpi_resource_fixed_io -{ - u32 base_address; - u32 range_length; -}; - -struct acpi_resource_vendor -{ - u32 length; - u8 reserved[1]; -}; - -struct acpi_resource_end_tag -{ - u8 checksum; -}; - -struct acpi_resource_mem24 -{ - u32 read_write_attribute; - u32 min_base_address; - u32 max_base_address; - u32 alignment; - u32 range_length; -}; - -struct acpi_resource_mem32 -{ - u32 read_write_attribute; - u32 min_base_address; - u32 max_base_address; - u32 alignment; - u32 range_length; -}; - -struct acpi_resource_fixed_mem32 -{ - u32 read_write_attribute; - u32 range_base_address; - u32 range_length; -}; - -struct acpi_memory_attribute -{ - u16 cache_attribute; - u16 read_write_attribute; -}; - -struct acpi_io_attribute -{ - u16 range_attribute; - u16 reserved; -}; - -struct acpi_bus_attribute -{ - u16 reserved1; - u16 reserved2; -}; - -union acpi_resource_attribute -{ - struct acpi_memory_attribute memory; - struct acpi_io_attribute io; - struct acpi_bus_attribute bus; -}; - -struct acpi_resource_source -{ - u32 index; - u32 string_length; - char *string_ptr; -}; - -struct acpi_resource_address16 -{ - u32 resource_type; - u32 producer_consumer; - u32 decode; - u32 min_address_fixed; - u32 max_address_fixed; - union acpi_resource_attribute attribute; - u32 granularity; - u32 min_address_range; - u32 max_address_range; - u32 address_translation_offset; - u32 address_length; - struct acpi_resource_source resource_source; -}; - -struct acpi_resource_address32 -{ - u32 resource_type; - u32 producer_consumer; - u32 decode; - u32 min_address_fixed; - u32 max_address_fixed; - union acpi_resource_attribute attribute; - u32 granularity; - u32 min_address_range; - u32 max_address_range; - u32 address_translation_offset; - u32 address_length; - struct acpi_resource_source resource_source; -}; - -struct acpi_resource_address64 -{ - u32 resource_type; - u32 producer_consumer; - u32 decode; - u32 min_address_fixed; - u32 max_address_fixed; - union acpi_resource_attribute attribute; - u64 granularity; - u64 min_address_range; - u64 max_address_range; - u64 address_translation_offset; - u64 address_length; - struct acpi_resource_source resource_source; -}; - -struct acpi_resource_ext_irq -{ - u32 producer_consumer; - u32 edge_level; - u32 active_high_low; - u32 shared_exclusive; - u32 number_of_interrupts; - struct acpi_resource_source resource_source; - u32 interrupts[1]; -}; - - -/* ACPI_RESOURCE_TYPEs */ - -#define ACPI_RSTYPE_IRQ 0 -#define ACPI_RSTYPE_DMA 1 -#define ACPI_RSTYPE_START_DPF 2 -#define ACPI_RSTYPE_END_DPF 3 -#define ACPI_RSTYPE_IO 4 -#define ACPI_RSTYPE_FIXED_IO 5 -#define ACPI_RSTYPE_VENDOR 6 -#define ACPI_RSTYPE_END_TAG 7 -#define ACPI_RSTYPE_MEM24 8 -#define ACPI_RSTYPE_MEM32 9 -#define ACPI_RSTYPE_FIXED_MEM32 10 -#define ACPI_RSTYPE_ADDRESS16 11 -#define ACPI_RSTYPE_ADDRESS32 12 -#define ACPI_RSTYPE_ADDRESS64 13 -#define ACPI_RSTYPE_EXT_IRQ 14 - -typedef u32 acpi_resource_type; - -union acpi_resource_data -{ - struct acpi_resource_irq irq; - struct acpi_resource_dma dma; - struct acpi_resource_start_dpf start_dpf; - struct acpi_resource_io io; - struct acpi_resource_fixed_io fixed_io; - struct acpi_resource_vendor vendor_specific; - struct acpi_resource_end_tag end_tag; - struct acpi_resource_mem24 memory24; - struct acpi_resource_mem32 memory32; - struct acpi_resource_fixed_mem32 fixed_memory32; - struct acpi_resource_address16 address16; - struct acpi_resource_address32 address32; - struct acpi_resource_address64 address64; - struct acpi_resource_ext_irq extended_irq; -}; - -struct acpi_resource -{ - acpi_resource_type id; - u32 length; - union acpi_resource_data data; -}; - -#define ACPI_RESOURCE_LENGTH 12 -#define ACPI_RESOURCE_LENGTH_NO_DATA 8 /* Id + Length fields */ - -#define ACPI_SIZEOF_RESOURCE(type) (ACPI_RESOURCE_LENGTH_NO_DATA + sizeof (type)) - -#define ACPI_NEXT_RESOURCE(res) (struct acpi_resource *)((u8 *) res + res->length) - -#ifdef _HW_ALIGNMENT_SUPPORT -#define ACPI_ALIGN_RESOURCE_SIZE(length) (length) -#else -#define ACPI_ALIGN_RESOURCE_SIZE(length) ACPI_ROUND_UP_TO_NATIVE_WORD(length) -#endif - -/* - * END: of definitions for Resource Attributes - */ - - -struct acpi_pci_routing_table -{ - u32 length; - u32 pin; - acpi_integer address; /* here for 64-bit alignment */ - u32 source_index; - char source[4]; /* pad to 64 bits so sizeof() works in all cases */ -}; - -/* - * END: of definitions for PCI Routing tables - */ - - -#endif /* __ACTYPES_H__ */ diff -Nru a/drivers/acpi/include/acutils.h b/drivers/acpi/include/acutils.h --- a/drivers/acpi/include/acutils.h Sun Feb 9 21:13:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,815 +0,0 @@ -/****************************************************************************** - * - * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef _ACUTILS_H -#define _ACUTILS_H - - -typedef -acpi_status (*acpi_pkg_callback) ( - u8 object_type, - union acpi_operand_object *source_object, - union acpi_generic_state *state, - void *context); - - -acpi_status -acpi_ut_walk_package_tree ( - union acpi_operand_object *source_object, - void *target_object, - acpi_pkg_callback walk_callback, - void *context); - - -struct acpi_pkg_info -{ - u8 *free_space; - acpi_size length; - u32 object_space; - u32 num_packages; -}; - -#define REF_INCREMENT (u16) 0 -#define REF_DECREMENT (u16) 1 -#define REF_FORCE_DELETE (u16) 2 - -/* acpi_ut_dump_buffer */ - -#define DB_BYTE_DISPLAY 1 -#define DB_WORD_DISPLAY 2 -#define DB_DWORD_DISPLAY 4 -#define DB_QWORD_DISPLAY 8 - - -/* Global initialization interfaces */ - -void -acpi_ut_init_globals ( - void); - -void -acpi_ut_terminate ( - void); - - -/* - * ut_init - miscellaneous initialization and shutdown - */ - -acpi_status -acpi_ut_hardware_initialize ( - void); - -void -acpi_ut_subsystem_shutdown ( - void); - -acpi_status -acpi_ut_validate_fadt ( - void); - -/* - * ut_global - Global data structures and procedures - */ - -#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) - -char * -acpi_ut_get_mutex_name ( - u32 mutex_id); - -#endif - -char * -acpi_ut_get_type_name ( - acpi_object_type type); - -char * -acpi_ut_get_object_type_name ( - union acpi_operand_object *obj_desc); - -char * -acpi_ut_get_region_name ( - u8 space_id); - -char * -acpi_ut_get_event_name ( - u32 event_id); - -char -acpi_ut_hex_to_ascii_char ( - acpi_integer integer, - u32 position); - -u8 -acpi_ut_valid_object_type ( - acpi_object_type type); - -acpi_owner_id -acpi_ut_allocate_owner_id ( - u32 id_type); - - -/* - * ut_clib - Local implementations of C library functions - */ - -#ifndef ACPI_USE_SYSTEM_CLIBRARY - -acpi_size -acpi_ut_strlen ( - const char *string); - -char * -acpi_ut_strcpy ( - char *dst_string, - const char *src_string); - -char * -acpi_ut_strncpy ( - char *dst_string, - const char *src_string, - acpi_size count); - -int -acpi_ut_strncmp ( - const char *string1, - const char *string2, - acpi_size count); - -int -acpi_ut_strcmp ( - const char *string1, - const char *string2); - -char * -acpi_ut_strcat ( - char *dst_string, - const char *src_string); - -char * -acpi_ut_strncat ( - char *dst_string, - const char *src_string, - acpi_size count); - -u32 -acpi_ut_strtoul ( - const char *string, - char **terminator, - u32 base); - -char * -acpi_ut_strstr ( - char *string1, - char *string2); - -void * -acpi_ut_memcpy ( - void *dest, - const void *src, - acpi_size count); - -void * -acpi_ut_memset ( - void *dest, - acpi_native_uint value, - acpi_size count); - -int -acpi_ut_to_upper ( - int c); - -int -acpi_ut_to_lower ( - int c); - -extern const u8 _acpi_ctype[]; - -#define _ACPI_XA 0x00 /* extra alphabetic - not supported */ -#define _ACPI_XS 0x40 /* extra space */ -#define _ACPI_BB 0x00 /* BEL, BS, etc. - not supported */ -#define _ACPI_CN 0x20 /* CR, FF, HT, NL, VT */ -#define _ACPI_DI 0x04 /* '0'-'9' */ -#define _ACPI_LO 0x02 /* 'a'-'z' */ -#define _ACPI_PU 0x10 /* punctuation */ -#define _ACPI_SP 0x08 /* space */ -#define _ACPI_UP 0x01 /* 'A'-'Z' */ -#define _ACPI_XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */ - -#define ACPI_IS_DIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_DI)) -#define ACPI_IS_SPACE(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_SP)) -#define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD)) -#define ACPI_IS_UPPER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP)) -#define ACPI_IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO)) -#define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU)) -#define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP)) -#define ACPI_IS_ASCII(c) ((c) < 0x80) - -#endif /* ACPI_USE_SYSTEM_CLIBRARY */ - -/* - * ut_copy - Object construction and conversion interfaces - */ - -acpi_status -acpi_ut_build_simple_object( - union acpi_operand_object *obj, - union acpi_object *user_obj, - u8 *data_space, - u32 *buffer_space_used); - -acpi_status -acpi_ut_build_package_object ( - union acpi_operand_object *obj, - u8 *buffer, - u32 *space_used); - -acpi_status -acpi_ut_copy_ielement_to_eelement ( - u8 object_type, - union acpi_operand_object *source_object, - union acpi_generic_state *state, - void *context); - -acpi_status -acpi_ut_copy_ielement_to_ielement ( - u8 object_type, - union acpi_operand_object *source_object, - union acpi_generic_state *state, - void *context); - -acpi_status -acpi_ut_copy_iobject_to_eobject ( - union acpi_operand_object *obj, - struct acpi_buffer *ret_buffer); - -acpi_status -acpi_ut_copy_esimple_to_isimple( - union acpi_object *user_obj, - union acpi_operand_object **return_obj); - -acpi_status -acpi_ut_copy_eobject_to_iobject ( - union acpi_object *obj, - union acpi_operand_object **internal_obj); - -acpi_status -acpi_ut_copy_isimple_to_isimple ( - union acpi_operand_object *source_obj, - union acpi_operand_object *dest_obj); - -acpi_status -acpi_ut_copy_ipackage_to_ipackage ( - union acpi_operand_object *source_obj, - union acpi_operand_object *dest_obj, - struct acpi_walk_state *walk_state); - -acpi_status -acpi_ut_copy_simple_object ( - union acpi_operand_object *source_desc, - union acpi_operand_object *dest_desc); - -acpi_status -acpi_ut_copy_iobject_to_iobject ( - union acpi_operand_object *source_desc, - union acpi_operand_object **dest_desc, - struct acpi_walk_state *walk_state); - - -/* - * ut_create - Object creation - */ - -acpi_status -acpi_ut_update_object_reference ( - union acpi_operand_object *object, - u16 action); - - -/* - * ut_debug - Debug interfaces - */ - -void -acpi_ut_init_stack_ptr_trace ( - void); - -void -acpi_ut_track_stack_ptr ( - void); - -void -acpi_ut_trace ( - u32 line_number, - struct acpi_debug_print_info *dbg_info); - -void -acpi_ut_trace_ptr ( - u32 line_number, - struct acpi_debug_print_info *dbg_info, - void *pointer); - -void -acpi_ut_trace_u32 ( - u32 line_number, - struct acpi_debug_print_info *dbg_info, - u32 integer); - -void -acpi_ut_trace_str ( - u32 line_number, - struct acpi_debug_print_info *dbg_info, - char *string); - -void -acpi_ut_exit ( - u32 line_number, - struct acpi_debug_print_info *dbg_info); - -void -acpi_ut_status_exit ( - u32 line_number, - struct acpi_debug_print_info *dbg_info, - acpi_status status); - -void -acpi_ut_value_exit ( - u32 line_number, - struct acpi_debug_print_info *dbg_info, - acpi_integer value); - -void -acpi_ut_ptr_exit ( - u32 line_number, - struct acpi_debug_print_info *dbg_info, - u8 *ptr); - -void -acpi_ut_report_info ( - char *module_name, - u32 line_number, - u32 component_id); - -void -acpi_ut_report_error ( - char *module_name, - u32 line_number, - u32 component_id); - -void -acpi_ut_report_warning ( - char *module_name, - u32 line_number, - u32 component_id); - -void -acpi_ut_dump_buffer ( - u8 *buffer, - u32 count, - u32 display, - u32 component_id); - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_debug_print ( - u32 requested_debug_level, - u32 line_number, - struct acpi_debug_print_info *dbg_info, - char *format, - ...) ACPI_PRINTF_LIKE_FUNC; - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_debug_print_raw ( - u32 requested_debug_level, - u32 line_number, - struct acpi_debug_print_info *dbg_info, - char *format, - ...) ACPI_PRINTF_LIKE_FUNC; - - -/* - * ut_delete - Object deletion - */ - -void -acpi_ut_delete_internal_obj ( - union acpi_operand_object *object); - -void -acpi_ut_delete_internal_package_object ( - union acpi_operand_object *object); - -void -acpi_ut_delete_internal_simple_object ( - union acpi_operand_object *object); - -void -acpi_ut_delete_internal_object_list ( - union acpi_operand_object **obj_list); - - -/* - * ut_eval - object evaluation - */ - -/* Method name strings */ - -#define METHOD_NAME__HID "_HID" -#define METHOD_NAME__CID "_CID" -#define METHOD_NAME__UID "_UID" -#define METHOD_NAME__ADR "_ADR" -#define METHOD_NAME__STA "_STA" -#define METHOD_NAME__REG "_REG" -#define METHOD_NAME__SEG "_SEG" -#define METHOD_NAME__BBN "_BBN" -#define METHOD_NAME__PRT "_PRT" - - -acpi_status -acpi_ut_evaluate_object ( - struct acpi_namespace_node *prefix_node, - char *path, - u32 expected_return_btypes, - union acpi_operand_object **return_desc); - -acpi_status -acpi_ut_evaluate_numeric_object ( - char *object_name, - struct acpi_namespace_node *device_node, - acpi_integer *address); - -acpi_status -acpi_ut_execute_HID ( - struct acpi_namespace_node *device_node, - struct acpi_device_id *hid); - -acpi_status -acpi_ut_execute_CID ( - struct acpi_namespace_node *device_node, - struct acpi_device_id *cid); - -acpi_status -acpi_ut_execute_STA ( - struct acpi_namespace_node *device_node, - u32 *status_flags); - -acpi_status -acpi_ut_execute_UID ( - struct acpi_namespace_node *device_node, - struct acpi_device_id *uid); - - -/* - * ut_mutex - mutual exclusion interfaces - */ - -acpi_status -acpi_ut_mutex_initialize ( - void); - -void -acpi_ut_mutex_terminate ( - void); - -acpi_status -acpi_ut_create_mutex ( - acpi_mutex_handle mutex_id); - -acpi_status -acpi_ut_delete_mutex ( - acpi_mutex_handle mutex_id); - -acpi_status -acpi_ut_acquire_mutex ( - acpi_mutex_handle mutex_id); - -acpi_status -acpi_ut_release_mutex ( - acpi_mutex_handle mutex_id); - - -/* - * ut_object - internal object create/delete/cache routines - */ - -union acpi_operand_object * -acpi_ut_create_internal_object_dbg ( - char *module_name, - u32 line_number, - u32 component_id, - acpi_object_type type); - -void * -acpi_ut_allocate_object_desc_dbg ( - char *module_name, - u32 line_number, - u32 component_id); - -#define acpi_ut_create_internal_object(t) acpi_ut_create_internal_object_dbg (_THIS_MODULE,__LINE__,_COMPONENT,t) -#define acpi_ut_allocate_object_desc() acpi_ut_allocate_object_desc_dbg (_THIS_MODULE,__LINE__,_COMPONENT) - -void -acpi_ut_delete_object_desc ( - union acpi_operand_object *object); - -u8 -acpi_ut_valid_internal_object ( - void *object); - -union acpi_operand_object * -acpi_ut_create_buffer_object ( - acpi_size buffer_size); - - -/* - * ut_ref_cnt - Object reference count management - */ - -void -acpi_ut_add_reference ( - union acpi_operand_object *object); - -void -acpi_ut_remove_reference ( - union acpi_operand_object *object); - -/* - * ut_size - Object size routines - */ - -acpi_status -acpi_ut_get_simple_object_size ( - union acpi_operand_object *obj, - acpi_size *obj_length); - -acpi_status -acpi_ut_get_package_object_size ( - union acpi_operand_object *obj, - acpi_size *obj_length); - -acpi_status -acpi_ut_get_object_size( - union acpi_operand_object *obj, - acpi_size *obj_length); - -acpi_status -acpi_ut_get_element_length ( - u8 object_type, - union acpi_operand_object *source_object, - union acpi_generic_state *state, - void *context); - - -/* - * ut_state - Generic state creation/cache routines - */ - -void -acpi_ut_push_generic_state ( - union acpi_generic_state **list_head, - union acpi_generic_state *state); - -union acpi_generic_state * -acpi_ut_pop_generic_state ( - union acpi_generic_state **list_head); - - -union acpi_generic_state * -acpi_ut_create_generic_state ( - void); - -struct acpi_thread_state * -acpi_ut_create_thread_state ( - void); - -union acpi_generic_state * -acpi_ut_create_update_state ( - union acpi_operand_object *object, - u16 action); - -union acpi_generic_state * -acpi_ut_create_pkg_state ( - void *internal_object, - void *external_object, - u16 index); - -acpi_status -acpi_ut_create_update_state_and_push ( - union acpi_operand_object *object, - u16 action, - union acpi_generic_state **state_list); - -acpi_status -acpi_ut_create_pkg_state_and_push ( - void *internal_object, - void *external_object, - u16 index, - union acpi_generic_state **state_list); - -union acpi_generic_state * -acpi_ut_create_control_state ( - void); - -void -acpi_ut_delete_generic_state ( - union acpi_generic_state *state); - -void -acpi_ut_delete_generic_state_cache ( - void); - -void -acpi_ut_delete_object_cache ( - void); - -/* - * utmisc - */ - -void -acpi_ut_print_string ( - char *string, - u8 max_length); - -acpi_status -acpi_ut_divide ( - acpi_integer *in_dividend, - acpi_integer *in_divisor, - acpi_integer *out_quotient, - acpi_integer *out_remainder); - -acpi_status -acpi_ut_short_divide ( - acpi_integer *in_dividend, - u32 divisor, - acpi_integer *out_quotient, - u32 *out_remainder); - -u8 -acpi_ut_valid_acpi_name ( - u32 name); - -u8 -acpi_ut_valid_acpi_character ( - char character); - -acpi_status -acpi_ut_strtoul64 ( - char *string, - u32 base, - acpi_integer *ret_integer); - -char * -acpi_ut_strupr ( - char *src_string); - -u8 * -acpi_ut_get_resource_end_tag ( - union acpi_operand_object *obj_desc); - -u8 -acpi_ut_generate_checksum ( - u8 *buffer, - u32 length); - -u32 -acpi_ut_dword_byte_swap ( - u32 value); - -void -acpi_ut_set_integer_width ( - u8 revision); - -#ifdef ACPI_DEBUG_OUTPUT -void -acpi_ut_display_init_pathname ( - u8 type, - struct acpi_namespace_node *obj_handle, - char *path); - -#endif - - -/* - * Utalloc - memory allocation and object caching - */ - -void * -acpi_ut_acquire_from_cache ( - u32 list_id); - -void -acpi_ut_release_to_cache ( - u32 list_id, - void *object); - -void -acpi_ut_delete_generic_cache ( - u32 list_id); - -acpi_status -acpi_ut_validate_buffer ( - struct acpi_buffer *buffer); - -acpi_status -acpi_ut_initialize_buffer ( - struct acpi_buffer *buffer, - acpi_size required_length); - - -/* Memory allocation functions */ - -void * -acpi_ut_allocate ( - acpi_size size, - u32 component, - char *module, - u32 line); - -void * -acpi_ut_callocate ( - acpi_size size, - u32 component, - char *module, - u32 line); - - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - -void * -acpi_ut_allocate_and_track ( - acpi_size size, - u32 component, - char *module, - u32 line); - -void * -acpi_ut_callocate_and_track ( - acpi_size size, - u32 component, - char *module, - u32 line); - -void -acpi_ut_free_and_track ( - void *address, - u32 component, - char *module, - u32 line); - -struct acpi_debug_mem_block * -acpi_ut_find_allocation ( - u32 list_id, - void *allocation); - -acpi_status -acpi_ut_track_allocation ( - u32 list_id, - struct acpi_debug_mem_block *address, - acpi_size size, - u8 alloc_type, - u32 component, - char *module, - u32 line); - -acpi_status -acpi_ut_remove_allocation ( - u32 list_id, - struct acpi_debug_mem_block *address, - u32 component, - char *module, - u32 line); - -void -acpi_ut_dump_allocation_info ( - void); - -void -acpi_ut_dump_allocations ( - u32 component, - char *module); -#endif - - -#endif /* _ACUTILS_H */ diff -Nru a/drivers/acpi/include/amlcode.h b/drivers/acpi/include/amlcode.h --- a/drivers/acpi/include/amlcode.h Sun Feb 9 21:13:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,477 +0,0 @@ -/****************************************************************************** - * - * Name: amlcode.h - Definitions for AML, as included in "definition blocks" - * Declarations and definitions contained herein are derived - * directly from the ACPI specification. - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __AMLCODE_H__ -#define __AMLCODE_H__ - -/* primary opcodes */ - -#define AML_NULL_CHAR (u16) 0x00 - -#define AML_ZERO_OP (u16) 0x00 -#define AML_ONE_OP (u16) 0x01 -#define AML_UNASSIGNED (u16) 0x02 -#define AML_ALIAS_OP (u16) 0x06 -#define AML_NAME_OP (u16) 0x08 -#define AML_BYTE_OP (u16) 0x0a -#define AML_WORD_OP (u16) 0x0b -#define AML_DWORD_OP (u16) 0x0c -#define AML_STRING_OP (u16) 0x0d -#define AML_QWORD_OP (u16) 0x0e /* ACPI 2.0 */ -#define AML_SCOPE_OP (u16) 0x10 -#define AML_BUFFER_OP (u16) 0x11 -#define AML_PACKAGE_OP (u16) 0x12 -#define AML_VAR_PACKAGE_OP (u16) 0x13 /* ACPI 2.0 */ -#define AML_METHOD_OP (u16) 0x14 -#define AML_DUAL_NAME_PREFIX (u16) 0x2e -#define AML_MULTI_NAME_PREFIX_OP (u16) 0x2f -#define AML_NAME_CHAR_SUBSEQ (u16) 0x30 -#define AML_NAME_CHAR_FIRST (u16) 0x41 -#define AML_OP_PREFIX (u16) 0x5b -#define AML_ROOT_PREFIX (u16) 0x5c -#define AML_PARENT_PREFIX (u16) 0x5e -#define AML_LOCAL_OP (u16) 0x60 -#define AML_LOCAL0 (u16) 0x60 -#define AML_LOCAL1 (u16) 0x61 -#define AML_LOCAL2 (u16) 0x62 -#define AML_LOCAL3 (u16) 0x63 -#define AML_LOCAL4 (u16) 0x64 -#define AML_LOCAL5 (u16) 0x65 -#define AML_LOCAL6 (u16) 0x66 -#define AML_LOCAL7 (u16) 0x67 -#define AML_ARG_OP (u16) 0x68 -#define AML_ARG0 (u16) 0x68 -#define AML_ARG1 (u16) 0x69 -#define AML_ARG2 (u16) 0x6a -#define AML_ARG3 (u16) 0x6b -#define AML_ARG4 (u16) 0x6c -#define AML_ARG5 (u16) 0x6d -#define AML_ARG6 (u16) 0x6e -#define AML_STORE_OP (u16) 0x70 -#define AML_REF_OF_OP (u16) 0x71 -#define AML_ADD_OP (u16) 0x72 -#define AML_CONCAT_OP (u16) 0x73 -#define AML_SUBTRACT_OP (u16) 0x74 -#define AML_INCREMENT_OP (u16) 0x75 -#define AML_DECREMENT_OP (u16) 0x76 -#define AML_MULTIPLY_OP (u16) 0x77 -#define AML_DIVIDE_OP (u16) 0x78 -#define AML_SHIFT_LEFT_OP (u16) 0x79 -#define AML_SHIFT_RIGHT_OP (u16) 0x7a -#define AML_BIT_AND_OP (u16) 0x7b -#define AML_BIT_NAND_OP (u16) 0x7c -#define AML_BIT_OR_OP (u16) 0x7d -#define AML_BIT_NOR_OP (u16) 0x7e -#define AML_BIT_XOR_OP (u16) 0x7f -#define AML_BIT_NOT_OP (u16) 0x80 -#define AML_FIND_SET_LEFT_BIT_OP (u16) 0x81 -#define AML_FIND_SET_RIGHT_BIT_OP (u16) 0x82 -#define AML_DEREF_OF_OP (u16) 0x83 -#define AML_CONCAT_RES_OP (u16) 0x84 /* ACPI 2.0 */ -#define AML_MOD_OP (u16) 0x85 /* ACPI 2.0 */ -#define AML_NOTIFY_OP (u16) 0x86 -#define AML_SIZE_OF_OP (u16) 0x87 -#define AML_INDEX_OP (u16) 0x88 -#define AML_MATCH_OP (u16) 0x89 -#define AML_CREATE_DWORD_FIELD_OP (u16) 0x8a -#define AML_CREATE_WORD_FIELD_OP (u16) 0x8b -#define AML_CREATE_BYTE_FIELD_OP (u16) 0x8c -#define AML_CREATE_BIT_FIELD_OP (u16) 0x8d -#define AML_TYPE_OP (u16) 0x8e -#define AML_CREATE_QWORD_FIELD_OP (u16) 0x8f /* ACPI 2.0 */ -#define AML_LAND_OP (u16) 0x90 -#define AML_LOR_OP (u16) 0x91 -#define AML_LNOT_OP (u16) 0x92 -#define AML_LEQUAL_OP (u16) 0x93 -#define AML_LGREATER_OP (u16) 0x94 -#define AML_LLESS_OP (u16) 0x95 -#define AML_TO_BUFFER_OP (u16) 0x96 /* ACPI 2.0 */ -#define AML_TO_DECSTRING_OP (u16) 0x97 /* ACPI 2.0 */ -#define AML_TO_HEXSTRING_OP (u16) 0x98 /* ACPI 2.0 */ -#define AML_TO_INTEGER_OP (u16) 0x99 /* ACPI 2.0 */ -#define AML_TO_STRING_OP (u16) 0x9c /* ACPI 2.0 */ -#define AML_COPY_OP (u16) 0x9d /* ACPI 2.0 */ -#define AML_MID_OP (u16) 0x9e /* ACPI 2.0 */ -#define AML_CONTINUE_OP (u16) 0x9f /* ACPI 2.0 */ -#define AML_IF_OP (u16) 0xa0 -#define AML_ELSE_OP (u16) 0xa1 -#define AML_WHILE_OP (u16) 0xa2 -#define AML_NOOP_OP (u16) 0xa3 -#define AML_RETURN_OP (u16) 0xa4 -#define AML_BREAK_OP (u16) 0xa5 -#define AML_BREAK_POINT_OP (u16) 0xcc -#define AML_ONES_OP (u16) 0xff - -/* prefixed opcodes */ - -#define AML_EXTOP (u16) 0x005b - - -#define AML_MUTEX_OP (u16) 0x5b01 -#define AML_EVENT_OP (u16) 0x5b02 -#define AML_SHIFT_RIGHT_BIT_OP (u16) 0x5b10 -#define AML_SHIFT_LEFT_BIT_OP (u16) 0x5b11 -#define AML_COND_REF_OF_OP (u16) 0x5b12 -#define AML_CREATE_FIELD_OP (u16) 0x5b13 -#define AML_LOAD_TABLE_OP (u16) 0x5b1f /* ACPI 2.0 */ -#define AML_LOAD_OP (u16) 0x5b20 -#define AML_STALL_OP (u16) 0x5b21 -#define AML_SLEEP_OP (u16) 0x5b22 -#define AML_ACQUIRE_OP (u16) 0x5b23 -#define AML_SIGNAL_OP (u16) 0x5b24 -#define AML_WAIT_OP (u16) 0x5b25 -#define AML_RESET_OP (u16) 0x5b26 -#define AML_RELEASE_OP (u16) 0x5b27 -#define AML_FROM_BCD_OP (u16) 0x5b28 -#define AML_TO_BCD_OP (u16) 0x5b29 -#define AML_UNLOAD_OP (u16) 0x5b2a -#define AML_REVISION_OP (u16) 0x5b30 -#define AML_DEBUG_OP (u16) 0x5b31 -#define AML_FATAL_OP (u16) 0x5b32 -#define AML_REGION_OP (u16) 0x5b80 -#define AML_FIELD_OP (u16) 0x5b81 -#define AML_DEVICE_OP (u16) 0x5b82 -#define AML_PROCESSOR_OP (u16) 0x5b83 -#define AML_POWER_RES_OP (u16) 0x5b84 -#define AML_THERMAL_ZONE_OP (u16) 0x5b85 -#define AML_INDEX_FIELD_OP (u16) 0x5b86 -#define AML_BANK_FIELD_OP (u16) 0x5b87 -#define AML_DATA_REGION_OP (u16) 0x5b88 /* ACPI 2.0 */ - - -/* Bogus opcodes (they are actually two separate opcodes) */ - -#define AML_LGREATEREQUAL_OP (u16) 0x9295 -#define AML_LLESSEQUAL_OP (u16) 0x9294 -#define AML_LNOTEQUAL_OP (u16) 0x9293 - - -/* - * Internal opcodes - * Use only "Unknown" AML opcodes, don't attempt to use - * any valid ACPI ASCII values (A-Z, 0-9, '-') - */ - -#define AML_INT_NAMEPATH_OP (u16) 0x002d -#define AML_INT_NAMEDFIELD_OP (u16) 0x0030 -#define AML_INT_RESERVEDFIELD_OP (u16) 0x0031 -#define AML_INT_ACCESSFIELD_OP (u16) 0x0032 -#define AML_INT_BYTELIST_OP (u16) 0x0033 -#define AML_INT_STATICSTRING_OP (u16) 0x0034 -#define AML_INT_METHODCALL_OP (u16) 0x0035 -#define AML_INT_RETURN_VALUE_OP (u16) 0x0036 -#define AML_INT_EVAL_SUBTREE_OP (u16) 0x0037 - - -#define ARG_NONE 0x0 - -/* - * Argument types for the AML Parser - * Each field in the arg_types u32 is 5 bits, allowing for a maximum of 6 arguments. - * There can be up to 31 unique argument types - */ - -#define ARGP_BYTEDATA 0x01 -#define ARGP_BYTELIST 0x02 -#define ARGP_CHARLIST 0x03 -#define ARGP_DATAOBJ 0x04 -#define ARGP_DATAOBJLIST 0x05 -#define ARGP_DWORDDATA 0x06 -#define ARGP_FIELDLIST 0x07 -#define ARGP_NAME 0x08 -#define ARGP_NAMESTRING 0x09 -#define ARGP_OBJLIST 0x0A -#define ARGP_PKGLENGTH 0x0B -#define ARGP_SUPERNAME 0x0C -#define ARGP_TARGET 0x0D -#define ARGP_TERMARG 0x0E -#define ARGP_TERMLIST 0x0F -#define ARGP_WORDDATA 0x10 -#define ARGP_QWORDDATA 0x11 -#define ARGP_SIMPLENAME 0x12 - -/* - * Resolved argument types for the AML Interpreter - * Each field in the arg_types u32 is 5 bits, allowing for a maximum of 6 arguments. - * There can be up to 31 unique argument types (0 is end-of-arg-list indicator) - * - * Note: If and when 5 bits becomes insufficient, it would probably be best - * to convert to a 6-byte array of argument types, allowing 8 bits per argument. - */ - -/* "Standard" ACPI types are 1-15 (0x0F) */ - -#define ARGI_INTEGER ACPI_TYPE_INTEGER /* 1 */ -#define ARGI_STRING ACPI_TYPE_STRING /* 2 */ -#define ARGI_BUFFER ACPI_TYPE_BUFFER /* 3 */ -#define ARGI_PACKAGE ACPI_TYPE_PACKAGE /* 4 */ -#define ARGI_EVENT ACPI_TYPE_EVENT -#define ARGI_MUTEX ACPI_TYPE_MUTEX -#define ARGI_REGION ACPI_TYPE_REGION -#define ARGI_DDBHANDLE ACPI_TYPE_DDB_HANDLE - -/* Custom types are 0x10 through 0x1F */ - -#define ARGI_IF 0x10 -#define ARGI_ANYOBJECT 0x11 -#define ARGI_ANYTYPE 0x12 -#define ARGI_COMPUTEDATA 0x13 /* Buffer, String, or Integer */ -#define ARGI_DATAOBJECT 0x14 /* Buffer, String, package or reference to a Node - Used only by size_of operator*/ -#define ARGI_COMPLEXOBJ 0x15 /* Buffer, String, or package (Used by INDEX op only) */ -#define ARGI_INTEGER_REF 0x16 -#define ARGI_OBJECT_REF 0x17 -#define ARGI_DEVICE_REF 0x18 -#define ARGI_REFERENCE 0x19 -#define ARGI_TARGETREF 0x1A /* Target, subject to implicit conversion */ -#define ARGI_FIXED_TARGET 0x1B /* Target, no implicit conversion */ -#define ARGI_SIMPLE_TARGET 0x1C /* Name, Local, Arg -- no implicit conversion */ -#define ARGI_BUFFERSTRING 0x1D -#define ARGI_REF_OR_STRING 0x1E /* Reference or String (Used by DEREFOF op only) */ - -#define ARGI_INVALID_OPCODE 0xFFFFFFFF - - -/* - * hash offsets - */ -#define AML_EXTOP_HASH_OFFSET 22 -#define AML_LNOT_HASH_OFFSET 19 - - -/* - * opcode groups and types - */ - -#define OPGRP_NAMED 0x01 -#define OPGRP_FIELD 0x02 -#define OPGRP_BYTELIST 0x04 - - -/* - * Opcode information - */ - -/* Opcode flags */ - -#define AML_HAS_ARGS 0x0800 -#define AML_HAS_TARGET 0x0400 -#define AML_HAS_RETVAL 0x0200 -#define AML_NSOBJECT 0x0100 -#define AML_NSOPCODE 0x0080 -#define AML_NSNODE 0x0040 -#define AML_NAMED 0x0020 -#define AML_DEFER 0x0010 -#define AML_FIELD 0x0008 -#define AML_CREATE 0x0004 -#define AML_MATH 0x0002 -#define AML_LOGICAL 0x0001 -#define AML_CONSTANT 0x1000 - -/* Convenient flag groupings */ - -#define AML_FLAGS_EXEC_1A_0T_0R AML_HAS_ARGS /* Monadic1 */ -#define AML_FLAGS_EXEC_1A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Monadic2 */ -#define AML_FLAGS_EXEC_1A_1T_0R AML_HAS_ARGS | AML_HAS_TARGET -#define AML_FLAGS_EXEC_1A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* monadic2_r */ -#define AML_FLAGS_EXEC_2A_0T_0R AML_HAS_ARGS /* Dyadic1 */ -#define AML_FLAGS_EXEC_2A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Dyadic2 */ -#define AML_FLAGS_EXEC_2A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* dyadic2_r */ -#define AML_FLAGS_EXEC_2A_2T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL -#define AML_FLAGS_EXEC_3A_0T_0R AML_HAS_ARGS -#define AML_FLAGS_EXEC_3A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL -#define AML_FLAGS_EXEC_6A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL - - -/* - * The opcode Type is used in a dispatch table, do not change - * without updating the table. - */ -#define AML_TYPE_EXEC_1A_0T_0R 0x00 /* Monadic1 */ -#define AML_TYPE_EXEC_1A_0T_1R 0x01 /* Monadic2 */ -#define AML_TYPE_EXEC_1A_1T_0R 0x02 -#define AML_TYPE_EXEC_1A_1T_1R 0x03 /* monadic2_r */ -#define AML_TYPE_EXEC_2A_0T_0R 0x04 /* Dyadic1 */ -#define AML_TYPE_EXEC_2A_0T_1R 0x05 /* Dyadic2 */ -#define AML_TYPE_EXEC_2A_1T_1R 0x06 /* dyadic2_r */ -#define AML_TYPE_EXEC_2A_2T_1R 0x07 -#define AML_TYPE_EXEC_3A_0T_0R 0x08 -#define AML_TYPE_EXEC_3A_1T_1R 0x09 -#define AML_TYPE_EXEC_6A_0T_1R 0x0A -/* End of types used in dispatch table */ - -#define AML_TYPE_LITERAL 0x0B -#define AML_TYPE_CONSTANT 0x0C -#define AML_TYPE_METHOD_ARGUMENT 0x0D -#define AML_TYPE_LOCAL_VARIABLE 0x0E -#define AML_TYPE_DATA_TERM 0x0F - -/* Generic for an op that returns a value */ - -#define AML_TYPE_METHOD_CALL 0x10 - -/* Misc */ - -#define AML_TYPE_CREATE_FIELD 0x11 -#define AML_TYPE_CREATE_OBJECT 0x12 -#define AML_TYPE_CONTROL 0x13 -#define AML_TYPE_NAMED_NO_OBJ 0x14 -#define AML_TYPE_NAMED_FIELD 0x15 -#define AML_TYPE_NAMED_SIMPLE 0x16 -#define AML_TYPE_NAMED_COMPLEX 0x17 -#define AML_TYPE_RETURN 0x18 - -#define AML_TYPE_UNDEFINED 0x19 -#define AML_TYPE_BOGUS 0x1A - - -/* - * Opcode classes - */ -#define AML_CLASS_EXECUTE 0x00 -#define AML_CLASS_CREATE 0x01 -#define AML_CLASS_ARGUMENT 0x02 -#define AML_CLASS_NAMED_OBJECT 0x03 -#define AML_CLASS_CONTROL 0x04 -#define AML_CLASS_ASCII 0x05 -#define AML_CLASS_PREFIX 0x06 -#define AML_CLASS_INTERNAL 0x07 -#define AML_CLASS_RETURN_VALUE 0x08 -#define AML_CLASS_METHOD_CALL 0x09 -#define AML_CLASS_UNKNOWN 0x0A - - -/* Predefined Operation Region space_iDs */ - -typedef enum -{ - REGION_MEMORY = 0, - REGION_IO, - REGION_PCI_CONFIG, - REGION_EC, - REGION_SMBUS, - REGION_CMOS, - REGION_PCI_BAR, - REGION_DATA_TABLE, /* Internal use only */ - REGION_FIXED_HW = 0x7F - -} AML_REGION_TYPES; - - -/* Comparison operation codes for match_op operator */ - -typedef enum -{ - MATCH_MTR = 0, - MATCH_MEQ = 1, - MATCH_MLE = 2, - MATCH_MLT = 3, - MATCH_MGE = 4, - MATCH_MGT = 5 - -} AML_MATCH_OPERATOR; - -#define MAX_MATCH_OPERATOR 5 - - -/* - * field_flags - * - * This byte is extracted from the AML and includes three separate - * pieces of information about the field: - * 1) The field access type - * 2) The field update rule - * 3) The lock rule for the field - * - * Bits 00 - 03 : access_type (any_acc, byte_acc, etc.) - * 04 : lock_rule (1 == Lock) - * 05 - 06 : update_rule - */ -#define AML_FIELD_ACCESS_TYPE_MASK 0x0F -#define AML_FIELD_LOCK_RULE_MASK 0x10 -#define AML_FIELD_UPDATE_RULE_MASK 0x60 - - -/* 1) Field Access Types */ - -typedef enum -{ - AML_FIELD_ACCESS_ANY = 0x00, - AML_FIELD_ACCESS_BYTE = 0x01, - AML_FIELD_ACCESS_WORD = 0x02, - AML_FIELD_ACCESS_DWORD = 0x03, - AML_FIELD_ACCESS_QWORD = 0x04, /* ACPI 2.0 */ - AML_FIELD_ACCESS_BUFFER = 0x05 /* ACPI 2.0 */ - -} AML_ACCESS_TYPE; - - -/* 2) Field Lock Rules */ - -typedef enum -{ - AML_FIELD_LOCK_NEVER = 0x00, - AML_FIELD_LOCK_ALWAYS = 0x10 - -} AML_LOCK_RULE; - - -/* 3) Field Update Rules */ - -typedef enum -{ - AML_FIELD_UPDATE_PRESERVE = 0x00, - AML_FIELD_UPDATE_WRITE_AS_ONES = 0x20, - AML_FIELD_UPDATE_WRITE_AS_ZEROS = 0x40 - -} AML_UPDATE_RULE; - - -/* - * Field Access Attributes. - * This byte is extracted from the AML via the - * access_as keyword - */ -typedef enum -{ - AML_FIELD_ATTRIB_SMB_QUICK = 0x02, - AML_FIELD_ATTRIB_SMB_SEND_RCV = 0x04, - AML_FIELD_ATTRIB_SMB_BYTE = 0x06, - AML_FIELD_ATTRIB_SMB_WORD = 0x08, - AML_FIELD_ATTRIB_SMB_BLOCK = 0x0A, - AML_FIELD_ATTRIB_SMB_WORD_CALL = 0x0C, - AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D - -} AML_ACCESS_ATTRIBUTE; - - -/* bit fields in method_flags byte */ - -#define METHOD_FLAGS_ARG_COUNT 0x07 -#define METHOD_FLAGS_SERIALIZED 0x08 -#define METHOD_FLAGS_SYNCH_LEVEL 0xF0 - - -#endif /* __AMLCODE_H__ */ diff -Nru a/drivers/acpi/include/amlresrc.h b/drivers/acpi/include/amlresrc.h --- a/drivers/acpi/include/amlresrc.h Sun Feb 9 21:13:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,310 +0,0 @@ - -/****************************************************************************** - * - * Module Name: amlresrc.h - AML resource descriptors - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - - -#ifndef __AMLRESRC_H -#define __AMLRESRC_H - - -#define ASL_RESNAME_ADDRESS "_ADR" -#define ASL_RESNAME_ALIGNMENT "_ALN" -#define ASL_RESNAME_ADDRESSSPACE "_ASI" -#define ASL_RESNAME_BASEADDRESS "_BAS" -#define ASL_RESNAME_BUSMASTER "_BM_" /* Master(1), Slave(0) */ -#define ASL_RESNAME_DECODE "_DEC" -#define ASL_RESNAME_DMA "_DMA" -#define ASL_RESNAME_DMATYPE "_TYP" /* Compatible(0), A(1), B(2), F(3) */ -#define ASL_RESNAME_GRANULARITY "_GRA" -#define ASL_RESNAME_INTERRUPT "_INT" -#define ASL_RESNAME_INTERRUPTLEVEL "_LL_" /* active_lo(1), active_hi(0) */ -#define ASL_RESNAME_INTERRUPTSHARE "_SHR" /* Shareable(1), no_share(0) */ -#define ASL_RESNAME_INTERRUPTTYPE "_HE_" /* Edge(1), Level(0) */ -#define ASL_RESNAME_LENGTH "_LEN" -#define ASL_RESNAME_MEMATTRIBUTES "_MTP" /* Memory(0), Reserved(1), ACPI(2), NVS(3) */ -#define ASL_RESNAME_MEMTYPE "_MEM" /* non_cache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */ -#define ASL_RESNAME_MAXADDR "_MAX" -#define ASL_RESNAME_MINADDR "_MIN" -#define ASL_RESNAME_MAXTYPE "_MAF" -#define ASL_RESNAME_MINTYPE "_MIF" -#define ASL_RESNAME_REGISTERBITOFFSET "_RBO" -#define ASL_RESNAME_REGISTERBITWIDTH "_RBW" -#define ASL_RESNAME_RANGETYPE "_RNG" -#define ASL_RESNAME_READWRITETYPE "_RW_" /* read_only(0), Writeable (1) */ -#define ASL_RESNAME_TRANSLATION "_TRA" -#define ASL_RESNAME_TRANSTYPE "_TRS" /* Sparse(1), Dense(0) */ -#define ASL_RESNAME_TYPE "_TTP" /* Translation(1), Static (0) */ -#define ASL_RESNAME_XFERTYPE "_SIz" /* 8(0), 8_and16(1), 16(2) */ - - -/* Default sizes for "small" resource descriptors */ - -#define ASL_RDESC_IRQ_SIZE 0x02 -#define ASL_RDESC_DMA_SIZE 0x02 -#define ASL_RDESC_ST_DEPEND_SIZE 0x00 -#define ASL_RDESC_END_DEPEND_SIZE 0x00 -#define ASL_RDESC_IO_SIZE 0x07 -#define ASL_RDESC_FIXED_IO_SIZE 0x03 -#define ASL_RDESC_END_TAG_SIZE 0x01 - - -struct asl_resource_node -{ - u32 buffer_length; - void *buffer; - struct asl_resource_node *next; -}; - - -/* - * Resource descriptors defined in the ACPI specification. - * - * Alignment must be BYTE because these descriptors - * are used to overlay the AML byte stream. - */ -#pragma pack(1) - -struct asl_irq_format_desc -{ - u8 descriptor_type; - u16 irq_mask; - u8 flags; -}; - - -struct asl_irq_noflags_desc -{ - u8 descriptor_type; - u16 irq_mask; -}; - - -struct asl_dma_format_desc -{ - u8 descriptor_type; - u8 dma_channel_mask; - u8 flags; -}; - - -struct asl_start_dependent_desc -{ - u8 descriptor_type; - u8 flags; -}; - - -struct asl_start_dependent_noprio_desc -{ - u8 descriptor_type; -}; - - -struct asl_end_dependent_desc -{ - u8 descriptor_type; -}; - - -struct asl_io_port_desc -{ - u8 descriptor_type; - u8 information; - u16 address_min; - u16 address_max; - u8 alignment; - u8 length; -}; - - -struct asl_fixed_io_port_desc -{ - u8 descriptor_type; - u16 base_address; - u8 length; -}; - - -struct asl_small_vendor_desc -{ - u8 descriptor_type; - u8 vendor_defined[7]; -}; - - -struct asl_end_tag_desc -{ - u8 descriptor_type; - u8 checksum; -}; - - -/* LARGE descriptors */ - -struct asl_memory_24_desc -{ - u8 descriptor_type; - u16 length; - u8 information; - u16 address_min; - u16 address_max; - u16 alignment; - u16 range_length; -}; - - -struct asl_large_vendor_desc -{ - u8 descriptor_type; - u16 length; - u8 vendor_defined[1]; -}; - - -struct asl_memory_32_desc -{ - u8 descriptor_type; - u16 length; - u8 information; - u32 address_min; - u32 address_max; - u32 alignment; - u32 range_length; -}; - - -struct asl_fixed_memory_32_desc -{ - u8 descriptor_type; - u16 length; - u8 information; - u32 base_address; - u32 range_length; -}; - - -struct asl_qword_address_desc -{ - u8 descriptor_type; - u16 length; - u8 resource_type; - u8 flags; - u8 specific_flags; - u64 granularity; - u64 address_min; - u64 address_max; - u64 translation_offset; - u64 address_length; - u8 optional_fields[2]; -}; - - -struct asl_dword_address_desc -{ - u8 descriptor_type; - u16 length; - u8 resource_type; - u8 flags; - u8 specific_flags; - u32 granularity; - u32 address_min; - u32 address_max; - u32 translation_offset; - u32 address_length; - u8 optional_fields[2]; -}; - - -struct asl_word_address_desc -{ - u8 descriptor_type; - u16 length; - u8 resource_type; - u8 flags; - u8 specific_flags; - u16 granularity; - u16 address_min; - u16 address_max; - u16 translation_offset; - u16 address_length; - u8 optional_fields[2]; -}; - - -struct asl_extended_xrupt_desc -{ - u8 descriptor_type; - u16 length; - u8 flags; - u8 table_length; - u32 interrupt_number[1]; - /* res_source_index, res_source optional fields follow */ -}; - - -struct asl_general_register_desc -{ - u8 descriptor_type; - u16 length; - u8 address_space_id; - u8 bit_width; - u8 bit_offset; - u8 reserved; - u64 address; -}; - -/* restore default alignment */ - -#pragma pack() - -/* Union of all resource descriptors, sow we can allocate the worst case */ - -union asl_resource_desc -{ - struct asl_irq_format_desc irq; - struct asl_dma_format_desc dma; - struct asl_start_dependent_desc std; - struct asl_end_dependent_desc end; - struct asl_io_port_desc iop; - struct asl_fixed_io_port_desc fio; - struct asl_small_vendor_desc smv; - struct asl_end_tag_desc et; - - struct asl_memory_24_desc M24; - struct asl_large_vendor_desc lgv; - struct asl_memory_32_desc M32; - struct asl_fixed_memory_32_desc F32; - struct asl_qword_address_desc qas; - struct asl_dword_address_desc das; - struct asl_word_address_desc was; - struct asl_extended_xrupt_desc exx; - struct asl_general_register_desc grg; - u32 u32_item; - u16 u16_item; - u8 U8item; -}; - - -#endif - diff -Nru a/drivers/acpi/include/platform/acenv.h b/drivers/acpi/include/platform/acenv.h --- a/drivers/acpi/include/platform/acenv.h Sun Feb 9 21:13:29 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,344 +0,0 @@ -/****************************************************************************** - * - * Name: acenv.h - Generation environment specific items - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACENV_H__ -#define __ACENV_H__ - - -/* - * Configuration for ACPI tools and utilities - */ - -#ifdef _ACPI_DUMP_APP -#ifndef MSDOS -#define ACPI_DEBUG_OUTPUT -#endif -#define ACPI_APPLICATION -#define ACPI_DISASSEMBLER -#define ACPI_NO_METHOD_EXECUTION -#define ACPI_USE_SYSTEM_CLIBRARY -#endif - -#ifdef _ACPI_EXEC_APP -#undef DEBUGGER_THREADING -#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED -#define ACPI_DEBUG_OUTPUT -#define ACPI_APPLICATION -#define ACPI_DEBUGGER -#define ACPI_DISASSEMBLER -#define ACPI_USE_SYSTEM_CLIBRARY -#endif - -#ifdef _ACPI_ASL_COMPILER -#define ACPI_DEBUG_OUTPUT -#define ACPI_APPLICATION -#define ACPI_DISASSEMBLER -#define ACPI_CONSTANT_EVAL_ONLY -#define ACPI_USE_SYSTEM_CLIBRARY -#endif - -/* - * Environment configuration. The purpose of this file is to interface to the - * local generation environment. - * - * 1) ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library. - * Otherwise, local versions of string/memory functions will be used. - * 2) ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and - * the standard header files may be used. - * - * The ACPI subsystem only uses low level C library functions that do not call - * operating system services and may therefore be inlined in the code. - * - * It may be necessary to tailor these include files to the target - * generation environment. - * - * - * Functions and constants used from each header: - * - * string.h: memcpy - * memset - * strcat - * strcmp - * strcpy - * strlen - * strncmp - * strncat - * strncpy - * - * stdlib.h: strtoul - * - * stdarg.h: va_list - * va_arg - * va_start - * va_end - * - */ - -/*! [Begin] no source code translation */ - -#if defined(_LINUX) -#include "aclinux.h" - -#elif defined(_AED_EFI) -#include "acefi.h" - -#elif defined(WIN32) -#include "acwin.h" - -#elif defined(WIN64) -#include "acwin64.h" - -#elif defined(MSDOS) /* Must appear after WIN32 and WIN64 check */ -#include "acdos16.h" - -#elif defined(__FreeBSD__) -#include "acfreebsd.h" - -#elif defined(MODESTO) -#include "acmodesto.h" - -#elif defined(NETWARE) -#include "acnetware.h" - -#else - -/* All other environments */ - -#define ACPI_USE_STANDARD_HEADERS - -#define COMPILER_DEPENDENT_INT64 long long -#define COMPILER_DEPENDENT_UINT64 unsigned long long - - -/* Name of host operating system (returned by the _OS_ namespace object) */ - -#define ACPI_OS_NAME "Intel ACPI/CA Core Subsystem" - -/* This macro is used to tag functions as "printf-like" because - * some compilers can catch printf format string problems. MSVC - * doesn't, so this is proprocessed away. - */ -#define ACPI_PRINTF_LIKE_FUNC - -#endif - -/* - * Memory allocation tracking. Used only if - * 1) This is the debug version - * 2) This is NOT a 16-bit version of the code (not enough real-mode memory) - */ -#ifdef ACPI_DEBUG_OUTPUT -#if ACPI_MACHINE_WIDTH != 16 -#define ACPI_DBG_TRACK_ALLOCATIONS -#endif -#endif - -/*! [End] no source code translation !*/ - - -/* - * Debugger threading model - * Use single threaded if the entire subsystem is contained in an application - * Use multiple threaded when the subsystem is running in the kernel. - * - * By default the model is single threaded if ACPI_APPLICATION is set, - * multi-threaded if ACPI_APPLICATION is not set. - */ -#define DEBUGGER_SINGLE_THREADED 0 -#define DEBUGGER_MULTI_THREADED 1 - -#ifdef ACPI_APPLICATION -#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED - -#else -#define DEBUGGER_THREADING DEBUGGER_MULTI_THREADED -#endif - - -/****************************************************************************** - * - * C library configuration - * - *****************************************************************************/ - -#ifdef ACPI_USE_SYSTEM_CLIBRARY -/* - * Use the standard C library headers. - * We want to keep these to a minimum. - */ - -#ifdef ACPI_USE_STANDARD_HEADERS -/* - * Use the standard headers from the standard locations - */ -#include -#include -#include -#include - -#endif /* ACPI_USE_STANDARD_HEADERS */ - -/* - * We will be linking to the standard Clib functions - */ - -#define ACPI_STRSTR(s1,s2) strstr((s1), (s2)) -#define ACPI_STRUPR(s) (void) acpi_ut_strupr ((s)) -#define ACPI_STRLEN(s) (acpi_size) strlen((s)) -#define ACPI_STRCPY(d,s) (void) strcpy((d), (s)) -#define ACPI_STRNCPY(d,s,n) (void) strncpy((d), (s), (acpi_size)(n)) -#define ACPI_STRNCMP(d,s,n) strncmp((d), (s), (acpi_size)(n)) -#define ACPI_STRCMP(d,s) strcmp((d), (s)) -#define ACPI_STRCAT(d,s) (void) strcat((d), (s)) -#define ACPI_STRNCAT(d,s,n) strncat((d), (s), (acpi_size)(n)) -#define ACPI_STRTOUL(d,s,n) strtoul((d), (s), (acpi_size)(n)) -#define ACPI_MEMCPY(d,s,n) (void) memcpy((d), (s), (acpi_size)(n)) -#define ACPI_MEMSET(d,s,n) (void) memset((d), (s), (acpi_size)(n)) - -#define ACPI_TOUPPER toupper -#define ACPI_TOLOWER tolower -#define ACPI_IS_XDIGIT isxdigit -#define ACPI_IS_DIGIT isdigit -#define ACPI_IS_SPACE isspace -#define ACPI_IS_UPPER isupper -#define ACPI_IS_PRINT isprint -#define ACPI_IS_ALPHA isalpha -#define ACPI_IS_ASCII isascii - -/****************************************************************************** - * - * Not using native C library, use local implementations - * - *****************************************************************************/ -#else - -/* - * Use local definitions of C library macros and functions - * NOTE: The function implementations may not be as efficient - * as an inline or assembly code implementation provided by a - * native C library. - */ - -#ifndef va_arg - -#ifndef _VALIST -#define _VALIST -typedef char *va_list; -#endif /* _VALIST */ - -/* - * Storage alignment properties - */ - -#define _AUPBND (sizeof (acpi_native_int) - 1) -#define _ADNBND (sizeof (acpi_native_int) - 1) - -/* - * Variable argument list macro definitions - */ - -#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd))) -#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND)))) -#define va_end(ap) (void) 0 -#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND)))) - -#endif /* va_arg */ - - -#define ACPI_STRSTR(s1,s2) acpi_ut_strstr ((s1), (s2)) -#define ACPI_STRUPR(s) (void) acpi_ut_strupr ((s)) -#define ACPI_STRLEN(s) (acpi_size) acpi_ut_strlen ((s)) -#define ACPI_STRCPY(d,s) (void) acpi_ut_strcpy ((d), (s)) -#define ACPI_STRNCPY(d,s,n) (void) acpi_ut_strncpy ((d), (s), (acpi_size)(n)) -#define ACPI_STRNCMP(d,s,n) acpi_ut_strncmp ((d), (s), (acpi_size)(n)) -#define ACPI_STRCMP(d,s) acpi_ut_strcmp ((d), (s)) -#define ACPI_STRCAT(d,s) (void) acpi_ut_strcat ((d), (s)) -#define ACPI_STRNCAT(d,s,n) acpi_ut_strncat ((d), (s), (acpi_size)(n)) -#define ACPI_STRTOUL(d,s,n) acpi_ut_strtoul ((d), (s), (acpi_size)(n)) -#define ACPI_MEMCPY(d,s,n) (void) acpi_ut_memcpy ((d), (s), (acpi_size)(n)) -#define ACPI_MEMSET(d,v,n) (void) acpi_ut_memset ((d), (v), (acpi_size)(n)) -#define ACPI_TOUPPER acpi_ut_to_upper -#define ACPI_TOLOWER acpi_ut_to_lower - -#endif /* ACPI_USE_SYSTEM_CLIBRARY */ - - -/****************************************************************************** - * - * Assembly code macros - * - *****************************************************************************/ - -/* - * Handle platform- and compiler-specific assembly language differences. - * These should already have been defined by the platform includes above. - * - * Notes: - * 1) Interrupt 3 is used to break into a debugger - * 2) Interrupts are turned off during ACPI register setup - */ - -/* Unrecognized compiler, use defaults */ - -#ifndef ACPI_ASM_MACROS - -/* - * Calling conventions: - * - * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) - * ACPI_EXTERNAL_XFACE - External ACPI interfaces - * ACPI_INTERNAL_XFACE - Internal ACPI interfaces - * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces - */ -#define ACPI_SYSTEM_XFACE -#define ACPI_EXTERNAL_XFACE -#define ACPI_INTERNAL_XFACE -#define ACPI_INTERNAL_VAR_XFACE - -#define ACPI_ASM_MACROS -#define BREAKPOINT3 -#define ACPI_DISABLE_IRQS() -#define ACPI_ENABLE_IRQS() -#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acq) -#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, acq) - -#endif /* ACPI_ASM_MACROS */ - - -#ifdef ACPI_APPLICATION - -/* Don't want software interrupts within a ring3 application */ - -#undef BREAKPOINT3 -#define BREAKPOINT3 -#endif - - -/****************************************************************************** - * - * Compiler-specific information is contained in the compiler-specific - * headers. - * - *****************************************************************************/ -#endif /* __ACENV_H__ */ diff -Nru a/drivers/acpi/include/platform/acgcc.h b/drivers/acpi/include/platform/acgcc.h --- a/drivers/acpi/include/platform/acgcc.h Sun Feb 9 21:13:36 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,40 +0,0 @@ -/****************************************************************************** - * - * Name: acgcc.h - GCC specific defines, etc. - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACGCC_H__ -#define __ACGCC_H__ - -/* This macro is used to tag functions as "printf-like" because - * some compilers (like GCC) can catch printf format string problems. - */ -#define ACPI_PRINTF_LIKE_FUNC __attribute__ ((__format__ (__printf__, 4, 5))) - -/* Some compilers complain about unused variables. Sometimes we don't want to - * use all the variables (most specifically for _THIS_MODULE). This allow us - * to to tell the compiler warning in a per-variable manner that a variable - * is unused. - */ -#define ACPI_UNUSED_VAR __attribute__ ((unused)) - -#endif /* __ACGCC_H__ */ diff -Nru a/drivers/acpi/include/platform/aclinux.h b/drivers/acpi/include/platform/aclinux.h --- a/drivers/acpi/include/platform/aclinux.h Sun Feb 9 21:13:35 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,72 +0,0 @@ -/****************************************************************************** - * - * Name: aclinux.h - OS specific defines, etc. - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2003, R. Byron Moore - * - * 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 - */ - -#ifndef __ACLINUX_H__ -#define __ACLINUX_H__ - -#define ACPI_OS_NAME "Linux" - -#define ACPI_USE_SYSTEM_CLIBRARY - -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define strtoul simple_strtoul - -#define ACPI_MACHINE_WIDTH BITS_PER_LONG - -#else /* !__KERNEL__ */ - -#include -#include -#include -#include -#include - -#if defined(__ia64__) || defined(__x86_64__) -#define ACPI_MACHINE_WIDTH 64 -#define COMPILER_DEPENDENT_INT64 long -#define COMPILER_DEPENDENT_UINT64 unsigned long -#else -#define ACPI_MACHINE_WIDTH 32 -#define COMPILER_DEPENDENT_INT64 long long -#define COMPILER_DEPENDENT_UINT64 unsigned long long -#define ACPI_USE_NATIVE_DIVIDE -#endif - -#endif /* __KERNEL__ */ - -/* Linux uses GCC */ - -#include "acgcc.h" - -#endif /* __ACLINUX_H__ */ diff -Nru a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c --- a/drivers/acpi/namespace/nsload.c Sun Feb 9 21:13:36 2003 +++ b/drivers/acpi/namespace/nsload.c Sun Feb 9 21:13:36 2003 @@ -75,9 +75,11 @@ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "AML block at %p\n", table_desc->aml_start)); + /* Ignore table if there is no AML contained within */ + if (!table_desc->aml_length) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Zero-length AML block\n")); - return_ACPI_STATUS (AE_BAD_PARAMETER); + ACPI_REPORT_WARNING (("Zero-length AML block in table [%4.4s]\n", table_desc->pointer->signature)); + return_ACPI_STATUS (AE_OK); } /* diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c --- a/drivers/acpi/osl.c Sun Feb 9 21:13:35 2003 +++ b/drivers/acpi/osl.c Sun Feb 9 21:13:35 2003 @@ -35,9 +35,9 @@ #include #include #include +#include #include #include "acpi_bus.h" -#include "acpi.h" #ifdef CONFIG_ACPI_EFI #include diff -Nru a/drivers/acpi/power.c b/drivers/acpi/power.c --- a/drivers/acpi/power.c Sun Feb 9 21:13:32 2003 +++ b/drivers/acpi/power.c Sun Feb 9 21:13:32 2003 @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include "acpi_bus.h" diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c --- a/drivers/acpi/processor.c Sun Feb 9 21:13:34 2003 +++ b/drivers/acpi/processor.c Sun Feb 9 21:13:34 2003 @@ -35,18 +35,19 @@ #include #include #include -#include -#include -#include +#include #include #include #include + +#include +#include +#include + #include "acpi_bus.h" #include "acpi_drivers.h" +#include "processor.h" -#ifdef CONFIG_ACPI_PROCESSOR_PERF -#include -#endif #define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_CLASS "processor" @@ -64,17 +65,6 @@ #define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ #define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ -#define ACPI_PROCESSOR_BUSY_METRIC 10 - -#define ACPI_PROCESSOR_MAX_POWER ACPI_C_STATE_COUNT -#define ACPI_PROCESSOR_MAX_C2_LATENCY 100 -#define ACPI_PROCESSOR_MAX_C3_LATENCY 1000 - -#define ACPI_PROCESSOR_MAX_PERFORMANCE 8 - -#define ACPI_PROCESSOR_MAX_THROTTLING 16 -#define ACPI_PROCESSOR_MAX_THROTTLE 250 /* 25% */ -#define ACPI_PROCESSOR_MAX_DUTY_WIDTH 4 const u32 POWER_OF_2[] = {1,2,4,8,16,32,64}; @@ -107,118 +97,6 @@ }, }; -/* Power Management */ - -struct acpi_processor_cx_policy { - u32 count; - int state; - struct { - u32 time; - u32 ticks; - u32 count; - u32 bm; - } threshold; -}; - -struct acpi_processor_cx { - u8 valid; - u32 address; - u32 latency; - u32 latency_ticks; - u32 power; - u32 usage; - struct acpi_processor_cx_policy promotion; - struct acpi_processor_cx_policy demotion; -}; - -struct acpi_processor_power { - int state; - int default_state; - u32 bm_activity; - struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER]; -}; - -/* Performance Management */ - -struct acpi_pct_register { - u8 descriptor; - u16 length; - u8 space_id; - u8 bit_width; - u8 bit_offset; - u8 reserved; - u64 address; -} __attribute__ ((packed)); - -struct acpi_processor_px { - acpi_integer core_frequency; /* megahertz */ - acpi_integer power; /* milliWatts */ - acpi_integer transition_latency; /* microseconds */ - acpi_integer bus_master_latency; /* microseconds */ - acpi_integer control; /* control value */ - acpi_integer status; /* success indicator */ -}; - -struct acpi_processor_performance { - int state; - int platform_limit; - u16 control_register; - u16 status_register; - int state_count; - struct acpi_processor_px states[ACPI_PROCESSOR_MAX_PERFORMANCE]; -}; - - -/* Throttling Control */ - -struct acpi_processor_tx { - u16 power; - u16 performance; -}; - -struct acpi_processor_throttling { - int state; - u32 address; - u8 duty_offset; - u8 duty_width; - int state_count; - struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING]; -}; - -/* Limit Interface */ - -struct acpi_processor_lx { - int px; /* performace state */ - int tx; /* throttle level */ -}; - -struct acpi_processor_limit { - struct acpi_processor_lx state; /* current limit */ - struct acpi_processor_lx thermal; /* thermal limit */ - struct acpi_processor_lx user; /* user limit */ -}; - - -struct acpi_processor_flags { - u8 power:1; - u8 performance:1; - u8 throttling:1; - u8 limit:1; - u8 bm_control:1; - u8 bm_check:1; - u8 reserved:2; -}; - -struct acpi_processor { - acpi_handle handle; - u32 acpi_id; - u32 id; - struct acpi_processor_flags flags; - struct acpi_processor_power power; - struct acpi_processor_performance performance; - struct acpi_processor_throttling throttling; - struct acpi_processor_limit limit; -}; struct acpi_processor_errata { u8 smp; @@ -262,18 +140,6 @@ static struct acpi_processor_errata errata; static void (*pm_idle_save)(void) = NULL; -#ifdef CONFIG_ACPI_PROCESSOR_PERF -static unsigned int cpufreq_usage_count = 0; -static struct cpufreq_driver *acpi_cpufreq_driver; -static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file); -static struct file_operations acpi_processor_perf_fops = { - .open = acpi_processor_perf_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - /* -------------------------------------------------------------------------- Errata Handling @@ -880,8 +746,7 @@ /* -------------------------------------------------------------------------- Performance Management -------------------------------------------------------------------------- */ -#ifdef CONFIG_ACPI_PROCESSOR_PERF -static int +int acpi_processor_get_platform_limit ( struct acpi_processor* pr) { @@ -898,347 +763,38 @@ * (e.g. 0 = states 0..n; 1 = states 1..n; etc. */ status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc); - if(ACPI_FAILURE(status)) { + if(ACPI_FAILURE(status) && status != AE_NOT_FOUND) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PPC\n")); return_VALUE(-ENODEV); } - pr->performance.platform_limit = (int) ppc; + pr->performance_platform_limit = (int) ppc; return_VALUE(0); } +EXPORT_SYMBOL(acpi_processor_get_platform_limit); - -static int -acpi_processor_get_performance_control ( - struct acpi_processor *pr) -{ - int result = 0; - acpi_status status = 0; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - union acpi_object *pct = NULL; - union acpi_object obj = {0}; - struct acpi_pct_register *reg = NULL; - - ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control"); - - status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer); - if(ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n")); - return_VALUE(-ENODEV); - } - - pct = (union acpi_object *) buffer.pointer; - if (!pct || (pct->type != ACPI_TYPE_PACKAGE) - || (pct->package.count != 2)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PCT data\n")); - result = -EFAULT; - goto end; - } - - /* - * control_register - */ - - obj = pct->package.elements[0]; - - if ((obj.type != ACPI_TYPE_BUFFER) - || (obj.buffer.length < sizeof(struct acpi_pct_register)) - || (obj.buffer.pointer == NULL)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid _PCT data (control_register)\n")); - result = -EFAULT; - goto end; - } - - reg = (struct acpi_pct_register *) (obj.buffer.pointer); - - if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unsupported address space [%d] (control_register)\n", - (u32) reg->space_id)); - result = -EFAULT; - goto end; - } - - pr->performance.control_register = (u16) reg->address; - - /* - * status_register - */ - - obj = pct->package.elements[1]; - - if ((obj.type != ACPI_TYPE_BUFFER) - || (obj.buffer.length < sizeof(struct acpi_pct_register)) - || (obj.buffer.pointer == NULL)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Invalid _PCT data (status_register)\n")); - result = -EFAULT; - goto end; - } - - reg = (struct acpi_pct_register *) (obj.buffer.pointer); - - if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unsupported address space [%d] (status_register)\n", - (u32) reg->space_id)); - result = -EFAULT; - goto end; - } - - pr->performance.status_register = (u16) reg->address; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "control_register[0x%04x] status_register[0x%04x]\n", - pr->performance.control_register, - pr->performance.status_register)); - -end: - acpi_os_free(buffer.pointer); - - return_VALUE(result); -} - - -static int -acpi_processor_get_performance_states ( - struct acpi_processor* pr) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - struct acpi_buffer format = {sizeof("NNNNNN"), "NNNNNN"}; - struct acpi_buffer state = {0, NULL}; - union acpi_object *pss = NULL; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states"); - - status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer); - if(ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n")); - return_VALUE(-ENODEV); - } - - pss = (union acpi_object *) buffer.pointer; - if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n")); - result = -EFAULT; - goto end; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n", - pss->package.count)); - - if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) { - pr->performance.state_count = ACPI_PROCESSOR_MAX_PERFORMANCE; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Limiting number of states to max (%d)\n", - ACPI_PROCESSOR_MAX_PERFORMANCE)); - } - else - pr->performance.state_count = pss->package.count; - - if (pr->performance.state_count > 1) - pr->flags.performance = 1; - - for (i = 0; i < pr->performance.state_count; i++) { - - struct acpi_processor_px *px = &(pr->performance.states[i]); - - state.length = sizeof(struct acpi_processor_px); - state.pointer = px; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i)); - - status = acpi_extract_package(&(pss->package.elements[i]), - &format, &state); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSS data\n")); - result = -EFAULT; - goto end; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n", - i, - (u32) px->core_frequency, - (u32) px->power, - (u32) px->transition_latency, - (u32) px->bus_master_latency, - (u32) px->control, - (u32) px->status)); - } - -end: - acpi_os_free(buffer.pointer); - - return_VALUE(result); -} - - -static int -acpi_processor_set_performance ( - struct acpi_processor *pr, - int state) +int +acpi_processor_register_performance ( + struct acpi_processor_performance * performance, + struct acpi_processor ** pr, + unsigned int cpu) { - u16 port = 0; - u8 value = 0; - int i = 0; - struct cpufreq_freqs cpufreq_freqs; - - ACPI_FUNCTION_TRACE("acpi_processor_set_performance"); - - if (!pr) - return_VALUE(-EINVAL); - - if (!pr->flags.performance) - return_VALUE(-ENODEV); - - if (state >= pr->performance.state_count) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Invalid target state (P%d)\n", state)); - return_VALUE(-ENODEV); - } - - if (state < pr->performance.platform_limit) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Platform limit (P%d) overrides target state (P%d)\n", - pr->performance.platform_limit, state)); - return_VALUE(-ENODEV); - } - - if (state == pr->performance.state) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Already at target state (P%d)\n", state)); - return_VALUE(0); - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n", - pr->performance.state, state)); - - /* cpufreq frequency struct */ - cpufreq_freqs.cpu = pr->id; - cpufreq_freqs.old = pr->performance.states[pr->performance.state].core_frequency; - cpufreq_freqs.new = pr->performance.states[state].core_frequency; - - /* notify cpufreq */ - cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); - - /* - * First we write the target state's 'control' value to the - * control_register. - */ + ACPI_FUNCTION_TRACE("acpi_processor_register_performance"); - port = pr->performance.control_register; - value = (u16) pr->performance.states[state].control; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Writing 0x%02x to port 0x%04x\n", value, port)); - - outb(value, port); - - /* - * Then we read the 'status_register' and compare the value with the - * target state's 'status' to make sure the transition was successful. - * Note that we'll poll for up to 1ms (100 cycles of 10us) before - * giving up. - */ - - port = pr->performance.status_register; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Looking for 0x%02x from port 0x%04x\n", - (u8) pr->performance.states[state].status, port)); - - for (i=0; i<100; i++) { - value = inb(port); - if (value == (u8) pr->performance.states[state].status) - break; - udelay(10); - } - - /* notify cpufreq */ - cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); - - if (value != pr->performance.states[state].status) { - unsigned int tmp = cpufreq_freqs.new; - cpufreq_freqs.new = cpufreq_freqs.old; - cpufreq_freqs.old = tmp; - cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); - cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n")); + *pr = processors[cpu]; + if (!*pr) return_VALUE(-ENODEV); - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Transition successful after %d microseconds\n", - i * 10)); - - pr->performance.state = state; - - return_VALUE(0); -} - - -static int -acpi_processor_get_performance_info ( - struct acpi_processor *pr) -{ - int result = 0; - acpi_status status = AE_OK; - acpi_handle handle = NULL; - ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info"); + if ((*pr)->performance) + return_VALUE(-EBUSY); - if (!pr) - return_VALUE(-EINVAL); - - status = acpi_get_handle(pr->handle, "_PCT", &handle); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "ACPI-based processor performance control unavailable\n")); - return_VALUE(0); - } - - result = acpi_processor_get_performance_control(pr); - if (result) - return_VALUE(result); - - result = acpi_processor_get_performance_states(pr); - if (result) - return_VALUE(result); - - result = acpi_processor_get_platform_limit(pr); - if (result) - return_VALUE(result); - - /* - * TBD: Don't trust the latency values we get from BIOS, but rather - * measure the latencies during run-time (e.g. get_latencies). - */ - - return_VALUE(0); -} -#else - - -static int -acpi_processor_get_performance_info ( - struct acpi_processor *pr) -{ - ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info_dummy"); - if (!pr) - return_VALUE(-EINVAL); - pr->flags.performance = 0; - return_VALUE(0); + (*pr)->performance = performance; + return 0; } -#endif - - +EXPORT_SYMBOL(acpi_processor_register_performance); +/* for the rest of it, check cpufreq/acpi.c */ /* -------------------------------------------------------------------------- @@ -1484,9 +1040,9 @@ if (!pr->flags.limit) return_VALUE(-ENODEV); -#ifdef CONFIG_ACPI_PROCESSOR_PERF +#ifdef CONFIG_CPU_FREQ if (pr->flags.performance) { - px = pr->performance.platform_limit; + px = pr->performance_platform_limit; if (pr->limit.user.px > px) px = pr->limit.user.px; if (pr->limit.thermal.px > px) @@ -1495,11 +1051,13 @@ struct cpufreq_policy policy; policy.cpu = pr->id; cpufreq_get_policy(&policy, pr->id); - policy.max = pr->performance.states[px].core_frequency * 1000; + policy.max = pr->performance->states[px].core_frequency * 1000; /* racy */ result = cpufreq_set_policy(&policy); } if (result) goto end; + } else if (pr->performance_platform_limit) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Platform limit event detected. Consider using ACPI P-States CPUfreq driver\n")); } #endif @@ -1560,7 +1118,7 @@ /* Thermal limits are always relative to the current Px/Tx state. */ if (pr->flags.performance) - pr->limit.thermal.px = pr->performance.state; + pr->limit.thermal.px = pr->performance->state; if (pr->flags.throttling) pr->limit.thermal.tx = pr->throttling.state; @@ -1581,7 +1139,7 @@ case ACPI_PROCESSOR_LIMIT_INCREMENT: if (pr->flags.performance) { - if (px == (pr->performance.state_count - 1)) + if (px == (pr->performance->state_count - 1)) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "At maximum performance state\n")); else { @@ -1600,7 +1158,7 @@ case ACPI_PROCESSOR_LIMIT_DECREMENT: if (pr->flags.performance) { - if (px == pr->performance.platform_limit) + if (px == pr->performance_platform_limit) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "At minimum performance state\n")); else { @@ -1650,247 +1208,6 @@ return_VALUE(0); } -/* -------------------------------------------------------------------------- - cpufreq interface - -------------------------------------------------------------------------- */ -#ifdef CONFIG_ACPI_PROCESSOR_PERF -static int -acpi_cpufreq_setpolicy ( - struct cpufreq_policy *policy) -{ - unsigned int i = 0; - struct acpi_processor *pr = NULL; - unsigned int next_state = 0; - unsigned int result = 0; - - ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy"); - - if (!policy) - return_VALUE(-EINVAL); - - pr = processors[policy->cpu]; - if (!pr) - return_VALUE(-EINVAL); - - /* select appropriate P-State */ - if (policy->policy == CPUFREQ_POLICY_POWERSAVE) - { - for (i=(pr->performance.state_count - 1); i>= pr->limit.state.px; i--) - { - unsigned int state_freq = pr->performance.states[i].core_frequency * 1000; - if ((policy->min <= state_freq) && - (policy->max >= state_freq)) - { - next_state = i; - break; - } - } - } else { - for (i=pr->limit.state.px; i < pr->performance.state_count; i++) - { - unsigned int state_freq = pr->performance.states[i].core_frequency * 1000; - if ((policy->min <= state_freq) && - (policy->max >= state_freq)) - { - next_state = i; - break; - } - } - } - - /* set one or all CPUs to the new state */ - result = acpi_processor_set_performance (pr, next_state); - - return_VALUE(result); -} - - -static int -acpi_cpufreq_verify ( - struct cpufreq_policy *policy) -{ - unsigned int i = 0; - struct acpi_processor *pr = NULL; - unsigned int number_states = 0; - unsigned int next_larger_state = 0; - - ACPI_FUNCTION_TRACE("acpi_cpufreq_verify"); - - if (!policy) - return_VALUE(-EINVAL); - - pr = processors[policy->cpu]; - if (!pr) - return_VALUE(-EINVAL); - - /* first check if min and max are within valid limits */ - cpufreq_verify_within_limits( - policy, - pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000, - pr->performance.states[pr->limit.state.px].core_frequency * 1000); - - /* now check if at least one value is within this limit */ - for (i=pr->limit.state.px; i < pr->performance.state_count; i++) - { - unsigned int state_freq = pr->performance.states[i].core_frequency * 1000; - if ((policy->min <= state_freq) && - (policy->max >= state_freq)) - number_states++; - if (state_freq > policy->max) - next_larger_state = i; - } - - if (!number_states) { - /* round up now */ - policy->max = pr->performance.states[next_larger_state].core_frequency * 1000; - } - - cpufreq_verify_within_limits( - policy, - pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000, - pr->performance.states[pr->limit.state.px].core_frequency * 1000); - - return_VALUE(0); -} - -static int -acpi_cpufreq_init ( - struct acpi_processor *pr) -{ - int result = 0; - int i = 0; - int current_state = 0; - struct cpufreq_driver *driver; - - ACPI_FUNCTION_TRACE("acpi_cpufreq_init"); - - if (!pr->flags.performance) - return_VALUE(0); - - if (cpufreq_usage_count) { - if (pr->flags.performance == 1) - cpufreq_usage_count++; - return_VALUE(0); - } - - /* test if it works */ - current_state = pr->performance.state; - - if (current_state == pr->limit.state.px) { - result = acpi_processor_set_performance(pr, (pr->performance.state_count - 1)); - if (result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n")); - pr->flags.performance = 0; - return_VALUE(-ENODEV); - } - } - - result = acpi_processor_set_performance(pr, pr->limit.state.px); - if (result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n")); - pr->flags.performance = 0; - return_VALUE(-ENODEV); - } - - if (current_state != 0) { - result = acpi_processor_set_performance(pr, current_state); - if (result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n")); - pr->flags.performance = 0; - return_VALUE(-ENODEV); - } - } - - /* initialization of main "cpufreq" code*/ - driver = kmalloc(sizeof(struct cpufreq_driver) + - NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL); - if (!driver) - return_VALUE(-ENOMEM); - - driver->policy = (struct cpufreq_policy *) (driver + 1); - -#ifdef CONFIG_CPU_FREQ_24_API - for (i=0;icpu_cur_freq[0] = pr->performance.states[current_state].core_frequency * 1000; - } -#endif - - /* detect highest transition latency */ - for (i=0;iperformance.state_count;i++) { - if (pr->performance.states[i].transition_latency > driver->policy[0].cpuinfo.transition_latency) - driver->policy[0].cpuinfo.transition_latency = pr->performance.states[i].transition_latency; - } - - driver->verify = &acpi_cpufreq_verify; - driver->setpolicy = &acpi_cpufreq_setpolicy; - driver->init = NULL; - driver->exit = NULL; - strncpy(driver->name, "acpi-processor", CPUFREQ_NAME_LEN); - - for (i=0;ipolicy[i].cpu = pr->id; - driver->policy[i].min = pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000; - driver->policy[i].max = pr->performance.states[pr->limit.state.px].core_frequency * 1000; - driver->policy[i].cpuinfo.max_freq = pr->performance.states[0].core_frequency * 1000; - driver->policy[i].cpuinfo.min_freq = pr->performance.states[pr->performance.state_count - 1].core_frequency * 1000; - driver->policy[i].cpuinfo.transition_latency = driver->policy[0].cpuinfo.transition_latency; - driver->policy[i].policy = ( pr->performance.states[current_state].core_frequency * 1000 == driver->policy[i].max) ? - CPUFREQ_POLICY_PERFORMANCE : CPUFREQ_POLICY_POWERSAVE; - } - - acpi_cpufreq_driver = driver; - result = cpufreq_register(driver); - if (result) { - kfree(driver); - acpi_cpufreq_driver = NULL; - return_VALUE(result); - } - - cpufreq_usage_count++; - - return_VALUE(0); -} - -static int -acpi_cpufreq_exit ( - struct acpi_processor *pr) -{ - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_cpufreq_exit"); - - if (!pr) - return_VALUE(-EINVAL); - - if (pr->flags.performance) - cpufreq_usage_count--; - - if (!cpufreq_usage_count) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Removing cpufreq driver\n")); - result = cpufreq_unregister(); - } - - return_VALUE(result); -} -#else -static int -acpi_cpufreq_init ( - struct acpi_processor *pr) -{ - ACPI_FUNCTION_TRACE("acpi_cpufreq_init_dummy"); - return_VALUE(0); -} - - -static int -acpi_cpufreq_exit ( - struct acpi_processor *pr) -{ - ACPI_FUNCTION_TRACE("acpi_cpufreq_exit_dummy"); - return_VALUE(0); -} -#endif /* -------------------------------------------------------------------------- FS Interface (/proc) @@ -1987,82 +1304,6 @@ PDE(inode)->data); } -#ifdef CONFIG_ACPI_PROCESSOR_PERF -static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) -{ - struct acpi_processor *pr = (struct acpi_processor *)seq->private; - int i = 0; - - ACPI_FUNCTION_TRACE("acpi_processor_perf_seq_show"); - - if (!pr) - goto end; - - if (!pr->flags.performance) { - seq_puts(seq, "\n"); - goto end; - } - - seq_printf(seq, "state count: %d\n" - "active state: P%d\n", - pr->performance.state_count, - pr->performance.state); - - seq_puts(seq, "states:\n"); - for (i = 0; i < pr->performance.state_count; i++) - seq_printf(seq, " %cP%d: %d MHz, %d mW, %d uS\n", - (i == pr->performance.state?'*':' '), i, - (u32) pr->performance.states[i].core_frequency, - (u32) pr->performance.states[i].power, - (u32) pr->performance.states[i].transition_latency); - -end: - return 0; -} - -static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_processor_perf_seq_show, - PDE(inode)->data); -} - -static int -acpi_processor_write_performance ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) -{ - int result = 0; - struct acpi_processor *pr = (struct acpi_processor *) data; - char state_string[12] = {'\0'}; - unsigned int new_state = 0; - struct cpufreq_policy policy; - - ACPI_FUNCTION_TRACE("acpi_processor_write_performance"); - - if (!pr || (count > sizeof(state_string) - 1)) - return_VALUE(-EINVAL); - - if (copy_from_user(state_string, buffer, count)) - return_VALUE(-EFAULT); - - state_string[count] = '\0'; - new_state = simple_strtoul(state_string, NULL, 0); - - cpufreq_get_policy(&policy, pr->id); - - policy.cpu = pr->id; - policy.max = pr->performance.states[new_state].core_frequency * 1000; - - result = cpufreq_set_policy(&policy); - if (result) - return_VALUE(result); - - return_VALUE(count); -} -#endif - static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset) { struct acpi_processor *pr = (struct acpi_processor *)seq->private; @@ -2111,8 +1352,8 @@ acpi_processor_write_throttling ( struct file *file, const char *buffer, - unsigned long count, - void *data) + size_t count, + loff_t *data) { int result = 0; struct acpi_processor *pr = (struct acpi_processor *) data; @@ -2155,7 +1396,7 @@ "user limit: P%d:T%d\n" "thermal limit: P%d:T%d\n", pr->limit.state.px, pr->limit.state.tx, - pr->flags.performance?pr->performance.platform_limit:0, + pr->flags.performance?pr->performance_platform_limit:0, pr->limit.user.px, pr->limit.user.tx, pr->limit.thermal.px, pr->limit.thermal.tx); @@ -2171,10 +1412,10 @@ static int acpi_processor_write_limit ( - struct file *file, - const char *buffer, - unsigned long count, - void *data) + struct file *file, + const char *buffer, + size_t count, + loff_t *data) { int result = 0; struct acpi_processor *pr = (struct acpi_processor *) data; @@ -2202,8 +1443,8 @@ } if (pr->flags.performance) { - if ((px < pr->performance.platform_limit) - || (px > (pr->performance.state_count - 1))) { + if ((px < pr->performance_platform_limit) + || (px > (pr->performance->state_count - 1))) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid px\n")); return_VALUE(-EINVAL); } @@ -2263,21 +1504,6 @@ entry->data = acpi_driver_data(device); } -#ifdef CONFIG_ACPI_PROCESSOR_PERF - /* 'performance' [R/W] */ - entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE, - S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); - if (!entry) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Unable to create '%s' fs entry\n", - ACPI_PROCESSOR_FILE_PERFORMANCE)); - else { - entry->proc_fops = &acpi_processor_perf_fops; - entry->write_proc = acpi_processor_write_performance; - entry->data = acpi_driver_data(device); - } -#endif - /* 'throttling' [R/W] */ entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device)); @@ -2287,7 +1513,7 @@ ACPI_PROCESSOR_FILE_THROTTLING)); else { entry->proc_fops = &acpi_processor_throttling_fops; - entry->write_proc = acpi_processor_write_throttling; + entry->proc_fops->write = acpi_processor_write_throttling; entry->data = acpi_driver_data(device); } @@ -2300,7 +1526,7 @@ ACPI_PROCESSOR_FILE_LIMIT)); else { entry->proc_fops = &acpi_processor_limit_fops; - entry->write_proc = acpi_processor_write_limit; + entry->proc_fops->write = acpi_processor_write_limit; entry->data = acpi_driver_data(device); } @@ -2383,22 +1609,27 @@ if (!object.processor.pblk_address) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n")); - else if (object.processor.pblk_length < 6) + else if (object.processor.pblk_length < 4) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid PBLK length [%d]\n", object.processor.pblk_length)); else { pr->throttling.address = object.processor.pblk_address; pr->throttling.duty_offset = acpi_fadt.duty_offset; pr->throttling.duty_width = acpi_fadt.duty_width; - pr->power.states[ACPI_STATE_C2].address = - object.processor.pblk_address + 4; - pr->power.states[ACPI_STATE_C3].address = - object.processor.pblk_address + 5; + + if (object.processor.pblk_length >= 5) + pr->power.states[ACPI_STATE_C2].address = + object.processor.pblk_address + 4; + + if (object.processor.pblk_length >= 6) + pr->power.states[ACPI_STATE_C3].address = + object.processor.pblk_address + 5; } acpi_processor_get_power_info(pr); - acpi_processor_get_performance_info(pr); - acpi_cpufreq_init(pr); + pr->flags.performance = 0; + pr->performance_platform_limit = 0; + acpi_processor_get_platform_limit(pr); acpi_processor_get_throttling_info(pr); acpi_processor_get_limit_info(pr); @@ -2426,18 +1657,11 @@ switch (event) { case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: -#ifdef CONFIG_ACPI_PROCESSOR_PERF result = acpi_processor_get_platform_limit(pr); if (!result) acpi_processor_apply_limit(pr); -#else - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Please use kernel with Processor Performance States support included!\n")); - result = 0; -#endif - acpi_bus_generate_event(device, event, - pr->performance.platform_limit); + pr->performance_platform_limit); break; case ACPI_PROCESSOR_NOTIFY_POWER: /* TBD */ @@ -2511,8 +1735,6 @@ for (i=1; ipower.states[i].valid) printk(" C%d", i); - if (pr->flags.performance) - printk(", %d performance states", pr->performance.state_count); if (pr->flags.throttling) printk(", %d throttling states", pr->throttling.state_count); printk(")\n"); @@ -2554,7 +1776,6 @@ return_VALUE(-ENODEV); } - acpi_cpufreq_exit(pr); acpi_processor_remove_fs(device); processors[pr->id] = NULL; diff -Nru a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c --- a/drivers/acpi/resources/rscalc.c Sun Feb 9 21:13:32 2003 +++ b/drivers/acpi/resources/rscalc.c Sun Feb 9 21:13:32 2003 @@ -793,7 +793,7 @@ * The length String.Length field does not include the * terminating NULL, add 1 */ - temp_size_needed += ((*sub_object_list)->string.length + 1); + temp_size_needed += ((acpi_size) (*sub_object_list)->string.length + 1); } else { temp_size_needed += acpi_ns_get_pathname_length ( diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c --- a/drivers/acpi/scan.c Sun Feb 9 21:13:31 2003 +++ b/drivers/acpi/scan.c Sun Feb 9 21:13:31 2003 @@ -6,7 +6,7 @@ #include #include "acpi_drivers.h" -#include "include/acinterp.h" /* for acpi_ex_eisa_id_to_string() */ +#include /* for acpi_ex_eisa_id_to_string() */ #define _COMPONENT ACPI_BUS_COMPONENT diff -Nru a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c --- a/drivers/acpi/tables/tbinstal.c Sun Feb 9 21:13:29 2003 +++ b/drivers/acpi/tables/tbinstal.c Sun Feb 9 21:13:29 2003 @@ -61,7 +61,7 @@ * Search for a signature match among the known table types */ for (i = 0; i < NUM_ACPI_TABLES; i++) { - if ((acpi_gbl_acpi_table_data[i].flags & ACPI_TABLE_TYPE_MASK) != search_type) { + if (!(acpi_gbl_acpi_table_data[i].flags & search_type)) { continue; } @@ -74,7 +74,7 @@ } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Table [%4.4s] matched and is a required ACPI table\n", + "Table [%4.4s] is an ACPI table consumed by the core subsystem\n", (char *) acpi_gbl_acpi_table_data[i].signature)); return_ACPI_STATUS (AE_OK); @@ -82,7 +82,7 @@ } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, - "Table [%4.4s] is not a required ACPI table - ignored\n", + "Table [%4.4s] is not an ACPI table consumed by the core subsystem - ignored\n", (char *) signature)); return_ACPI_STATUS (AE_TABLE_NOT_SUPPORTED); @@ -125,7 +125,7 @@ status = acpi_tb_init_table_descriptor (table_info->type, table_info); if (ACPI_FAILURE (status)) { - ACPI_REPORT_ERROR (("Could not install ACPI table [%s], %s\n", + ACPI_REPORT_ERROR (("Could not install ACPI table [%4.4s], %s\n", table_info->pointer->signature, acpi_format_exception (status))); } diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c --- a/drivers/acpi/tables.c Sun Feb 9 21:13:31 2003 +++ b/drivers/acpi/tables.c Sun Feb 9 21:13:31 2003 @@ -509,8 +509,7 @@ int __init -acpi_table_init ( - char *cmdline) +acpi_table_init (void) { struct acpi_table_rsdp *rsdp = NULL; unsigned long rsdp_phys = 0; diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c --- a/drivers/acpi/thermal.c Sun Feb 9 21:13:35 2003 +++ b/drivers/acpi/thermal.c Sun Feb 9 21:13:35 2003 @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -878,10 +877,12 @@ acpi_thermal_write_trip_points ( struct file *file, const char *buffer, - unsigned long count, - void *data) + size_t count, + loff_t *ppos) { - struct acpi_thermal *tz = (struct acpi_thermal *) data; + struct seq_file *m = (struct seq_file *)file->private_data; + struct acpi_thermal *tz = (struct acpi_thermal *)m->private; + char limit_string[25] = {'\0'}; int critical, hot, passive, active0, active1; @@ -945,8 +946,8 @@ acpi_thermal_write_cooling_mode ( struct file *file, const char *buffer, - unsigned long count, - void *data) + size_t count, + loff_t *data) { int result = 0; struct acpi_thermal *tz = (struct acpi_thermal *) data; @@ -1005,8 +1006,8 @@ acpi_thermal_write_polling ( struct file *file, const char *buffer, - unsigned long count, - void *data) + size_t count, + loff_t *data) { int result = 0; struct acpi_thermal *tz = (struct acpi_thermal *) data; @@ -1080,10 +1081,10 @@ if (!entry) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to create '%s' fs entry\n", - ACPI_THERMAL_FILE_POLLING_FREQ)); + ACPI_THERMAL_FILE_TRIP_POINTS)); else { entry->proc_fops = &acpi_thermal_trip_fops; - entry->write_proc = acpi_thermal_write_trip_points; + entry->proc_fops->write = acpi_thermal_write_trip_points; entry->data = acpi_driver_data(device); } @@ -1096,7 +1097,7 @@ ACPI_THERMAL_FILE_COOLING_MODE)); else { entry->proc_fops = &acpi_thermal_cooling_fops; - entry->write_proc = acpi_thermal_write_cooling_mode; + entry->proc_fops->write = acpi_thermal_write_cooling_mode; entry->data = acpi_driver_data(device); } @@ -1109,7 +1110,7 @@ ACPI_THERMAL_FILE_POLLING_FREQ)); else { entry->proc_fops = &acpi_thermal_polling_fops; - entry->write_proc = acpi_thermal_write_polling; + 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 Sun Feb 9 21:13:28 2003 +++ b/drivers/acpi/toshiba_acpi.c Sun Feb 9 21:13:28 2003 @@ -309,8 +309,8 @@ } static int -proc_write_lcd(struct file* file, const char* buffer, unsigned long count, - void* data) +proc_write_lcd(struct file* file, const char* buffer, size_t count, + loff_t* data) { int value; /*int byte_count;*/ @@ -358,8 +358,8 @@ } static int -proc_write_video(struct file* file, const char* buffer, unsigned long count, - void* data) +proc_write_video(struct file* file, const char* buffer, size_t count, + loff_t* data) { int value; const char* buffer_end = buffer + count; @@ -423,8 +423,8 @@ } static int -proc_write_fan(struct file* file, const char* buffer, unsigned long count, - void* data) +proc_write_fan(struct file* file, const char* buffer, size_t count, + loff_t* data) { int value; u32 hci_result; @@ -476,8 +476,8 @@ } static int -proc_write_keys(struct file* file, const char* buffer, unsigned long count, - void* data) +proc_write_keys(struct file* file, const char* buffer, size_t count, + loff_t* data) { int value; @@ -518,28 +518,28 @@ toshiba_proc_dir); if (proc) { proc->proc_fops = &toshiba_lcd_fops; - proc->write_proc = proc_write_lcd; + proc->proc_fops->write = proc_write_lcd; } proc = create_proc_entry(PROC_VIDEO, S_IFREG | S_IRUGO | S_IWUSR, toshiba_proc_dir); if (proc) { proc->proc_fops = &toshiba_video_fops; - proc->write_proc = proc_write_video; + proc->proc_fops->write = proc_write_video; } proc = create_proc_entry(PROC_FAN, S_IFREG | S_IRUGO | S_IWUSR, toshiba_proc_dir); if (proc) { proc->proc_fops = &toshiba_fan_fops; - proc->write_proc = proc_write_fan; + proc->proc_fops->write = proc_write_fan; } proc = create_proc_entry(PROC_KEYS, S_IFREG | S_IRUGO | S_IWUSR, toshiba_proc_dir); if (proc) { proc->proc_fops = &toshiba_keys_fops; - proc->write_proc = proc_write_keys; + proc->proc_fops->write = proc_write_keys; } proc = create_proc_entry(PROC_VERSION, S_IFREG | S_IRUGO | S_IWUSR, diff -Nru a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c --- a/drivers/acpi/utilities/utcopy.c Sun Feb 9 21:13:31 2003 +++ b/drivers/acpi/utilities/utcopy.c Sun Feb 9 21:13:31 2003 @@ -652,13 +652,13 @@ */ if ((source_desc->string.length) && (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) { - dest_desc->string.pointer = ACPI_MEM_ALLOCATE (source_desc->string.length + 1); + dest_desc->string.pointer = ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1); if (!dest_desc->string.pointer) { return (AE_NO_MEMORY); } ACPI_MEMCPY (dest_desc->string.pointer, source_desc->string.pointer, - source_desc->string.length + 1); + (acpi_size) source_desc->string.length + 1); } break; diff -Nru a/drivers/atm/Kconfig b/drivers/atm/Kconfig --- a/drivers/atm/Kconfig Sun Feb 9 21:13:31 2003 +++ b/drivers/atm/Kconfig Sun Feb 9 21:13:31 2003 @@ -15,6 +15,11 @@ config ATM_LANAI tristate "Efficient Networks Speedstream 3010" depends on PCI + help + Supports ATM cards based on the Efficient Networks "Lanai" + chipset such as the Speedstream 3010 and the ENI-25p. The + Speedstream 3060 is currently not supported since we don't + have the code to drive the on-board Alcatel DSL chipset (yet). config ATM_ENI tristate "Efficient Networks ENI155P" @@ -29,7 +34,7 @@ This driver is also available as a module. If you want to compile it as a module, say M here and read - . The module will be called eni.o. + . The module will be called eni. config ATM_ENI_DEBUG bool "Enable extended debugging" @@ -136,7 +141,7 @@ This driver is also available as a module. If you want to compile it as a module, say M here and read . The module will be called - firestream.o. + firestream. config ATM_ZATM tristate "ZeitNet ZN1221/ZN1225" @@ -147,7 +152,7 @@ This driver is also available as a module. If you want to compile it as a module, say M here and read - . The module will be called zatm.o. + . The module will be called zatm. config ATM_ZATM_DEBUG bool "Enable extended debugging" @@ -186,7 +191,7 @@ This driver is also available as a module. If you want to compile it as a module, say M here and read . The module will be called - nicstar.o. + nicstar. config ATM_NICSTAR_USE_SUNI bool "Use suni PHY driver (155Mbps)" @@ -218,7 +223,7 @@ This driver is also available as a module. If you want to compile it as a module, say M here and read - . The module will be called idt77252.o + . The module will be called idt77252 config ATM_IDT77252_DEBUG bool "Enable debugging messages" @@ -251,7 +256,7 @@ depends on PCI help This is a driver for ATMizer based ATM card produced by Madge - Networks Ltd. Say Y (or M to compile as a module named ambassador.o) + Networks Ltd. Say Y (or M to compile as a module named ambassador) here if you have one of these cards. config ATM_AMBASSADOR_DEBUG @@ -276,7 +281,7 @@ help This is a driver for the Horizon chipset ATM adapter cards once produced by Madge Networks Ltd. Say Y (or M to compile as a module - named horizon.o) here if you have one of these cards. + named horizon) here if you have one of these cards. config ATM_HORIZON_DEBUG bool "Enable debugging messages" @@ -305,7 +310,7 @@ UTP155, UTP25, DS3 and E3). Go to: for more info about the cards. Say Y (or M to compile as a module - named iphase.o) here if you have one of these cards. + named iphase) here if you have one of these cards. See the file for further details. @@ -334,7 +339,7 @@ This is a driver for the FORE Systems 200E-series ATM adapter cards. It simultaneously supports PCA-200E and SBA-200E models on PCI and SBUS hosts. Say Y (or M to compile as a module - named fore_200e.o) here if you have one of these ATM adapters. + named fore_200e) here if you have one of these ATM adapters. Note that the driver will actually be compiled only if you additionally enable the support for PCA-200E and/or SBA-200E diff -Nru a/drivers/atm/Makefile b/drivers/atm/Makefile --- a/drivers/atm/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/atm/Makefile Sun Feb 9 21:13:28 2003 @@ -4,7 +4,6 @@ EXTRA_CFLAGS := -g -export-objs := uPD98402.o suni.o idt77105.o fore_200e-objs := fore200e.o host-progs := fore200e_mkfirm diff -Nru a/drivers/atm/lanai.c b/drivers/atm/lanai.c --- a/drivers/atm/lanai.c Sun Feb 9 21:13:30 2003 +++ b/drivers/atm/lanai.c Sun Feb 9 21:13:30 2003 @@ -632,7 +632,7 @@ * anytime it wants to consult its table of vccs - for instance * when handling an incoming PDU. This also explains why we would * probably want the write_lock while in _change_qos - to prevent - * handling of PDUs while possibly in an inconsistant state. + * handling of PDUs while possibly in an inconsistent state. * Also, _send would grab the lock for reading. * * One problem with this is that _open and _close could no longer diff -Nru a/drivers/base/Makefile b/drivers/base/Makefile --- a/drivers/base/Makefile Sun Feb 9 21:13:35 2003 +++ b/drivers/base/Makefile Sun Feb 9 21:13:35 2003 @@ -1,14 +1,8 @@ # Makefile for the Linux device tree -obj-y := core.o sys.o interface.o power.o bus.o \ - driver.o class.o intf.o platform.o \ - cpu.o firmware.o - +obj-y := core.o sys.o interface.o power.o bus.o \ + driver.o class.o intf.o platform.o \ + cpu.o firmware.o obj-$(CONFIG_NUMA) += node.o memblk.o - -obj-y += fs/ - +obj-y += fs/ obj-$(CONFIG_HOTPLUG) += hotplug.o - -export-objs := core.o power.o sys.o bus.o driver.o \ - class.o intf.o platform.o firmware.o diff -Nru a/drivers/base/cpu.c b/drivers/base/cpu.c --- a/drivers/base/cpu.c Sun Feb 9 21:13:30 2003 +++ b/drivers/base/cpu.c Sun Feb 9 21:13:30 2003 @@ -35,7 +35,7 @@ */ int __init register_cpu(struct cpu *cpu, int num, struct node *root) { - cpu->node_id = __cpu_to_node(num); + cpu->node_id = cpu_to_node(num); cpu->sysdev.name = "cpu"; cpu->sysdev.id = num; if (root) diff -Nru a/drivers/base/fs/Makefile b/drivers/base/fs/Makefile --- a/drivers/base/fs/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/base/fs/Makefile Sun Feb 9 21:13:32 2003 @@ -1,3 +1,2 @@ obj-y := device.o -export-objs := device.o diff -Nru a/drivers/base/memblk.c b/drivers/base/memblk.c --- a/drivers/base/memblk.c Sun Feb 9 21:13:37 2003 +++ b/drivers/base/memblk.c Sun Feb 9 21:13:37 2003 @@ -36,7 +36,7 @@ */ int __init register_memblk(struct memblk *memblk, int num, struct node *root) { - memblk->node_id = __memblk_to_node(num); + memblk->node_id = memblk_to_node(num); memblk->sysdev.name = "memblk"; memblk->sysdev.id = num; if (root) diff -Nru a/drivers/base/node.c b/drivers/base/node.c --- a/drivers/base/node.c Sun Feb 9 21:13:29 2003 +++ b/drivers/base/node.c Sun Feb 9 21:13:29 2003 @@ -72,7 +72,7 @@ { int error; - node->cpumap = __node_to_cpu_mask(num); + node->cpumap = node_to_cpumask(num); node->sysroot.id = num; if (parent) node->sysroot.dev.parent = &parent->sysroot.sysdev; diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c --- a/drivers/block/DAC960.c Sun Feb 9 21:13:34 2003 +++ b/drivers/block/DAC960.c Sun Feb 9 21:13:34 2003 @@ -267,10 +267,12 @@ } } if (Controller->FirmwareType == DAC960_V1_Controller) { + Command->cmd_sglist = Command->V1.ScatterList; Command->V1.ScatterGatherList = (DAC960_V1_ScatterGatherSegment_T *)ScatterGatherCPU; Command->V1.ScatterGatherListDMA = ScatterGatherDMA; } else { + Command->cmd_sglist = Command->V2.ScatterList; Command->V2.ScatterGatherList = (DAC960_V2_ScatterGatherSegment_T *)ScatterGatherCPU; Command->V2.ScatterGatherListDMA = ScatterGatherDMA; @@ -3046,25 +3048,12 @@ DAC960_V1_ScatterGatherSegment_T *ScatterGatherList = Command->V1.ScatterGatherList; struct scatterlist *ScatterList = Command->V1.ScatterList; - int DmaDirection, SegCount; DAC960_V1_ClearCommand(Command); - if (Command->CommandType == DAC960_ReadCommand) - DmaDirection = PCI_DMA_FROMDEVICE; - else - DmaDirection = PCI_DMA_TODEVICE; - - SegCount = blk_rq_map_sg(&Controller->RequestQueue, Command->Request, - ScatterList); - /* pci_map_sg MAY change the value of SegCount */ - SegCount = pci_map_sg(Command->PciDevice, ScatterList, SegCount, - DmaDirection); - Command->SegmentCount = SegCount; - - if (SegCount == 1) + if (Command->SegmentCount == 1) { - if (Command->CommandType == DAC960_ReadCommand) + if (Command->DmaDirection == PCI_DMA_FROMDEVICE) CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read; else CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write; @@ -3079,7 +3068,7 @@ { int i; - if (Command->CommandType == DAC960_ReadCommand) + if (Command->DmaDirection == PCI_DMA_FROMDEVICE) CommandMailbox->Type5.CommandOpcode = DAC960_V1_ReadWithScatterGather; else CommandMailbox->Type5.CommandOpcode = DAC960_V1_WriteWithScatterGather; @@ -3089,9 +3078,9 @@ CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber; CommandMailbox->Type5.BusAddress = Command->V1.ScatterGatherListDMA; - CommandMailbox->Type5.ScatterGatherCount = SegCount; + CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount; - for (i = 0; i < SegCount; i++, ScatterList++, ScatterGatherList++) { + for (i = 0; i < Command->SegmentCount; i++, ScatterList++, ScatterGatherList++) { ScatterGatherList->SegmentDataPointer = (DAC960_BusAddress32_T)sg_dma_address(ScatterList); ScatterGatherList->SegmentByteCount = @@ -3112,25 +3101,12 @@ DAC960_Controller_T *Controller = Command->Controller; DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; struct scatterlist *ScatterList = Command->V2.ScatterList; - int DmaDirection, SegCount; DAC960_V2_ClearCommand(Command); - if (Command->CommandType == DAC960_ReadCommand) - DmaDirection = PCI_DMA_FROMDEVICE; - else - DmaDirection = PCI_DMA_TODEVICE; - - SegCount = blk_rq_map_sg(&Controller->RequestQueue, Command->Request, - ScatterList); - /* pci_map_sg MAY change the value of SegCount */ - SegCount = pci_map_sg(Command->PciDevice, ScatterList, SegCount, - DmaDirection); - Command->SegmentCount = SegCount; - CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10; CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost = - (Command->CommandType == DAC960_ReadCommand); + (Command->DmaDirection == PCI_DMA_FROMDEVICE); CommandMailbox->SCSI_10.DataTransferSize = Command->BlockCount << DAC960_BlockSizeBits; CommandMailbox->SCSI_10.RequestSenseBusAddress = Command->V2.RequestSenseDMA; @@ -3139,7 +3115,7 @@ CommandMailbox->SCSI_10.RequestSenseSize = sizeof(DAC960_SCSI_RequestSense_T); CommandMailbox->SCSI_10.CDBLength = 10; CommandMailbox->SCSI_10.SCSI_CDB[0] = - (Command->CommandType == DAC960_ReadCommand ? 0x28 : 0x2A); + (Command->DmaDirection == PCI_DMA_FROMDEVICE ? 0x28 : 0x2A); CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24; CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16; CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8; @@ -3147,7 +3123,7 @@ CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8; CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount; - if (SegCount == 1) + if (Command->SegmentCount == 1) { CommandMailbox->SCSI_10.DataTransferMemoryAddress .ScatterGatherSegments[0] @@ -3163,13 +3139,13 @@ DAC960_V2_ScatterGatherSegment_T *ScatterGatherList; int i; - if (SegCount > 2) + if (Command->SegmentCount > 2) { ScatterGatherList = Command->V2.ScatterGatherList; CommandMailbox->SCSI_10.CommandControlBits .AdditionalScatterGatherListMemory = true; CommandMailbox->SCSI_10.DataTransferMemoryAddress - .ExtendedScatterGather.ScatterGatherList0Length = SegCount; + .ExtendedScatterGather.ScatterGatherList0Length = Command->SegmentCount; CommandMailbox->SCSI_10.DataTransferMemoryAddress .ExtendedScatterGather.ScatterGatherList0Address = Command->V2.ScatterGatherListDMA; @@ -3178,7 +3154,7 @@ ScatterGatherList = CommandMailbox->SCSI_10.DataTransferMemoryAddress .ScatterGatherSegments; - for (i = 0; i < SegCount; i++, ScatterList++, ScatterGatherList++) { + for (i = 0; i < Command->SegmentCount; i++, ScatterList++, ScatterGatherList++) { ScatterGatherList->SegmentDataPointer = (DAC960_BusAddress64_T)sg_dma_address(ScatterList); ScatterGatherList->SegmentByteCount = @@ -3220,22 +3196,75 @@ DAC960_WaitForCommand(Controller); } - if (rq_data_dir(Request) == READ) + if (rq_data_dir(Request) == READ) { + Command->DmaDirection = PCI_DMA_FROMDEVICE; Command->CommandType = DAC960_ReadCommand; - else + } else { + Command->DmaDirection = PCI_DMA_TODEVICE; Command->CommandType = DAC960_WriteCommand; + } Command->Completion = Request->waiting; Command->LogicalDriveNumber = (int)Request->rq_disk->private_data; Command->BlockNumber = Request->sector; Command->BlockCount = Request->nr_sectors; Command->Request = Request; blkdev_dequeue_request(Request); + Command->SegmentCount = blk_rq_map_sg(&Controller->RequestQueue, + Command->Request, Command->cmd_sglist); + /* pci_map_sg MAY change the value of SegCount */ + Command->SegmentCount = pci_map_sg(Command->PciDevice, Command->cmd_sglist, + Command->SegmentCount, Command->DmaDirection); + DAC960_QueueReadWriteCommand(Command); return true; } /* + DAC960_queue_partial_rw extracts one bio from the request already + associated with argument command, and construct a new command block to retry I/O + only on that bio. Queue that command to the controller. + + This function re-uses a previously-allocated Command, + there is no failure mode from trying to allocate a command. +*/ + +static void DAC960_queue_partial_rw(DAC960_Command_T *Command) +{ + DAC960_Controller_T *Controller = Command->Controller; + IO_Request_T *Request = Command->Request; + + if (Command->DmaDirection == PCI_DMA_FROMDEVICE) + Command->CommandType = DAC960_ReadRetryCommand; + else + Command->CommandType = DAC960_WriteRetryCommand; + + /* + * We could be more efficient with these mapping requests + * and map only the portions that we need. But since this + * code should almost never be called, just go with a + * simple coding. + */ + (void)blk_rq_map_sg(&Controller->RequestQueue, Command->Request, + Command->cmd_sglist); + + (void)pci_map_sg(Command->PciDevice, Command->cmd_sglist, 1, + Command->DmaDirection); + /* + * Resubmitting the request sector at a time is really tedious. + * But, this should almost never happen. So, we're willing to pay + * this price so that in the end, as much of the transfer is completed + * successfully as possible. + */ + Command->SegmentCount = 1; + Command->BlockNumber = Request->sector; + Command->BlockCount = 1; + DAC960_QueueReadWriteCommand(Command); + return; +} + + +/* DAC960_ProcessRequests attempts to remove as many I/O Requests as possible from Controller's I/O Request Queue and queue them to the Controller. */ @@ -3276,43 +3305,30 @@ individual Buffer. */ -static inline void DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, +static inline boolean DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, boolean SuccessfulIO) { - DAC960_CommandType_T CommandType = Command->CommandType; IO_Request_T *Request = Command->Request; - int DmaDirection, UpToDate; + int UpToDate; UpToDate = 0; if (SuccessfulIO) UpToDate = 1; - /* - * We could save DmaDirection in the command structure - * and just reuse that information here. - */ - if (CommandType == DAC960_ReadCommand || - CommandType == DAC960_ReadRetryCommand) - DmaDirection = PCI_DMA_FROMDEVICE; - else - DmaDirection = PCI_DMA_TODEVICE; - - pci_unmap_sg(Command->PciDevice, Command->V1.ScatterList, - Command->SegmentCount, DmaDirection); - /* - * BlockCount is redundant with nr_sectors in the request - * structure. Consider eliminating BlockCount from the - * command structure now that Command includes a pointer to - * the request. - */ - while (end_that_request_first(Request, UpToDate, Command->BlockCount)) - ; - end_that_request_last(Request); - - if (Command->Completion) { - complete(Command->Completion); - Command->Completion = NULL; + pci_unmap_sg(Command->PciDevice, Command->cmd_sglist, + Command->SegmentCount, Command->DmaDirection); + + if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) { + + end_that_request_last(Request); + + if (Command->Completion) { + complete(Command->Completion); + Command->Completion = NULL; + } + return true; } + return false; } /* @@ -3384,46 +3400,65 @@ if (CommandType == DAC960_ReadCommand || CommandType == DAC960_WriteCommand) { - if (CommandStatus == DAC960_V1_NormalCompletion) - DAC960_ProcessCompletedRequest(Command, true); +#ifdef FORCE_RETRY_DEBUG + CommandStatus = DAC960_V1_IrrecoverableDataError; +#endif + + if (CommandStatus == DAC960_V1_NormalCompletion) { - else if (CommandStatus == DAC960_V1_IrrecoverableDataError || + if (!DAC960_ProcessCompletedRequest(Command, true)) + BUG(); + + } else if (CommandStatus == DAC960_V1_IrrecoverableDataError || CommandStatus == DAC960_V1_BadDataEncountered) { - /* - * Finish this later. - * - * We should call "complete_that_request_first()" - * to remove the first part of the request. Then, if there - * is still more I/O to be done, resubmit the request. - * - * We want to recalculate scatter/gather list, - * and requeue the command. - * - * For now, print a message on the console, and clone - * the code for "normal" completion. + * break the command down into pieces and resubmit each + * piece, hoping that some of them will succeed. */ - printk("V1_ProcessCompletedCommand: I/O error on read/write\n"); - - DAC960_ProcessCompletedRequest(Command, false); + DAC960_queue_partial_rw(Command); + return; } else { if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline) DAC960_V1_ReadWriteError(Command); - DAC960_ProcessCompletedRequest(Command, false); + if (!DAC960_ProcessCompletedRequest(Command, false)) + BUG(); } } else if (CommandType == DAC960_ReadRetryCommand || CommandType == DAC960_WriteRetryCommand) { - /* - * We're not doing retry commands yet. - */ - printk("DAC960_ProcessCompletedCommand: RetryCommand not done yet\n"); + boolean normal_completion; +#ifdef FORCE_RETRY_FAILURE_DEBUG + static int retry_count = 1; +#endif + /* + Perform completion processing for the portion that was + retried, and submit the next portion, if any. + */ + normal_completion = true; + if (CommandStatus != DAC960_V1_NormalCompletion) { + normal_completion = false; + if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline) + DAC960_V1_ReadWriteError(Command); + } + +#ifdef FORCE_RETRY_FAILURE_DEBUG + if (!(++retry_count % 10000)) { + printk("V1 error retry failure test\n"); + normal_completion = false; + DAC960_V1_ReadWriteError(Command); + } +#endif + + if (!DAC960_ProcessCompletedRequest(Command, normal_completion)) { + DAC960_queue_partial_rw(Command); + return; + } } else if (CommandType == DAC960_MonitoringCommand) @@ -4451,23 +4486,25 @@ if (CommandType == DAC960_ReadCommand || CommandType == DAC960_WriteCommand) { - if (CommandStatus == DAC960_V2_NormalCompletion) - DAC960_ProcessCompletedRequest(Command, true); +#ifdef FORCE_RETRY_DEBUG + CommandStatus = DAC960_V2_AbormalCompletion; +#endif + Command->V2.RequestSense->SenseKey = DAC960_SenseKey_MediumError; + + if (CommandStatus == DAC960_V2_NormalCompletion) { + + if (!DAC960_ProcessCompletedRequest(Command, true)) + BUG(); - else if (Command->V2.RequestSense->SenseKey == DAC960_SenseKey_MediumError) + } else if (Command->V2.RequestSense->SenseKey == DAC960_SenseKey_MediumError) { - /* - * Don't know yet how to handle this case. - * See comments in DAC960_V1_ProcessCompletedCommand() - * - * For now, print a message on the console, and clone - * the code for "normal" completion. + * break the command down into pieces and resubmit each + * piece, hoping that some of them will succeed. */ - printk("V1_ProcessCompletedCommand: I/O error on read/write\n"); - - DAC960_ProcessCompletedRequest(Command, false); + DAC960_queue_partial_rw(Command); + return; } else { @@ -4476,13 +4513,40 @@ /* Perform completion processing for all buffers in this I/O Request. */ - DAC960_ProcessCompletedRequest(Command, false); + (void)DAC960_ProcessCompletedRequest(Command, false); } } else if (CommandType == DAC960_ReadRetryCommand || CommandType == DAC960_WriteRetryCommand) { - printk("DAC960_V2_ProcessCompletedCommand: retries not coded yet\n"); + boolean normal_completion; + +#ifdef FORCE_RETRY_FAILURE_DEBUG + static int retry_count = 1; +#endif + /* + Perform completion processing for the portion that was + retried, and submit the next portion, if any. + */ + normal_completion = true; + if (CommandStatus != DAC960_V2_NormalCompletion) { + normal_completion = false; + if (Command->V2.RequestSense->SenseKey != DAC960_SenseKey_NotReady) + DAC960_V2_ReadWriteError(Command); + } + +#ifdef FORCE_RETRY_FAILURE_DEBUG + if (!(++retry_count % 10000)) { + printk("V2 error retry failure test\n"); + normal_completion = false; + DAC960_V2_ReadWriteError(Command); + } +#endif + + if (!DAC960_ProcessCompletedRequest(Command, normal_completion)) { + DAC960_queue_partial_rw(Command); + return; + } } else if (CommandType == DAC960_MonitoringCommand) { diff -Nru a/drivers/block/DAC960.h b/drivers/block/DAC960.h --- a/drivers/block/DAC960.h Sun Feb 9 21:13:34 2003 +++ b/drivers/block/DAC960.h Sun Feb 9 21:13:35 2003 @@ -2305,6 +2305,8 @@ unsigned int BlockNumber; unsigned int BlockCount; unsigned int SegmentCount; + int DmaDirection; + struct scatterlist *cmd_sglist; IO_Request_T *Request; struct pci_dev *PciDevice; union { diff -Nru a/drivers/block/Kconfig b/drivers/block/Kconfig --- a/drivers/block/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/block/Kconfig Sun Feb 9 21:13:29 2003 @@ -16,7 +16,7 @@ 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 will be called floppy.o. If you want to compile it as a + The module will be called floppy. If you want to compile it as a module, say M here and read . config AMIGA_FLOPPY @@ -44,7 +44,7 @@ If you want to compile the driver 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 ps2esdi.o. + will be called ps2esdi. config AMIGA_Z2RAM tristate "Amiga Zorro II ramdisk support" @@ -54,7 +54,7 @@ ramdisk or as a swap partition. Say Y if you want to include this driver in the kernel. 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 z2ram.o. If you want + kernel whenever you want). The module is called z2ram. If you want to compile it as a module, say M here and read . @@ -74,7 +74,7 @@ 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 will be called acsi.o. + The module will be called acsi. comment "Some devices (e.g. CD jukebox) support multiple LUNs" depends on ATARI && ATARI_ACSI @@ -98,7 +98,7 @@ it in the kernel. Otherwise, say N. 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 will be called - acsi_slm.o. Be warned: the driver needs much ST-RAM and can cause + acsi_slm. Be warned: the driver needs much ST-RAM and can cause problems due to that fact! config BLK_DEV_XD @@ -111,7 +111,7 @@ If you want to compile the driver 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 xd.o. + will be called xd. It's pretty unlikely that you have one of these: say N. @@ -133,7 +133,7 @@ PARIDE as a module. If you built PARIDE support into your kernel, you may still build the individual protocol modules and high-level drivers as loadable modules. If you build this support as a module, - it will be called paride.o. + it will be called paride. To use the PARIDE support, you must say Y or M here and also to at least one high-level driver (e.g. "Parallel port IDE disks", @@ -190,7 +190,7 @@ If you want to compile the driver 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 DAC960.o. + will be called DAC960. config BLK_DEV_UMEM tristate "Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)" @@ -206,7 +206,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read Documentation/modules.txt. The module will be - called umem.o. + called umem. The umem driver has not yet been allocated a MAJOR number, so one is chosen dynamically. Use "devfs" or look in /proc/devices @@ -259,7 +259,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called loop.o. + will be called loop. Most users will answer N here. @@ -288,7 +288,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called nbd.o. + will be called nbd. If unsure, say N. @@ -308,7 +308,7 @@ 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 and read . The module will be - called rd.o. + called rd. Most normal users won't need the RAM disk functionality, and can thus say N here. diff -Nru a/drivers/block/Makefile b/drivers/block/Makefile --- a/drivers/block/Makefile Sun Feb 9 21:13:35 2003 +++ b/drivers/block/Makefile Sun Feb 9 21:13:35 2003 @@ -8,9 +8,6 @@ # In the future, some of these should be built conditionally. # -export-objs := elevator.o ll_rw_blk.o loop.o genhd.o acsi.o \ - scsi_ioctl.o deadline-iosched.o - obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o deadline-iosched.o obj-$(CONFIG_MAC_FLOPPY) += swim3.o diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c --- a/drivers/block/cpqarray.c Sun Feb 9 21:13:29 2003 +++ b/drivers/block/cpqarray.c Sun Feb 9 21:13:29 2003 @@ -607,7 +607,7 @@ #ifndef MODULE #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13) /* - * Config string is a comma seperated set of i/o addresses of EISA cards. + * Config string is a comma separated set of i/o addresses of EISA cards. */ static int cpqarray_setup(char *str) { diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c --- a/drivers/block/floppy.c Sun Feb 9 21:13:29 2003 +++ b/drivers/block/floppy.c Sun Feb 9 21:13:29 2003 @@ -2298,7 +2298,7 @@ if (end_that_request_first(req, uptodate, current_count_sectors)) return; add_disk_randomness(req->rq_disk); - floppy_off((int)req->rq_disk->private_data); + floppy_off((long)req->rq_disk->private_data); blkdev_dequeue_request(req); end_that_request_last(req); @@ -2631,7 +2631,7 @@ return 0; } - set_fdc((int)current_req->rq_disk->private_data); + set_fdc((long)current_req->rq_disk->private_data); raw_cmd = &default_raw_cmd; raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK | @@ -2911,7 +2911,11 @@ for (;;) { if (!current_req) { - struct request *req = elv_next_request(&floppy_queue); + struct request *req; + + spin_lock_irq(floppy_queue.queue_lock); + req = elv_next_request(&floppy_queue); + spin_unlock_irq(floppy_queue.queue_lock); if (!req) { do_floppy = NULL; unlock_fdc(); @@ -2919,7 +2923,7 @@ } current_req = req; } - drive = (int)current_req->rq_disk->private_data; + drive = (long)current_req->rq_disk->private_data; set_fdc(drive); reschedule_timeout(current_reqD, "redo fd request", 0); @@ -3298,7 +3302,7 @@ static int invalidate_drive(struct block_device *bdev) { /* invalidate the buffer track to force a reread */ - set_bit((int)bdev->bd_disk->private_data, &fake_change); + set_bit((long)bdev->bd_disk->private_data, &fake_change); process_fd_request(); check_disk_change(bdev); return 0; @@ -3793,7 +3797,7 @@ */ static int check_floppy_change(struct gendisk *disk) { - int drive = (int)disk->private_data; + int drive = (long)disk->private_data; if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY)) return 1; @@ -3896,7 +3900,7 @@ * geometry formats */ static int floppy_revalidate(struct gendisk *disk) { - int drive=(int)disk->private_data; + int drive=(long)disk->private_data; #define NO_GEOM (!current_type[drive] && !ITYPE(UDRS->fd_device)) int cf; int res = 0; @@ -4354,7 +4358,7 @@ if (fdc_state[FDC(drive)].version == FDC_NONE) continue; /* to be cleaned up... */ - disks[drive]->private_data = (void*)drive; + disks[drive]->private_data = (void*)(long)drive; disks[drive]->queue = &floppy_queue; add_disk(disks[drive]); } diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c --- a/drivers/block/ll_rw_blk.c Sun Feb 9 21:13:29 2003 +++ b/drivers/block/ll_rw_blk.c Sun Feb 9 21:13:29 2003 @@ -27,6 +27,8 @@ #include #include +static void blk_unplug_work(void *data); + /* * For the allocated request tables */ @@ -237,6 +239,14 @@ blk_queue_hardsect_size(q, 512); blk_queue_dma_alignment(q, 511); + q->unplug_thresh = 4; /* hmm */ + q->unplug_delay = (3 * HZ) / 1000; /* 3 milliseconds */ + if (q->unplug_delay == 0) + q->unplug_delay = 1; + + init_timer(&q->unplug_timer); + INIT_WORK(&q->unplug_work, blk_unplug_work, q); + /* * by default assume old behaviour and bounce for any highmem page */ @@ -274,7 +284,7 @@ init_emergency_isa_pool(); q->bounce_gfp = GFP_NOIO | GFP_DMA; } else - q->bounce_gfp = GFP_NOHIGHIO; + q->bounce_gfp = GFP_NOIO; /* * keep this for debugging for now... @@ -960,6 +970,7 @@ if (!blk_queue_plugged(q)) { spin_lock(&blk_plug_lock); list_add_tail(&q->plug_list, &blk_plug_list); + mod_timer(&q->unplug_timer, jiffies + q->unplug_delay); spin_unlock(&blk_plug_lock); } } @@ -974,6 +985,7 @@ if (blk_queue_plugged(q)) { spin_lock(&blk_plug_lock); list_del_init(&q->plug_list); + del_timer(&q->unplug_timer); spin_unlock(&blk_plug_lock); return 1; } @@ -992,6 +1004,8 @@ if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)) return; + del_timer(&q->unplug_timer); + /* * was plugged, fire request_fn if queue has stuff to do */ @@ -1020,6 +1034,18 @@ spin_unlock_irq(q->queue_lock); } +static void blk_unplug_work(void *data) +{ + generic_unplug_device(data); +} + +static void blk_unplug_timeout(unsigned long data) +{ + request_queue_t *q = (request_queue_t *)data; + + schedule_work(&q->unplug_work); +} + /** * blk_start_queue - restart a previously stopped queue * @q: The &request_queue_t in question @@ -1164,6 +1190,9 @@ count -= __blk_cleanup_queue(&q->rq[READ]); count -= __blk_cleanup_queue(&q->rq[WRITE]); + del_timer_sync(&q->unplug_timer); + flush_scheduled_work(); + if (count) printk("blk_cleanup_queue: leaked requests (%d)\n", count); @@ -1269,6 +1298,9 @@ 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); @@ -1811,7 +1843,15 @@ out: if (freereq) __blk_put_request(q, freereq); + + if (blk_queue_plugged(q)) { + int nr_queued = (queue_nr_requests - q->rq[0].count) + + (queue_nr_requests - q->rq[1].count); + if (nr_queued == q->unplug_thresh) + __generic_unplug_device(q); + } spin_unlock_irq(q->queue_lock); + return 0; end_io: diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c --- a/drivers/block/loop.c Sun Feb 9 21:13:32 2003 +++ b/drivers/block/loop.c Sun Feb 9 21:13:32 2003 @@ -350,15 +350,10 @@ int ret; pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; - - do { - if (bio_rw(bio) == WRITE) - ret = lo_send(lo, bio, lo->lo_blocksize, pos); - else - ret = lo_receive(lo, bio, lo->lo_blocksize, pos); - - } while (++bio->bi_idx < bio->bi_vcnt); - + if (bio_rw(bio) == WRITE) + ret = lo_send(lo, bio, lo->lo_blocksize, pos); + else + ret = lo_receive(lo, bio, lo->lo_blocksize, pos); return ret; } @@ -589,10 +584,10 @@ hence, it mustn't be stopped at all because it could be indirectly used during suspension */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigfillset(¤t->blocked); flush_signals(current); - spin_unlock_irq(¤t->sig->siglock); + 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 Sun Feb 9 21:13:29 2003 +++ b/drivers/block/nbd.c Sun Feb 9 21:13:29 2003 @@ -24,7 +24,7 @@ * 01-3-11 Make nbd work with new Linux block layer code. It now supports * plugging like all the other block devices. Also added in MSG_MORE to * reduce number of partial TCP segments sent. - * 01-12-6 Fix deadlock condition by making queue locks independant of + * 01-12-6 Fix deadlock condition by making queue locks independent of * the transmit lock. * 02-10-11 Allow hung xmit to be aborted via SIGKILL & various fixes. * @@ -118,12 +118,12 @@ set_fs(get_ds()); /* Allow interception of SIGKILL only * Don't allow other signals to interrupt the transmission */ - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); oldset = current->blocked; sigfillset(¤t->blocked); sigdelsetmask(¤t->blocked, sigmask(SIGKILL)); recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); do { @@ -146,11 +146,11 @@ if (signal_pending(current)) { siginfo_t info; - spin_lock_irqsave(¤t->sig->siglock, flags); + 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)); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); result = -EINTR; break; } @@ -166,10 +166,10 @@ buf += result; } while (size > 0); - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); current->blocked = oldset; recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); set_fs(oldfs); return result; diff -Nru a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig --- a/drivers/block/paride/Kconfig Sun Feb 9 21:13:28 2003 +++ b/drivers/block/paride/Kconfig Sun Feb 9 21:13:28 2003 @@ -21,7 +21,7 @@ connected through a parallel port. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the parallel port IDE driver, otherwise you should answer M to build - it as a loadable module. The module will be called pd.o. You + it as a loadable module. The module will be called pd. You must also have at least one parallel port protocol driver in your system. Among the devices supported by this driver are the SyQuest EZ-135, EZ-230 and SparQ drives, the Avatar Shark and the backpack @@ -35,7 +35,7 @@ connected through a parallel port. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the parallel port ATAPI CD-ROM driver, otherwise you should answer M to - build it as a loadable module. The module will be called pcd.o. You + build it as a loadable module. The module will be called pcd. You must also have at least one parallel port protocol driver in your system. Among the devices supported by this driver are the MicroSolutions backpack CD-ROM drives and the Freecom Power CD. If @@ -51,7 +51,7 @@ connected through a parallel port. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the parallel port ATAPI disk driver, otherwise you should answer M - to build it as a loadable module. The module will be called pf.o. + to build it as a loadable module. The module will be called pf. You must also have at least one parallel port protocol driver in your system. Among the devices supported by this driver are the MicroSolutions backpack PD/CD drive and the Imation Superdisk @@ -65,7 +65,7 @@ connected through a parallel port. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the parallel port ATAPI disk driver, otherwise you should answer M - to build it as a loadable module. The module will be called pt.o. + to build it as a loadable module. The module will be called pt. You must also have at least one parallel port protocol driver in your system. Among the devices supported by this driver is the parallel port version of the HP 5GB drive. @@ -82,7 +82,7 @@ If you chose to build PARIDE support into your kernel, you may answer Y here to build in the parallel port generic ATAPI driver, otherwise you should answer M to build it as a loadable module. The - module will be called pg.o. + module will be called pg. You must also have at least one parallel port protocol driver in your system. @@ -106,7 +106,7 @@ parallel port kits made in Hong Kong. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a - loadable module. The module will be called aten.o. You must also + loadable module. The module will be called aten. You must also have a high-level driver for the type of device that you want to support. @@ -125,7 +125,7 @@ If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a loadable module. The module will be - called bpck.o. You must also have a high-level driver for the type + called bpck. You must also have a high-level driver for the type of device that you want to support. config PARIDE_BPCK6 @@ -144,7 +144,7 @@ If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a loadable module. The module will be - called bpck6.o. You must also have a high-level driver for the type + called bpck6. You must also have a high-level driver for the type of device that you want to support. config PARIDE_COMM @@ -155,7 +155,7 @@ protocol from DataStor. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a loadable - module. The module will be called comm.o. You must also have + module. The module will be called comm. You must also have a high-level driver for the type of device that you want to support. config PARIDE_DSTR @@ -166,7 +166,7 @@ protocol from DataStor. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a loadable - module. The module will be called dstr.o. You must also have + module. The module will be called dstr. You must also have a high-level driver for the type of device that you want to support. config PARIDE_FIT2 @@ -178,7 +178,7 @@ (low speed) adapter that is used in some portable hard drives. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M - to build it as a loadable module. The module will be called ktti.o. + to build it as a loadable module. The module will be called ktti. You must also have a high-level driver for the type of device that you want to support. @@ -192,7 +192,7 @@ devices. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a loadable module. The module will be - called fit3.o. You must also have a high-level driver for the type + called fit3. You must also have a high-level driver for the type of device that you want to support. config PARIDE_EPAT @@ -205,7 +205,7 @@ Hewlett-Packard, SyQuest, Imation and Avatar. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a - loadable module. The module will be called epat.o. You must also + loadable module. The module will be called epat. You must also have a high-level driver for the type of device that you want to support. @@ -226,7 +226,7 @@ found in some no-name kits. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a loadable - module. The module will be called epia.o. You must also have a + module. The module will be called epia. You must also have a high-level driver for the type of device that you want to support. config PARIDE_FRIQ @@ -238,7 +238,7 @@ drive. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a loadable module. The module will be - called friq.o. You must also have a high-level driver for the type + called friq. You must also have a high-level driver for the type of device that you want to support. config PARIDE_FRPW @@ -249,7 +249,7 @@ protocol. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a loadable module. The module will be - called frpw.o. You must also have a high-level driver for the type + called frpw. You must also have a high-level driver for the type of device that you want to support. config PARIDE_KBIC @@ -262,7 +262,7 @@ especially in Europe. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a loadable module. The - module will be called kbic.o. You must also have a high-level driver + module will be called kbic. You must also have a high-level driver for the type of device that you want to support. config PARIDE_KTTI @@ -274,7 +274,7 @@ used in some 2.5" portable hard drives. If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a - loadable module. The module will be called ktti.o. You must also + loadable module. The module will be called ktti. You must also have a high-level driver for the type of device that you want to support. @@ -287,7 +287,7 @@ name). If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a loadable module. The module will - be called on20.o. You must also have a high-level driver for the + be called on20. You must also have a high-level driver for the type of device that you want to support. config PARIDE_ON26 @@ -299,7 +299,7 @@ name). If you chose to build PARIDE support into your kernel, you may answer Y here to build in the protocol driver, otherwise you should answer M to build it as a loadable module. The module will be - called on26.o. You must also have a high-level driver for the type + called on26. You must also have a high-level driver for the type of device that you want to support. # diff -Nru a/drivers/block/paride/Makefile b/drivers/block/paride/Makefile --- a/drivers/block/paride/Makefile Sun Feb 9 21:13:36 2003 +++ b/drivers/block/paride/Makefile Sun Feb 9 21:13:36 2003 @@ -5,8 +5,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs := paride.o - obj-$(CONFIG_PARIDE) += paride.o obj-$(CONFIG_PARIDE_ATEN) += aten.o obj-$(CONFIG_PARIDE_BPCK) += bpck.o diff -Nru a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig --- a/drivers/bluetooth/Kconfig Sun Feb 9 21:13:31 2003 +++ b/drivers/bluetooth/Kconfig Sun Feb 9 21:13:31 2003 @@ -11,7 +11,7 @@ USB interface. Say Y here to compile support for Bluetooth USB devices into the - kernel or say M to compile it as module (hci_usb.o). + kernel or say M to compile it as module (hci_usb). config BT_USB_ZERO_PACKET bool "USB zero packet support" @@ -34,7 +34,7 @@ adapter and BrainBoxes Bluetooth PC Card. Say Y here to compile support for Bluetooth UART devices into the - kernel or say M to compile it as module (hci_uart.o). + kernel or say M to compile it as module (hci_uart). config BT_HCIUART_H4 bool "UART (H4) protocol support" @@ -68,7 +68,7 @@ Socket Bluetooth CF Card Say Y here to compile support for HCI DTL1 devices into the - kernel or say M to compile it as module (dtl1_cs.o). + kernel or say M to compile it as module (dtl1_cs). config BT_HCIBT3C tristate "HCI BT3C (PC Card) driver" @@ -84,7 +84,7 @@ the BlueFW package. For more information, see . Say Y here to compile support for HCI BT3C devices into the - kernel or say M to compile it as module (bt3c_cs.o). + kernel or say M to compile it as module (bt3c_cs). config BT_HCIBLUECARD tristate "HCI BlueCard (PC Card) driver" @@ -97,7 +97,7 @@ Anycom Bluetooth CF Card Say Y here to compile support for HCI BlueCard devices into the - kernel or say M to compile it as module (bluecard_cs.o). + kernel or say M to compile it as module (bluecard_cs). config BT_HCIVHCI tristate "HCI VHCI (Virtual HCI device) driver" @@ -107,7 +107,7 @@ This driver is required if you want to use HCI Emulation software. Say Y here to compile support for virtual HCI devices into the - kernel or say M to compile it as module (hci_vhci.o). + kernel or say M to compile it as module (hci_vhci). endmenu diff -Nru a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c --- a/drivers/bluetooth/bt3c_cs.c Sun Feb 9 21:13:37 2003 +++ b/drivers/bluetooth/bt3c_cs.c Sun Feb 9 21:13:37 2003 @@ -528,19 +528,19 @@ } /* Block signals, everything but SIGKILL/SIGSTOP */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); tmpsig = current->blocked; siginitsetinv(¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP)); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); result = waitpid(pid, NULL, __WCLONE); /* Allow signals again */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = tmpsig; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (result != pid) { printk(KERN_WARNING "bt3c_cs: Waiting for pid %d failed (errno=%d).\n", pid, -result); diff -Nru a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig --- a/drivers/cdrom/Kconfig Sun Feb 9 21:13:35 2003 +++ b/drivers/cdrom/Kconfig Sun Feb 9 21:13:35 2003 @@ -18,7 +18,7 @@ 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 will be called aztcd.o. If you want to compile it as a + The module will be called aztcd. If you want to compile it as a module, say M here and read . config GSCD @@ -36,7 +36,7 @@ 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 will be called gscd.o. If you want to compile it as a + The module will be called gscd. If you want to compile it as a module, say M here and read . config SBPCD @@ -76,7 +76,7 @@ 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 will be called sbpcd.o. If you want to compile it as a + The module will be called sbpcd. If you want to compile it as a module, say M here and read . config MCD @@ -101,7 +101,7 @@ 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 will be called mcd.o. If you want to compile it as a + The module will be called mcd. If you want to compile it as a module, say M here and read . config MCD_IRQ @@ -142,7 +142,7 @@ 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 will be called mcdx.o. If you want to compile it as a + The module will be called mcdx. If you want to compile it as a module, say M here and read . config OPTCD @@ -161,7 +161,7 @@ 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 will be called optcd.o. If you want to compile it as a + The module will be called optcd. If you want to compile it as a module, say M here and read . config CM206 @@ -178,7 +178,7 @@ 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 will be called cm206.o. If you want to compile it as a + The module will be called cm206. If you want to compile it as a module, say M here and read . config SJCD @@ -192,7 +192,7 @@ 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 will be called sjcd.o. If you want to compile it as a + The module will be called sjcd. If you want to compile it as a module, say M here and read . config ISP16_CDI @@ -207,7 +207,7 @@ 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 will be called isp16.o. If you want to compile it as a + The module will be called isp16. If you want to compile it as a module, say M here and read . config CDU31A @@ -229,7 +229,7 @@ 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 will be called cdu31a.o. If you want to compile it as a + The module will be called cdu31a. If you want to compile it as a module, say M here and read . config CDU535 @@ -245,6 +245,6 @@ 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 will be called sonycd535.o. If you want to compile it as + The module will be called sonycd535. If you want to compile it as a module, say M here and read . diff -Nru a/drivers/cdrom/Makefile b/drivers/cdrom/Makefile --- a/drivers/cdrom/Makefile Sun Feb 9 21:13:31 2003 +++ b/drivers/cdrom/Makefile Sun Feb 9 21:13:31 2003 @@ -3,22 +3,6 @@ # 30 Jan 1998, Michael Elizabeth Chastain, # Rewritten to use lists instead of if-statements. -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := cdrom.o - - - -# Object file lists. - -obj-y := -obj-m := -obj-n := -obj- := - - - # Each configuration option enables a list of files. obj-$(CONFIG_BLK_DEV_IDECD) += cdrom.o diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig --- a/drivers/char/Kconfig Sun Feb 9 21:13:28 2003 +++ b/drivers/char/Kconfig Sun Feb 9 21:13:28 2003 @@ -91,7 +91,7 @@ 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 . You will get - two modules called ip2.o and ip2main.o. + two modules called ip2 and ip2main. config ROCKETPORT tristate "Comtrol Rocketport support" @@ -104,7 +104,7 @@ If you want to compile this driver as a module, say M here and read . The module will be called - rocket.o. + rocket. config CYCLADES tristate "Cyclades async mux support" @@ -122,7 +122,7 @@ 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 cyclades.o. + will be called cyclades. If you haven't heard about it, it's safe to say N. @@ -155,7 +155,7 @@ one of the two drivers. If you want to compile this driver as a module, say M here and read - . The module will be called epca.o. + . The module will be called epca. config DIGI tristate "Digiboard PC/Xx Support" @@ -168,7 +168,7 @@ Y here and read the file . If you want to compile this driver as a module, say M here and read - . The module will be called pcxx.o. + . The module will be called pcxx. config ESPSERIAL tristate "Hayes ESP serial port support" @@ -181,7 +181,7 @@ To compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module will be - called esp.o. If unsure, say N. + called esp. If unsure, say N. config MOXA_INTELLIO tristate "Moxa Intellio support" @@ -191,7 +191,7 @@ This driver can also be built as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called moxa.o. If you want to do that, say M + The module will be called moxa. If you want to do that, say M here. config MOXA_SMARTIO @@ -202,7 +202,7 @@ This driver can also be built as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called mxser.o. If you want to do that, say M + The module will be called mxser. If you want to do that, say M here. config ISI @@ -214,7 +214,7 @@ built as a module ( = code which can be inserted in and removed from the running kernel whenever you want). Please read . The module will be called - isicom.o. + isicom. config SYNCLINK tristate "Microgate SyncLink card support" @@ -226,7 +226,7 @@ This driver can only be built as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called synclink.o. If you want to do that, say M + The module will be called synclink. If you want to do that, say M here. config SYNCLINKMP @@ -240,7 +240,7 @@ This driver may be built as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called synclinkmp.o. If you want to do that, say M + The module will be called synclinkmp. If you want to do that, say M here. config N_HDLC @@ -252,7 +252,7 @@ This driver can only be built as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called n_hdlc.o. If you want to do that, say M + The module will be called n_hdlc. If you want to do that, say M here. config RISCOM8 @@ -266,7 +266,7 @@ say Y here and read the file . Also it's possible to say M here and compile this driver as kernel - loadable module; the module will be called riscom8.o. + loadable module; the module will be called riscom8. config SPECIALIX tristate "Specialix IO8+ card support" @@ -280,7 +280,7 @@ If you have a card like that, say Y here and read the file . Also it's possible to say M here and compile this driver as kernel loadable module which will be - called specialix.o. + called specialix. config SPECIALIX_RTSCTS bool "Specialix DTR/RTS pin is RTS" @@ -301,7 +301,7 @@ This driver can only be built as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called sx.o. If you want to do that, say M here. + The module will be called sx. If you want to do that, say M here. config RIO tristate "Specialix RIO system support" @@ -343,7 +343,7 @@ 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 stallion.o. + will be called stallion. config ISTALLION tristate "Stallion EC8/64, ONboard, Brumby support" @@ -356,7 +356,7 @@ To compile it 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 - istallion.o. + istallion. config SERIAL_TX3912 bool "TMPTX3912/PR31700 serial port support" @@ -430,9 +430,9 @@ for which 8 pin to DB25 adapters were supplied. The card also had jumpers internally to toggle various pinning configurations. - This driver can be built as a module; but then "generic_serial.o" + This driver can be built as a module; but then "generic_serial" will also be built as a module. This has to be loaded before - "ser_a2232.o". If you want to do this, answer M here and read + "ser_a2232". If you want to do this, answer M here and read "". source "drivers/serial/Kconfig" @@ -495,7 +495,7 @@ driver as a module however ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read and - . The module will be called lp.o. + . The module will be called lp. If you have several parallel ports, you can specify which ports to use with the "lp" kernel command line option. (Try "man bootparam" @@ -539,7 +539,7 @@ This support is also available as a module. If you want to compile it as a module, say M here and read . The module will be called - ppdev.o. + ppdev. If unsure, say N. @@ -558,7 +558,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called tipar.o. If you want to compile it as a + The module will be called tipar. If you want to compile it as a module, say M here and read Documentation/modules.txt. If you don't know what a parallel link cable is or what a Texas @@ -598,7 +598,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called busmouse.o. If you want to compile it as a + The module will be called busmouse. If you want to compile it as a module, say M here and read . endmenu @@ -610,7 +610,7 @@ to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module will be called - tpqic02.o. + tpqic02. config QIC02_DYNCONF bool "Do you want runtime configuration for QIC-02" @@ -649,7 +649,7 @@ found in the NetWinder. This driver allows the user to control the temperature set points and to read the current temperature. - It is also possible to say M here to build it as a module (ds1620.o) + It is also possible to say M here to build it as a module (ds1620) It is recommended to be used on a NetWinder, but it is not a necessity. @@ -675,7 +675,7 @@ inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . The module will be called - nwbutton.o. + nwbutton. Most people will answer Y to this question and "Reboot Using Button" below to be able to initiate a system shutdown from the button. @@ -704,7 +704,7 @@ 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 will be called nwflash.o. If you want to compile it as a + The module will be called nwflash. If you want to compile it as a module, say M here and read . If you're not sure, say N. @@ -723,7 +723,7 @@ To compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module will be called - i810_rng.o. + i810_rng. If unsure, say N. @@ -741,7 +741,7 @@ To compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module will be called - amd768_rng.o. + amd768_rng. If unsure, say N. @@ -769,7 +769,7 @@ 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 will be called nvram.o. If you want to compile it as a + The module will be called nvram. If you want to compile it as a module, say M here and read . config RTC @@ -797,7 +797,7 @@ 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 rtc.o. If you want to compile it as a module, + The module is called rtc. If you want to compile it as a module, say M here and read . config GEN_RTC @@ -817,7 +817,7 @@ 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 genrtc.o. If you want to compile it as a module, + The module is called genrtc. If you want to compile it as a module, say M here and read . To load the module automatically add 'alias char-major-10-135 genrtc' to your /etc/modules.conf @@ -851,7 +851,7 @@ called the `internal DoubleTalk'. 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 dtlk.o. + . The module will be called dtlk. config R3964 tristate "Siemens R3964 line discipline" @@ -863,7 +863,7 @@ To compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module will be called - n_r3964.o. + n_r3964. If unsure, say N. @@ -879,7 +879,7 @@ To compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module will be called - applicom.o. + applicom. If unsure, say N. @@ -896,7 +896,7 @@ If you want to compile the driver 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 sonypi.o. + will be called sonypi. menu "Ftape, the floppy tape device driver" @@ -927,7 +927,7 @@ module ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . The - module will be called ftape.o. + module will be called ftape. Note that the Ftape-HOWTO is out of date (sorry) and documents the older version 2.08 of this software but still contains useful @@ -973,7 +973,7 @@ 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 will be called mwave.o. If you want to compile it as + The module will be called mwave. If you want to compile it as a module, say M here and read Documentation/modules.txt. config SCx200_GPIO @@ -983,7 +983,7 @@ Give userspace access to the GPIO pins on the National Semiconductor SCx200 processors. - If compiled as a module, it will be called scx200_gpio.o. + If compiled as a module, it will be called scx200_gpio. config RAW_DRIVER tristate "RAW driver (/dev/raw/rawN)" @@ -991,6 +991,13 @@ The raw driver permits block devices to be bound to /dev/raw/rawN. Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. See the raw(8) manpage for more details. + +config HANGCHECK_TIMER + tristate "Hangcheck timer" + help + The hangcheck-timer module detects when the system has gone + out to lunch past a certain margin. It can reboot the system + or merely print a warning. endmenu diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile --- a/drivers/char/Makefile Sun Feb 9 21:13:36 2003 +++ b/drivers/char/Makefile Sun Feb 9 21:13:36 2003 @@ -9,13 +9,6 @@ obj-y += mem.o tty_io.o n_tty.o tty_ioctl.o pty.o misc.o random.o -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := busmouse.o vt.o generic_serial.o ip2main.o consolemap.o\ - ite_gpio.o keyboard.o misc.o nvram.o random.o rtc.o \ - selection.o sonypi.o sysrq.o tty_io.o tty_ioctl.o - obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o consolemap.o consolemap_deftbl.o selection.o keyboard.o obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o @@ -84,6 +77,7 @@ obj-$(CONFIG_PCMCIA) += pcmcia/ obj-$(CONFIG_IPMI_HANDLER) += ipmi/ +obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o # Files generated that shall be removed upon make clean clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c diff -Nru a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig --- a/drivers/char/agp/Kconfig Sun Feb 9 21:13:32 2003 +++ b/drivers/char/agp/Kconfig Sun Feb 9 21:13:32 2003 @@ -23,7 +23,7 @@ This driver is available as a module. If you want to compile it as a module, say M here and read . The - module will be called agpgart.o. + module will be called agpgart. config AGP_GART bool "/dev/agpgart (AGP Support)" diff -Nru a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile --- a/drivers/char/agp/Makefile Sun Feb 9 21:13:30 2003 +++ b/drivers/char/agp/Makefile Sun Feb 9 21:13:30 2003 @@ -3,8 +3,6 @@ # space ioctl interface to use agp memory. It also adds a kernel interface # that other drivers could use to manipulate agp memory. -export-objs := backend.o - agpgart-y := backend.o frontend.o generic.o agpgart-$(CONFIG_AGP3) += generic-3.0.o agpgart-objs := $(agpgart-y) diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h --- a/drivers/char/agp/agp.h Sun Feb 9 21:13:31 2003 +++ b/drivers/char/agp/agp.h Sun Feb 9 21:13:31 2003 @@ -47,7 +47,7 @@ flush_agp_cache(); } #else -static void global_cache_flush(void) +static inline void global_cache_flush(void) { flush_agp_cache(); } diff -Nru a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig --- a/drivers/char/drm/Kconfig Sun Feb 9 21:13:35 2003 +++ b/drivers/char/drm/Kconfig Sun Feb 9 21:13:35 2003 @@ -20,7 +20,7 @@ depends on DRM help Choose this option if you have a 3dfx Banshee or Voodoo3 (or later), - graphics card. If M is selected, the module will be called tdfx.o. + graphics card. If M is selected, the module will be called tdfx. # tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA config DRM_R128 @@ -28,7 +28,7 @@ depends on DRM help Choose this option if you have an ATI Rage 128 graphics card. If M - is selected, the module will be called r128.o. AGP support for + is selected, the module will be called r128. AGP support for this card is strongly suggested (unless you have a PCI version). config DRM_RADEON @@ -39,14 +39,14 @@ are both PCI and AGP versions. You don't need to choose this to run the Radeon in plain VGA mode. There is a product page at . - If M is selected, the module will be called radeon.o. + If M is selected, the module will be called radeon. config DRM_I810 tristate "Intel I810" depends on DRM && AGP help Choose this option if you have an Intel I810 graphics card. If M is - selected, the module will be called i810.o. AGP support is required + selected, the module will be called i810. AGP support is required for this driver to work. config DRM_I830 @@ -58,6 +58,6 @@ depends on DRM && AGP help Choose this option if you have a Matrox G200, G400 or G450 graphics - card. If M is selected, the module will be called mga.o. AGP + card. If M is selected, the module will be called mga. AGP support is required for this driver to work. diff -Nru a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c --- a/drivers/char/drm/i830_dma.c Sun Feb 9 21:13:29 2003 +++ b/drivers/char/drm/i830_dma.c Sun Feb 9 21:13:29 2003 @@ -454,7 +454,7 @@ DRM_DEBUG("pitch_bits %x\n", init->pitch_bits); dev_priv->cpp = init->cpp; - /* We are using seperate values as placeholders for mechanisms for + /* We are using separate values as placeholders for mechanisms for * private backbuffer/depthbuffer usage. */ diff -Nru a/drivers/char/ftape/Kconfig b/drivers/char/ftape/Kconfig --- a/drivers/char/ftape/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/char/ftape/Kconfig Sun Feb 9 21:13:29 2003 @@ -18,14 +18,14 @@ module ( = code which can be inserted in and removed from the running kernel whenever you want). In this case you should read . The module will be called - zftape.o. + zftape. Regardless of whether you say Y or M here, an additional runtime - loadable module called `zft-compressor.o' which contains code to + loadable module called `zft-compressor' which contains code to support user transparent on-the-fly compression based on Ross William's lzrw3 algorithm will be produced. If you have enabled the kernel module loader (i.e. have said Y to "Kernel module loader - support", above) then `zft-compressor.o' will be loaded + support", above) then `zft-compressor' will be loaded automatically by zftape when needed. Despite its name, zftape does NOT use compression by default. The diff -Nru a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c --- a/drivers/char/ftape/compressor/zftape-compress.c Sun Feb 9 21:13:35 2003 +++ b/drivers/char/ftape/compressor/zftape-compress.c Sun Feb 9 21:13:35 2003 @@ -1196,11 +1196,7 @@ printk( KERN_INFO "(c) 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n" KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n" -KERN_INFO "Compiled for kernel version %s" -#ifdef MODVERSIONS - " with versioned symbols" -#endif - "\n", UTS_RELEASE); +KERN_INFO "Compiled for kernel version %s\n", UTS_RELEASE); } #else /* !MODULE */ /* print a short no-nonsense boot message */ diff -Nru a/drivers/char/ftape/lowlevel/Makefile b/drivers/char/ftape/lowlevel/Makefile --- a/drivers/char/ftape/lowlevel/Makefile Sun Feb 9 21:13:30 2003 +++ b/drivers/char/ftape/lowlevel/Makefile Sun Feb 9 21:13:30 2003 @@ -23,8 +23,6 @@ # driver for Linux. # -export-objs := ftape_syms.o - obj-$(CONFIG_FTAPE) += ftape.o ftape-objs := ftape-init.o fdc-io.o fdc-isr.o \ diff -Nru a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c --- a/drivers/char/ftape/lowlevel/fdc-io.c Sun Feb 9 21:13:30 2003 +++ b/drivers/char/ftape/lowlevel/fdc-io.c Sun Feb 9 21:13:30 2003 @@ -386,11 +386,11 @@ /* timeout time will be up to USPT microseconds too long ! */ timeout = (1000 * time + FT_USPT - 1) / FT_USPT; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); old_sigmask = current->blocked; sigfillset(¤t->blocked); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; add_wait_queue(&ftape_wait_intr, &wait); @@ -398,10 +398,10 @@ timeout = schedule_timeout(timeout); } - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = old_sigmask; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); remove_wait_queue(&ftape_wait_intr, &wait); /* the following IS necessary. True: as well diff -Nru a/drivers/char/ftape/lowlevel/ftape-init.c b/drivers/char/ftape/lowlevel/ftape-init.c --- a/drivers/char/ftape/lowlevel/ftape-init.c Sun Feb 9 21:13:35 2003 +++ b/drivers/char/ftape/lowlevel/ftape-init.c Sun Feb 9 21:13:35 2003 @@ -70,11 +70,7 @@ KERN_INFO "(c) 1995-1996 Kai Harrekilde-Petersen (khp@dolphinics.no)\n" KERN_INFO "(c) 1996-1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n" KERN_INFO "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives\n" -KERN_INFO "Compiled for Linux version %s" -#ifdef MODVERSIONS - " with versioned symbols" -#endif - "\n", UTS_RELEASE); +KERN_INFO "Compiled for Linux version %s\n", UTS_RELEASE); } #else /* !MODULE */ /* print a short no-nonsense boot message */ diff -Nru a/drivers/char/ftape/zftape/Makefile b/drivers/char/ftape/zftape/Makefile --- a/drivers/char/ftape/zftape/Makefile Sun Feb 9 21:13:34 2003 +++ b/drivers/char/ftape/zftape/Makefile Sun Feb 9 21:13:34 2003 @@ -27,8 +27,6 @@ # ZFT_OBSOLETE - enable the MTIOC_ZFTAPE_GETBLKSZ ioctl. You should # leave this enabled for compatibility with taper. -export-objs := zftape_syms.o - obj-$(CONFIG_ZFTAPE) += zftape.o zftape-objs := zftape-rw.o zftape-ctl.o zftape-read.o \ diff -Nru a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c --- a/drivers/char/ftape/zftape/zftape-init.c Sun Feb 9 21:13:31 2003 +++ b/drivers/char/ftape/zftape/zftape-init.c Sun Feb 9 21:13:31 2003 @@ -331,11 +331,7 @@ KERN_INFO "and builtin compression (lzrw3 algorithm).\n" KERN_INFO -"Compiled for Linux version %s" -#ifdef MODVERSIONS - " with versioned symbols" -#endif - "\n", UTS_RELEASE); +"Compiled for Linux version %s\n", UTS_RELEASE); } #else /* !MODULE */ /* print a short no-nonsense boot message */ diff -Nru a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/char/hangcheck-timer.c Sun Feb 9 21:13:37 2003 @@ -0,0 +1,127 @@ +/* + * hangcheck-timer.c + * + * Driver for a little io fencing timer. + * + * Copyright (C) 2002 Oracle Corporation. All rights reserved. + * + * Author: Joel Becker + * + * 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. + * + * 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 recieved 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 021110-1307, USA. + */ + +/* + * The hangcheck-timer driver uses the TSC to catch delays that + * jiffies does not notice. A timer is set. When the timer fires, it + * checks whether it was delayed and if that delay exceeds a given + * margin of error. The hangcheck_tick module paramter takes the timer + * duration in seconds. The hangcheck_margin parameter defines the + * margin of error, in seconds. The defaults are 60 seconds for the + * timer and 180 seconds for the margin of error. IOW, a timer is set + * for 60 seconds. When the timer fires, the callback checks the + * actual duration that the timer waited. If the duration exceeds the + * alloted time and margin (here 60 + 180, or 240 seconds), the machine + * is restarted. A healthy machine will have the duration match the + * expected timeout very closely. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define VERSION_STR "0.5.0" + +#define DEFAULT_IOFENCE_MARGIN 60 /* Default fudge factor, in seconds */ +#define DEFAULT_IOFENCE_TICK 180 /* Default timer timeout, in seconds */ + +static int hangcheck_tick = DEFAULT_IOFENCE_TICK; +static int hangcheck_margin = DEFAULT_IOFENCE_MARGIN; +static int hangcheck_reboot; /* Defaults to not reboot */ + +/* Driver options */ +module_param(hangcheck_tick, int, 0); +MODULE_PARM_DESC(hangcheck_tick, "Timer delay."); +module_param(hangcheck_margin, int, 0); +MODULE_PARM_DESC(hangcheck_margin, "If the hangcheck timer has been delayed more than hangcheck_margin seconds, the driver will fire."); +module_param(hangcheck_reboot, int, 0); +MODULE_PARM_DESC(hangcheck_reboot, "If nonzero, the machine will reboot when the timer margin is exceeded."); + +MODULE_AUTHOR("Joel Becker"); +MODULE_DESCRIPTION("Hangcheck-timer detects when the system has gone out to lunch past a certain margin."); +MODULE_LICENSE("GPL"); + + +/* Last time scheduled */ +static unsigned long long hangcheck_tsc, hangcheck_tsc_margin; + +static void hangcheck_fire(unsigned long); + +static struct timer_list hangcheck_ticktock = + TIMER_INITIALIZER(hangcheck_fire, 0, 0); + +static void hangcheck_fire(unsigned long data) +{ + unsigned long long cur_tsc, tsc_diff; + + cur_tsc = get_cycles(); + + if (cur_tsc > hangcheck_tsc) + tsc_diff = cur_tsc - hangcheck_tsc; + else + tsc_diff = (cur_tsc + (~0ULL - hangcheck_tsc)); /* or something */ + + if (tsc_diff > hangcheck_tsc_margin) { + if (hangcheck_reboot) { + printk(KERN_CRIT "Hangcheck: hangcheck is restarting the machine.\n"); + machine_restart(NULL); + } else { + printk(KERN_CRIT "Hangcheck: hangcheck value past margin!\n"); + } + } + mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); + hangcheck_tsc = get_cycles(); +} + + +static int __init hangcheck_init(void) +{ + printk("Hangcheck: starting hangcheck timer %s (tick is %d seconds, margin is %d seconds).\n", + VERSION_STR, hangcheck_tick, hangcheck_margin); + + hangcheck_tsc_margin = hangcheck_margin + hangcheck_tick; + hangcheck_tsc_margin *= HZ; + hangcheck_tsc_margin *= current_cpu_data.loops_per_jiffy; + + hangcheck_tsc = get_cycles(); + mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); + + return 0; +} + + +static void __exit hangcheck_exit(void) +{ + del_timer_sync(&hangcheck_ticktock); +} + +module_init(hangcheck_init); +module_exit(hangcheck_exit); diff -Nru a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c --- a/drivers/char/ip2/i2ellis.c Sun Feb 9 21:13:28 2003 +++ b/drivers/char/ip2/i2ellis.c Sun Feb 9 21:13:28 2003 @@ -773,7 +773,7 @@ // // Writes 'count' bytes from 'address' to the data fifo specified by the board // structure pointer pB. Should count happen to be odd, an extra pad byte is -// sent (identity unknown...). This is to be consistant with the 16-bit version. +// sent (identity unknown...). This is to be consistent with the 16-bit version. // Uses 8-bit (byte) operations. Is called indirectly through pB->i2eWriteBuf. // //****************************************************************************** diff -Nru a/drivers/char/ip2/i2os.h b/drivers/char/ip2/i2os.h --- a/drivers/char/ip2/i2os.h Sun Feb 9 21:13:32 2003 +++ b/drivers/char/ip2/i2os.h Sun Feb 9 21:13:32 2003 @@ -8,7 +8,7 @@ * PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport * serial I/O controllers. * -* DESCRIPTION: Defines, definitions and includes which are heavily dependant +* DESCRIPTION: Defines, definitions and includes which are heavily dependent * on O/S, host, compiler, etc. This file is tailored for: * Linux v2.0.0 and later * Gnu gcc c2.7.2 diff -Nru a/drivers/char/ip2main.c b/drivers/char/ip2main.c --- a/drivers/char/ip2main.c Sun Feb 9 21:13:37 2003 +++ b/drivers/char/ip2main.c Sun Feb 9 21:13:37 2003 @@ -21,7 +21,7 @@ // // 1.2.14 /\/\|=mhw=|\/\/ // Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts. -// Changed the definition of ip2trace to be more consistant with kernel style +// Changed the definition of ip2trace to be more consistent with kernel style // Thanks to Andreas Dilger for these updates // // 1.2.13 /\/\|=mhw=|\/\/ @@ -1466,7 +1466,7 @@ } #ifdef NEVER_HAPPENS_AS_SETUP_XXX // and can't work because we don't know the_char - // as the_char is reported on a seperate path + // as the_char is reported on a separate path // The intelligent board does this stuff as setup { char brkf = TTY_NORMAL; diff -Nru a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile --- a/drivers/char/ipmi/Makefile Sun Feb 9 21:13:36 2003 +++ b/drivers/char/ipmi/Makefile Sun Feb 9 21:13:36 2003 @@ -2,8 +2,6 @@ # Makefile for the ipmi drivers. # -export-objs := ipmi_msghandler.o ipmi_watchdog.o - ipmi_kcs_drv-objs := ipmi_kcs_sm.o ipmi_kcs_intf.o obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c --- a/drivers/char/keyboard.c Sun Feb 9 21:13:31 2003 +++ b/drivers/char/keyboard.c Sun Feb 9 21:13:31 2003 @@ -918,7 +918,7 @@ DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); -#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) +#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] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, diff -Nru a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c --- a/drivers/char/n_hdlc.c Sun Feb 9 21:13:30 2003 +++ b/drivers/char/n_hdlc.c Sun Feb 9 21:13:30 2003 @@ -35,7 +35,7 @@ * callback directly to avoid fragmenting or concatenating * multiple frames into a single receive callback. * - * The HDLC line discipline queues the receive frames in seperate + * The HDLC line discipline queues the receive frames in separate * buffers so complete receive frames can be returned by the * tty read calls. * diff -Nru a/drivers/char/n_tty.c b/drivers/char/n_tty.c --- a/drivers/char/n_tty.c Sun Feb 9 21:13:28 2003 +++ b/drivers/char/n_tty.c Sun Feb 9 21:13:28 2003 @@ -787,7 +787,7 @@ int is_ignored(int sig) { return (sigismember(¤t->blocked, sig) || - current->sig->action[sig-1].sa.sa_handler == SIG_IGN); + current->sighand->action[sig-1].sa.sa_handler == SIG_IGN); } static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) diff -Nru a/drivers/char/nvram.c b/drivers/char/nvram.c --- a/drivers/char/nvram.c Sun Feb 9 21:13:31 2003 +++ b/drivers/char/nvram.c Sun Feb 9 21:13:31 2003 @@ -11,7 +11,7 @@ * "NVRAM" (NV stands for non-volatile). * * The data are supplied as a (seekable) character device, /dev/nvram. The - * size of this file is dependant on the controller. The usual size is 114, + * size of this file is dependent on the controller. The usual size is 114, * the number of freely available bytes in the memory (i.e., not used by the * RTC itself). * diff -Nru a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig --- a/drivers/char/pcmcia/Kconfig Sun Feb 9 21:13:35 2003 +++ b/drivers/char/pcmcia/Kconfig Sun Feb 9 21:13:35 2003 @@ -15,7 +15,7 @@ This driver may be built as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called synclinkmp.o. If you want to do that, say M + The module will be called synclinkmp. If you want to do that, say M here. endmenu diff -Nru a/drivers/char/rio/cmdpkt.h b/drivers/char/rio/cmdpkt.h --- a/drivers/char/rio/cmdpkt.h Sun Feb 9 21:13:29 2003 +++ b/drivers/char/rio/cmdpkt.h Sun Feb 9 21:13:29 2003 @@ -41,7 +41,7 @@ /* ** overlays for the data area of a packet. Used in both directions ** (to build a packet to send, and to interpret a packet that arrives) -** and is very inconvenient for MIPS, so they appear as two seperate +** and is very inconvenient for MIPS, so they appear as two separate ** structures - those used for modifying/reading packets on the card ** and those for modifying/reading packets in real memory, which have an _M ** suffix. diff -Nru a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c --- a/drivers/char/rio/riotty.c Sun Feb 9 21:13:31 2003 +++ b/drivers/char/rio/riotty.c Sun Feb 9 21:13:31 2003 @@ -1287,7 +1287,7 @@ } /* - ttyseth -- set hardware dependant tty settings + ttyseth -- set hardware dependent tty settings */ void ttyseth(PortP, s, sg) @@ -1342,7 +1342,7 @@ } /* - ttyseth_pv -- set hardware dependant tty settings using either the + ttyseth_pv -- set hardware dependent tty settings using either the POSIX termios structure or the System V termio structure. sysv = 0 => (POSIX): struct termios *sg sysv != 0 => (System V): struct termio *sg diff -Nru a/drivers/char/rtc.c b/drivers/char/rtc.c --- a/drivers/char/rtc.c Sun Feb 9 21:13:31 2003 +++ b/drivers/char/rtc.c Sun Feb 9 21:13:31 2003 @@ -171,7 +171,7 @@ * A very tiny interrupt handler. It runs with SA_INTERRUPT set, * but there is possibility of conflicting with the set_rtc_mmss() * call (the rtc irq and the timer irq can easily run at the same - * time in two different CPUs). So we need to serializes + * time in two different CPUs). So we need to serialize * accesses to the chip with the rtc_lock spinlock that each * architecture should implement in the timer code. * (See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.) @@ -401,22 +401,18 @@ min = alm_tm.tm_min; sec = alm_tm.tm_sec; - if (hrs >= 24) - hrs = 0xff; - - if (min >= 60) - min = 0xff; - - if (sec >= 60) - sec = 0xff; - spin_lock_irq(&rtc_lock); if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); + if (sec < 60) BIN_TO_BCD(sec); + else sec = 0xff; + + if (min < 60) BIN_TO_BCD(min); + else min = 0xff; + + if (hrs < 24) BIN_TO_BCD(hrs); + else hrs = 0xff; } CMOS_WRITE(hrs, RTC_HOURS_ALARM); CMOS_WRITE(min, RTC_MINUTES_ALARM); @@ -486,7 +482,7 @@ yrs = 73; } #endif - /* These limits and adjustments are independant of + /* These limits and adjustments are independent of * whether the chip is in binary mode or not. */ if (yrs > 169) { diff -Nru a/drivers/char/synclink.c b/drivers/char/synclink.c --- a/drivers/char/synclink.c Sun Feb 9 21:13:30 2003 +++ b/drivers/char/synclink.c Sun Feb 9 21:13:31 2003 @@ -6098,7 +6098,7 @@ /* * Program the Bus Configuration Register (BCR) * - * <15> 0 Don't use seperate address + * <15> 0 Don't use separate address * <14..6> 0 reserved * <5..4> 00 IAckmode = Default, don't care * <3> 1 Bus Request Totem Pole output diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c --- a/drivers/char/tty_io.c Sun Feb 9 21:13:33 2003 +++ b/drivers/char/tty_io.c Sun Feb 9 21:13:33 2003 @@ -442,6 +442,13 @@ file_list_lock(); for (l = tty->tty_files.next; l != &tty->tty_files; l = l->next) { struct file * filp = list_entry(l, struct file, f_list); + /* + * If this file descriptor has been closed, ignore it; it + * will be going away shortly. (We don't test filp->f_count + * for zero since that could open another race.) --rmk + */ + if (filp->private_data == NULL) + continue; if (IS_CONSOLE_DEV(filp->f_dentry->d_inode->i_rdev) || IS_SYSCONS_DEV(filp->f_dentry->d_inode->i_rdev)) { cons_filp = filp; diff -Nru a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig --- a/drivers/char/watchdog/Kconfig Sun Feb 9 21:13:33 2003 +++ b/drivers/char/watchdog/Kconfig Sun Feb 9 21:13:33 2003 @@ -50,7 +50,7 @@ inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . The module will be called - softdog.o. + softdog. config WDT tristate "WDT Watchdog timer" @@ -66,7 +66,7 @@ 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 wdt.o. + will be called wdt. config WDTPCI tristate "WDT PCI Watchdog timer" @@ -82,7 +82,7 @@ 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 wdt_pci.o. + will be called wdt_pci. config WDT_501 bool "WDT501 features" @@ -115,7 +115,7 @@ 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 pcwd.o. If you want to compile it as a module, + The module is called pcwd. If you want to compile it as a module, say M here and read . Most people will say N. @@ -132,7 +132,7 @@ This driver is like the WDT501 driver but for different hardware. 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 pscwdt.o. If you want to compile it as a + The module is called pscwdt. If you want to compile it as a module, say M here and read . Most people will say N. @@ -150,7 +150,7 @@ help The Intel Footbridge chip contains a builtin watchdog circuit. Say Y here if you wish to use this. Alternatively say M to compile the - driver as a module, which will be called wdt285.o. + driver as a module, which will be called wdt285. This driver does not work on all machines. In particular, early CATS boards have hardware problems that will cause the machine to simply @@ -164,7 +164,7 @@ help Say Y here to include support for the WB977 watchdog included in NetWinder machines. Alternatively say M to compile the driver as - a module, which will be called wdt977.o. + a module, which will be called wdt977. Not sure? It's safe to say N. @@ -179,7 +179,7 @@ This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read - Documentation/modules.txt. The module will be called sa1100_wdt.o. + Documentation/modules.txt. The module will be called sa1100_wdt. config EUROTECH_WDT tristate "Eurotech CPU-1220/1410 Watchdog Timer" @@ -202,7 +202,7 @@ 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 ib700wdt.o. If you want to compile it as a + The module is called ib700wdt. If you want to compile it as a module, say M here and read Documentation/modules.txt. Most people will say N. @@ -225,7 +225,7 @@ If you want to compile this as a module, say M and read . The module will be called - i810-tco.o. + i810-tco. config MIXCOMWD tristate "Mixcom Watchdog" @@ -238,7 +238,7 @@ 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 mixcomwd.o. If you want to compile it as a + The module is called mixcomwd. If you want to compile it as a module, say M here and read . Most people will say N. @@ -249,7 +249,7 @@ Enable the built-in watchdog timer support on the National Semiconductor SCx200 processors. - If compiled as a module, it will be called scx200_watchdog.o. + If compiled as a module, it will be called scx200_watchdog. config 60XX_WDT tristate "SBC-60XX Watchdog Timer" @@ -263,7 +263,7 @@ you can probably make this driver work with your card as well. You can compile this driver directly into the kernel, or use - it as a module. The module will be called sbc60xxwdt.o. + it as a module. The module will be called sbc60xxwdt. config W83877F_WDT tristate "W83877F (EMACS) Watchdog Timer" @@ -277,7 +277,7 @@ 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 mixcomwd.o. If you want to compile it as a + The module is called mixcomwd. If you want to compile it as a module, say M here and read . Most people will say N. @@ -293,7 +293,7 @@ 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 machzwd.o. If you want to compile it as a + The module is called machzwd. If you want to compile it as a module, say M here and read . config W83877F_WDT @@ -303,17 +303,55 @@ config SC520_WDT tristate "AMD Elan SC520 processor Watchdog" depends on WATCHDOG + help + This is the driver for the hardware watchdog built in to the + AMD "Elan" SC520 microcomputer commonly used in embedded systems. + This watchdog simply watches your kernel to make sure it doesn't + freeze, and if it does, it reboots your computer after a certain + amount of time. + + You can compile this driver directly into the kernel, or use + it as a module. The module will be called sc520_wdt.o. config ALIM7101_WDT tristate "ALi M7101 PMU Computer Watchdog" depends on WATCHDOG + help + This is the driver for the hardware watchdog on the ALi M7101 PMU + as used in the x86 Cobalt servers. + + 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 alim7101_wdt.o. If you want to compile it as a + module, say M here and read Documentation/modules.txt. Most + people will say N. config SC1200_WDT tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog" depends on WATCHDOG + help + This is a driver for National Semiconductor PC87307/PC97307 hardware + watchdog cards as found on the SC1200. This watchdog is mainly used + for power management purposes and can be used to power down the device + during inactivity periods (includes interrupt activity monitoring). + + 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 sc1200wdt.o. If you want to compile it as a + module, say M here and read Documentation/modules.txt. Most + people will say N. config WAFER_WDT tristate "ICP Wafer 5823 Single Board Computer Watchdog" depends on WATCHDOG + help + This is a driver for the hardware watchdog on the ICP Wafer 5823 + Single Board Computer (and probably other similar models). + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + If you want to compile it as a module, say M here and read + Documentation/modules.txt. The module will be called + wafer5823wdt.o endmenu diff -Nru a/drivers/eisa/Makefile b/drivers/eisa/Makefile --- a/drivers/eisa/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/eisa/Makefile Sun Feb 9 21:13:32 2003 @@ -2,8 +2,6 @@ obj-$(CONFIG_EISA) += eisa-bus.o -export-objs := eisa-bus.o - clean-files:= devlist.h # Ugly hack to get DEVICE_NAME_SIZE value... diff -Nru a/drivers/fc4/Kconfig b/drivers/fc4/Kconfig --- a/drivers/fc4/Kconfig Sun Feb 9 21:13:31 2003 +++ b/drivers/fc4/Kconfig Sun Feb 9 21:13:31 2003 @@ -33,7 +33,7 @@ that if you have older firmware in the card, you'll need the microcode from the Solaris driver to make it work. - This support is also available as a module called soc.o ( = code + This support is also available as a module called soc ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -48,7 +48,7 @@ Interface Board). You'll probably need the microcode from the Solaris driver to make it work. - This support is also available as a module called socal.o ( = code + This support is also available as a module called socal ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -62,7 +62,7 @@ help If you never bought a disk array made by Sun, go with N. - This support is also available as a module called pluto.o ( = code + This support is also available as a module called pluto ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -76,7 +76,7 @@ common is either A5000 array or internal disks in E[3-6]000 machines. - This support is also available as a module called fcal.o ( = code + This support is also available as a module called fcal ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . If unsure, say N. diff -Nru a/drivers/fc4/Makefile b/drivers/fc4/Makefile --- a/drivers/fc4/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/fc4/Makefile Sun Feb 9 21:13:32 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux Fibre Channel device drivers. # -export-objs := fc_syms.o - fc4-objs := fc.o fc_syms.o obj-$(CONFIG_FC4) += fc4.o diff -Nru a/drivers/fc4/fc.c b/drivers/fc4/fc.c --- a/drivers/fc4/fc.c Sun Feb 9 21:13:32 2003 +++ b/drivers/fc4/fc.c Sun Feb 9 21:13:32 2003 @@ -74,7 +74,7 @@ #endif #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp)) -#define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->host->hostdata[0])) +#define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->device->host->hostdata[0])) #define SC_FCMND(fcmnd) ((Scsi_Cmnd *)((long)fcmnd - (long)&(((Scsi_Cmnd *)0)->SCp))) static int fcp_scsi_queue_it(fc_channel *, Scsi_Cmnd *, fcp_cmnd *, int); @@ -449,7 +449,7 @@ } if (status_byte(rsp_status) == QUEUE_FULL) { - printk ("%s: (%d,%d) Received rsp_status 0x%x\n", fc->name, SCpnt->channel, SCpnt->target, rsp_status); + printk ("%s: (%d,%d) Received rsp_status 0x%x\n", fc->name, SCpnt->device->channel, SCpnt->device->id, rsp_status); } SCpnt->result = (host_status << 16) | (rsp_status & 0xff); @@ -771,10 +771,10 @@ { unsigned long flags; - spin_lock_irqsave(SCpnt->host->host_lock, flags); + spin_lock_irqsave(SCpnt->device->host->host_lock, flags); if (FCP_CMND(SCpnt)->done) FCP_CMND(SCpnt)->done(SCpnt); - spin_unlock_irqrestore(SCpnt->host->host_lock, flags); + spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); } static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare) @@ -799,8 +799,8 @@ fc->cmd_slots[fcmd->token] = fcmd; if (SCpnt->device->tagged_supported) { - if (jiffies - fc->ages[SCpnt->channel * fc->targets + SCpnt->target] > (5 * 60 * HZ)) { - fc->ages[SCpnt->channel * fc->targets + SCpnt->target] = jiffies; + if (jiffies - fc->ages[SCpnt->device->channel * fc->targets + SCpnt->device->id] > (5 * 60 * HZ)) { + fc->ages[SCpnt->device->channel * fc->targets + SCpnt->device->id] = jiffies; fcp_cntl = FCP_CNTL_QTYPE_ORDERED; } else fcp_cntl = FCP_CNTL_QTYPE_SIMPLE; @@ -916,9 +916,9 @@ unsigned long flags; SCpnt->result = DID_ABORT; - spin_lock_irqsave(SCpnt->host->host_lock, flags); + spin_lock_irqsave(SCpnt->device->host->host_lock, flags); fcmd->done(SCpnt); - spin_unlock_irqrestore(SCpnt->host->host_lock, flags); + spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); printk("FC: soft abort\n"); return SUCCESS; } else { @@ -932,7 +932,7 @@ fc_channel *fc = FC_SCMND(SCpnt); fc->rst_pkt->eh_state = SCSI_STATE_FINISHED; - up(fc->rst_pkt->host->eh_action); + up(fc->rst_pkt->device->host->eh_action); } #define FCP_RESET_TIMEOUT (2*HZ) @@ -955,9 +955,7 @@ cmd = fc->scsi_cmd_pool + 0; FCD(("Preparing rst packet\n")) fc->encode_addr (SCpnt, cmd->fcp_addr, fc, fcmd); - fc->rst_pkt->channel = SCpnt->channel; - fc->rst_pkt->target = SCpnt->target; - fc->rst_pkt->lun = 0; + fc->rst_pkt->device = SCpnt->device; fc->rst_pkt->cmd_len = 0; fc->cmd_slots[0] = fcmd; @@ -989,7 +987,7 @@ * Set up the semaphore so we wait for the command to complete. */ - fc->rst_pkt->host->eh_action = &sem; + fc->rst_pkt->device->host->eh_action = &sem; fc->rst_pkt->request->rq_status = RQ_SCSI_BUSY; fc->rst_pkt->done = fcp_scsi_reset_done; @@ -997,7 +995,7 @@ down(&sem); - fc->rst_pkt->host->eh_action = NULL; + fc->rst_pkt->device->host->eh_action = NULL; del_timer(&fc->rst_pkt->eh_timeout); /* diff -Nru a/drivers/hotplug/Kconfig b/drivers/hotplug/Kconfig --- a/drivers/hotplug/Kconfig Sun Feb 9 21:13:31 2003 +++ b/drivers/hotplug/Kconfig Sun Feb 9 21:13:31 2003 @@ -16,7 +16,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called pci_hotplug.o. If you want to compile it + The module will be called pci_hotplug. If you want to compile it as a module, say M here and read . When in doubt, say N. @@ -30,7 +30,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called cpqphp.o. If you want to compile it + The module will be called cpqphp. If you want to compile it as a module, say M here and read . When in doubt, say N. @@ -54,7 +54,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called cpqphp.o. If you want to compile it + The module will be called cpqphp. If you want to compile it as a module, say M here and read . When in doubt, say N. @@ -68,7 +68,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called acpiphp.o. If you want to compile it + The module will be called acpiphp. If you want to compile it as a module, say M here and read . When in doubt, say N. @@ -82,7 +82,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called cpci_hotplug.o. If you want to compile it + The module will be called cpci_hotplug. If you want to compile it as a module, say M here and read . When in doubt, say N. @@ -96,7 +96,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called cpcihp_zt5550.o. If you want to compile it + The module will be called cpcihp_zt5550. If you want to compile it as a module, say M here and read . When in doubt, say N. @@ -111,7 +111,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called cpcihp_generic.o. If you want to compile it + The module will be called cpcihp_generic. If you want to compile it as a module, say M here and read . When in doubt, say N. diff -Nru a/drivers/hotplug/Makefile b/drivers/hotplug/Makefile --- a/drivers/hotplug/Makefile Sun Feb 9 21:13:34 2003 +++ b/drivers/hotplug/Makefile Sun Feb 9 21:13:34 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux kernel pci hotplug controller drivers. # -export-objs := pci_hotplug_core.o pci_hotplug_util.o cpci_hotplug_core.o - obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o @@ -11,8 +9,7 @@ obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o -pci_hotplug-objs := pci_hotplug_core.o \ - pci_hotplug_util.o +pci_hotplug-objs := pci_hotplug_core.o ifdef CONFIG_HOTPLUG_PCI_CPCI pci_hotplug-objs += cpci_hotplug_core.o \ diff -Nru a/drivers/hotplug/acpiphp.h b/drivers/hotplug/acpiphp.h --- a/drivers/hotplug/acpiphp.h Sun Feb 9 21:13:37 2003 +++ b/drivers/hotplug/acpiphp.h Sun Feb 9 21:13:37 2003 @@ -34,9 +34,8 @@ #ifndef _ACPIPHP_H #define _ACPIPHP_H -#include "include/acpi.h" +#include #include "pci_hotplug.h" -#include "acpi_bus.h" #define dbg(format, arg...) \ do { \ diff -Nru a/drivers/hotplug/acpiphp_glue.c b/drivers/hotplug/acpiphp_glue.c --- a/drivers/hotplug/acpiphp_glue.c Sun Feb 9 21:13:30 2003 +++ b/drivers/hotplug/acpiphp_glue.c Sun Feb 9 21:13:30 2003 @@ -578,6 +578,7 @@ bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1); if (!bridge->io_head) { err("out of memory\n"); + kfree(bridge); return; } dbg("16bit I/O range: %04x-%04x\n", @@ -592,6 +593,7 @@ bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1); if (!bridge->io_head) { err("out of memory\n"); + kfree(bridge); return; } dbg("32bit I/O range: %08x-%08x\n", @@ -613,6 +615,7 @@ bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1); if (!bridge->mem_head) { err("out of memory\n"); + kfree(bridge); return; } dbg("32bit Memory range: %08x-%08x\n", @@ -632,6 +635,7 @@ bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1); if (!bridge->p_mem_head) { err("out of memory\n"); + kfree(bridge); return; } dbg("32bit Prefetchable memory range: %08x-%08x\n", @@ -647,6 +651,7 @@ bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1); if (!bridge->p_mem_head) { err("out of memory\n"); + kfree(bridge); return; } dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n", diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c --- a/drivers/hotplug/cpci_hotplug_core.c Sun Feb 9 21:13:31 2003 +++ b/drivers/hotplug/cpci_hotplug_core.c Sun Feb 9 21:13:31 2003 @@ -130,7 +130,7 @@ return -EINVAL; memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info)); info.latch_status = value; - return pci_hp_change_slot_info(hotplug_slot->name, &info); + return pci_hp_change_slot_info(hotplug_slot, &info); } static int @@ -142,7 +142,7 @@ return -EINVAL; memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info)); info.adapter_status = value; - return pci_hp_change_slot_info(hotplug_slot->name, &info); + return pci_hp_change_slot_info(hotplug_slot, &info); } static int diff -Nru a/drivers/hotplug/cpci_hotplug_pci.c b/drivers/hotplug/cpci_hotplug_pci.c --- a/drivers/hotplug/cpci_hotplug_pci.c Sun Feb 9 21:13:33 2003 +++ b/drivers/hotplug/cpci_hotplug_pci.c Sun Feb 9 21:13:33 2003 @@ -341,7 +341,7 @@ /* * Need to explicitly set irq field to 0 so that it'll get assigned - * by the pcibios platform dependant code called by pci_enable_device. + * by the pcibios platform dependent code called by pci_enable_device. */ dev->irq = 0; @@ -395,6 +395,8 @@ /* Scan behind bridge */ n = pci_scan_bridge(bus, dev, max, 2); child = pci_find_bus(max + 1); + if (!child) + return -ENODEV; #ifdef CONFIG_PROC_FS pci_proc_attach_bus(child); #endif diff -Nru a/drivers/hotplug/cpqphp_core.c b/drivers/hotplug/cpqphp_core.c --- a/drivers/hotplug/cpqphp_core.c Sun Feb 9 21:13:28 2003 +++ b/drivers/hotplug/cpqphp_core.c Sun Feb 9 21:13:28 2003 @@ -42,7 +42,7 @@ #include "cpqphp.h" #include "cpqphp_nvram.h" -#include "../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */ +#include "../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependent we are... */ /* Global variables */ @@ -488,6 +488,8 @@ bridgeSlot = 0xFF; PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table(); + if (!PCIIRQRoutingInfoLength) + return -1; len = (PCIIRQRoutingInfoLength->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); diff -Nru a/drivers/hotplug/cpqphp_ctrl.c b/drivers/hotplug/cpqphp_ctrl.c --- a/drivers/hotplug/cpqphp_ctrl.c Sun Feb 9 21:13:30 2003 +++ b/drivers/hotplug/cpqphp_ctrl.c Sun Feb 9 21:13:30 2003 @@ -188,6 +188,8 @@ rc++; p_slot = find_slot(ctrl, hp_slot + (readb(ctrl->hpc_reg + SLOT_MASK) >> 4)); + if (!p_slot) + return 0; // If the switch closed, must be a button // If not in button mode, nevermind @@ -1765,19 +1767,17 @@ static int update_slot_info (struct controller *ctrl, struct slot *slot) { struct hotplug_slot_info *info; - char buffer[SLOT_NAME_SIZE]; int result; info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL); if (!info) return -ENOMEM; - make_slot_name (&buffer[0], SLOT_NAME_SIZE, slot); info->power_status = get_slot_enabled(ctrl, slot); info->attention_status = cpq_get_attention_status(ctrl, slot); info->latch_status = cpq_get_latch_status(ctrl, slot); info->adapter_status = get_presence_status(ctrl, slot); - result = pci_hp_change_slot_info(buffer, info); + result = pci_hp_change_slot_info(slot->hotplug_slot, info); kfree (info); return result; } @@ -1799,8 +1799,12 @@ hp_slot = ctrl->event_queue[loop].hp_slot; func = cpqhp_slot_find(ctrl->bus, (hp_slot + ctrl->slot_device_offset), 0); + if (!func) + return; p_slot = find_slot(ctrl, hp_slot + ctrl->slot_device_offset); + if (!p_slot) + return; dbg("hp_slot %d, func %p, p_slot %p\n", hp_slot, func, p_slot); @@ -2511,8 +2515,14 @@ // Setup the IO, memory, and prefetchable windows io_node = get_max_resource(&(resources->io_head), 0x1000); + if (!io_node) + return -ENOMEM; mem_node = get_max_resource(&(resources->mem_head), 0x100000); + if (!mem_node) + return -ENOMEM; p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000); + if (!p_mem_node) + return -ENOMEM; dbg("Setup the IO, memory, and prefetchable windows\n"); dbg("io_node\n"); dbg("(base, len, next) (%x, %x, %p)\n", io_node->base, io_node->length, io_node->next); diff -Nru a/drivers/hotplug/cpqphp_nvram.c b/drivers/hotplug/cpqphp_nvram.c --- a/drivers/hotplug/cpqphp_nvram.c Sun Feb 9 21:13:35 2003 +++ b/drivers/hotplug/cpqphp_nvram.c Sun Feb 9 21:13:35 2003 @@ -473,7 +473,7 @@ p_byte += 3; if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + return 2; bus = p_ev_ctrl->bus; device = p_ev_ctrl->device; @@ -490,20 +490,20 @@ p_byte += 4; if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + return 2; // Skip forward to the next entry p_byte += (nummem + numpmem + numio + numbus) * 8; if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + return 2; p_ev_ctrl = (struct ev_hrt_ctrl *) p_byte; p_byte += 3; if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + return 2; bus = p_ev_ctrl->bus; device = p_ev_ctrl->device; @@ -518,7 +518,7 @@ p_byte += 4; if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + return 2; while (nummem--) { mem_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); @@ -530,15 +530,19 @@ dbg("mem base = %8.8x\n",mem_node->base); p_byte += 4; - if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { + kfree(mem_node); + return 2; + } mem_node->length = *(u32*)p_byte; dbg("mem length = %8.8x\n",mem_node->length); p_byte += 4; - if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { + kfree(mem_node); + return 2; + } mem_node->next = ctrl->mem_head; ctrl->mem_head = mem_node; @@ -554,15 +558,19 @@ dbg("pre-mem base = %8.8x\n",p_mem_node->base); p_byte += 4; - if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { + kfree(p_mem_node); + return 2; + } p_mem_node->length = *(u32*)p_byte; dbg("pre-mem length = %8.8x\n",p_mem_node->length); p_byte += 4; - if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { + kfree(p_mem_node); + return 2; + } p_mem_node->next = ctrl->p_mem_head; ctrl->p_mem_head = p_mem_node; @@ -578,15 +586,19 @@ dbg("io base = %8.8x\n",io_node->base); p_byte += 4; - if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { + kfree(io_node); + return 2; + } io_node->length = *(u32*)p_byte; dbg("io length = %8.8x\n",io_node->length); p_byte += 4; - if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { + kfree(io_node); + return 2; + } io_node->next = ctrl->io_head; ctrl->io_head = io_node; @@ -601,15 +613,18 @@ bus_node->base = *(u32*)p_byte; p_byte += 4; - if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { + kfree(bus_node); + return 2; + } bus_node->length = *(u32*)p_byte; p_byte += 4; - - if (p_byte > ((u8*)p_EV_header + evbuffer_length)) - return(2); + if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { + kfree(bus_node); + return 2; + } bus_node->next = ctrl->bus_head; ctrl->bus_head = bus_node; @@ -623,13 +638,11 @@ rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head)); rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head)); - if (rc) { + if (rc) return(rc); - } } else { - if ((evbuffer[0] != 0) && (!ctrl->push_flag)) { - return(1); - } + if ((evbuffer[0] != 0) && (!ctrl->push_flag)) + return 1; } return 0; diff -Nru a/drivers/hotplug/cpqphp_pci.c b/drivers/hotplug/cpqphp_pci.c --- a/drivers/hotplug/cpqphp_pci.c Sun Feb 9 21:13:36 2003 +++ b/drivers/hotplug/cpqphp_pci.c Sun Feb 9 21:13:36 2003 @@ -36,7 +36,7 @@ #include #include "cpqphp.h" #include "cpqphp_nvram.h" -#include "../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */ +#include "../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependent we are... */ u8 cpqhp_nic_irq; @@ -435,6 +435,8 @@ u8 tbus, tdevice, tslot; PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table(); + if (!PCIIRQRoutingInfoLength) + return -1; len = (PCIIRQRoutingInfoLength->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); @@ -1191,7 +1193,7 @@ if (temp != func->config_space[cloop >> 2]) { dbg("Config space compare failure!!! offset = %x\n", cloop); dbg("bus = %x, device = %x, function = %x\n", func->bus, func->device, func->function); - dbg("temp = %x, config space = %x\n\n", temp, func->config_space[cloop]); + dbg("temp = %x, config space = %x\n\n", temp, func->config_space[cloop >> 2]); return 1; } } diff -Nru a/drivers/hotplug/cpqphp_proc.c b/drivers/hotplug/cpqphp_proc.c --- a/drivers/hotplug/cpqphp_proc.c Sun Feb 9 21:13:36 2003 +++ b/drivers/hotplug/cpqphp_proc.c Sun Feb 9 21:13:36 2003 @@ -113,6 +113,8 @@ while (slot) { new_slot = cpqhp_slot_find(slot->bus, slot->device, 0); + if (!new_slot) + break; out += sprintf(out, "assigned resources: memory\n"); index = 11; res = new_slot->mem_head; diff -Nru a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c --- a/drivers/hotplug/ibmphp_core.c Sun Feb 9 21:13:37 2003 +++ b/drivers/hotplug/ibmphp_core.c Sun Feb 9 21:13:37 2003 @@ -686,7 +686,6 @@ int ibmphp_update_slot_info (struct slot *slot_cur) { struct hotplug_slot_info *info; - char buffer[30]; int rc; u8 bus_speed; u8 mode; @@ -697,7 +696,6 @@ return -ENOMEM; } - strncpy (buffer, slot_cur->hotplug_slot->name, 30); info->power_status = SLOT_PWRGD (slot_cur->status); info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status); info->latch_status = SLOT_LATCH (slot_cur->status); @@ -735,7 +733,7 @@ info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed; // To do: bus_names - rc = pci_hp_change_slot_info (buffer, info); + rc = pci_hp_change_slot_info (slot_cur->hotplug_slot, info); kfree (info); return rc; } @@ -1057,6 +1055,8 @@ if (func->dev == NULL) { dev0.bus = ibmphp_find_bus (func->busno); + if (!dev0.bus) + return 0; dev0.devfn = ((func->device << 3) + (func->function & 0x7)); dev0.sysdata = dev0.bus->sysdata; @@ -1097,6 +1097,8 @@ continue; } tmp_slot = ibmphp_get_slot_from_physical_num (i); + if (!tmp_slot) + return 0; rc = slot_update (&tmp_slot); if (rc) return 0; @@ -1219,6 +1221,8 @@ for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) { tmp_slot = ibmphp_get_slot_from_physical_num (i); + if (!tmp_slot) + return -ENODEV; if ((SLOT_PWRGD (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status))) count++; } diff -Nru a/drivers/hotplug/ibmphp_ebda.c b/drivers/hotplug/ibmphp_ebda.c --- a/drivers/hotplug/ibmphp_ebda.c Sun Feb 9 21:13:29 2003 +++ b/drivers/hotplug/ibmphp_ebda.c Sun Feb 9 21:13:29 2003 @@ -65,24 +65,11 @@ static LIST_HEAD (opt_lo_head); static void *io_mem; -char *chassis_str, *rxe_str, *str; - /* Local functions */ static int ebda_rsrc_controller (void); static int ebda_rsrc_rsrc (void); static int ebda_rio_table (void); -static struct slot *alloc_ibm_slot (void) -{ - struct slot *slot; - - slot = kmalloc (sizeof (struct slot), GFP_KERNEL); - if (!slot) - return NULL; - memset (slot, 0, sizeof (*slot)); - return slot; -} - static struct ebda_hpc_list * __init alloc_ebda_hpc_list (void) { struct ebda_hpc_list *list; @@ -591,32 +578,6 @@ return 0; } -static char *convert_2digits_to_char (int var) -{ - int bit; - char *str1; - - str = (char *) kmalloc (3, GFP_KERNEL); - memset (str, 0, 3); - str1 = (char *) kmalloc (2, GFP_KERNEL); - memset (str, 0, 3); - bit = (int)(var / 10); - switch (bit) { - case 0: - //one digit number - *str = (char)(var + 48); - return str; - default: - //2 digits number - *str1 = (char)(bit + 48); - strncpy (str, str1, 1); - memset (str1, 0, 3); - *str1 = (char)((var % 10) + 48); - strcat (str, str1); - return str; - } - return NULL; -} /* Since we don't know the max slot number per each chassis, hence go * through the list of all chassis to find out the range @@ -701,7 +662,7 @@ { struct opt_rio *opt_vg_ptr = NULL; struct opt_rio_lo *opt_lo_ptr = NULL; - char *ptr_chassis_num, *ptr_rxe_num, *ptr_slot_num; + static char str[30]; int which = 0; /* rxe = 1, chassis = 0 */ u8 number = 1; /* either chassis or rxe # */ u8 first_slot = 1; @@ -715,19 +676,7 @@ slot_num = slot_cur->number; - chassis_str = (char *) kmalloc (30, GFP_KERNEL); - memset (chassis_str, 0, 30); - rxe_str = (char *) kmalloc (30, GFP_KERNEL); - memset (rxe_str, 0, 30); - ptr_chassis_num = (char *) kmalloc (3, GFP_KERNEL); - memset (ptr_chassis_num, 0, 3); - ptr_rxe_num = (char *) kmalloc (3, GFP_KERNEL); - memset (ptr_rxe_num, 0, 3); - ptr_slot_num = (char *) kmalloc (3, GFP_KERNEL); - memset (ptr_slot_num, 0, 3); - - strcpy (chassis_str, "chassis"); - strcpy (rxe_str, "rxe"); + memset (str, 0, sizeof(str)); if (rio_table_ptr) { if (rio_table_ptr->ver_num == 3) { @@ -772,31 +721,10 @@ } } - switch (which) { - case 0: - /* Chassis */ - *ptr_chassis_num = (char)(number + 48); - strcat (chassis_str, ptr_chassis_num); - kfree (ptr_chassis_num); - strcat (chassis_str, "slot"); - ptr_slot_num = convert_2digits_to_char (slot_num - first_slot + 1); - strcat (chassis_str, ptr_slot_num); - kfree (ptr_slot_num); - return chassis_str; - break; - case 1: - /* RXE */ - *ptr_rxe_num = (char)(number + 48); - strcat (rxe_str, ptr_rxe_num); - kfree (ptr_rxe_num); - strcat (rxe_str, "slot"); - ptr_slot_num = convert_2digits_to_char (slot_num - first_slot + 1); - strcat (rxe_str, ptr_slot_num); - kfree (ptr_slot_num); - return rxe_str; - break; - } - return NULL; + sprintf(str, "%s%dslot%d", + which == 0 ? "chassis" : "rxe", + number, slot_num - first_slot + 1); + return str; } static struct pci_driver ibmphp_driver; @@ -818,8 +746,7 @@ struct ebda_hpc_slot *slot_ptr; struct bus_info *bus_info_ptr1, *bus_info_ptr2; int rc; - int retval; - struct slot *slot_cur; + struct slot *tmp_slot; struct list_head *list; addr = hpc_list_ptr->phys_addr; @@ -844,8 +771,8 @@ /* init hpc structure */ hpc_ptr = alloc_ebda_hpc (slot_num, bus_num); if (!hpc_ptr ) { - iounmap (io_mem); - return -ENOMEM; + rc = -ENOMEM; + goto error_no_hpc; } hpc_ptr->ctlr_id = ctlr_id; hpc_ptr->ctlr_relative_id = ctlr; @@ -871,8 +798,8 @@ if (!bus_info_ptr2) { bus_info_ptr1 = (struct bus_info *) kmalloc (sizeof (struct bus_info), GFP_KERNEL); if (!bus_info_ptr1) { - iounmap (io_mem); - return -ENOMEM; + rc = -ENOMEM; + goto error_no_hp_slot; } memset (bus_info_ptr1, 0, sizeof (struct bus_info)); bus_info_ptr1->slot_min = slot_ptr->slot_num; @@ -932,16 +859,20 @@ hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1); hpc_ptr->irq = readb (io_mem + addr + 2); addr += 3; - debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n", hpc_ptr->u.pci_ctlr.bus, hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq); + debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n", + hpc_ptr->u.pci_ctlr.bus, + hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq); break; case 0: hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr); hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2); - retval = check_region (hpc_ptr->u.isa_ctlr.io_start, (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1)); - if (retval) - return -ENODEV; - request_region (hpc_ptr->u.isa_ctlr.io_start, (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1), "ibmphp"); + if (!request_region (hpc_ptr->u.isa_ctlr.io_start, + (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1), + "ibmphp")) { + rc = -ENODEV; + goto error_no_hp_slot; + } hpc_ptr->irq = readb (io_mem + addr + 4); addr += 5; break; @@ -954,8 +885,8 @@ addr += 6; break; default: - iounmap (io_mem); - return -ENODEV; + rc = -ENODEV; + goto error_no_hp_slot; } //reorganize chassis' linked list @@ -971,79 +902,71 @@ hp_slot_ptr = (struct hotplug_slot *) kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL); if (!hp_slot_ptr) { - iounmap (io_mem); - return -ENOMEM; + rc = -ENOMEM; + goto error_no_hp_slot; } memset (hp_slot_ptr, 0, sizeof (struct hotplug_slot)); hp_slot_ptr->info = (struct hotplug_slot_info *) kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL); if (!hp_slot_ptr->info) { - iounmap (io_mem); - kfree (hp_slot_ptr); - return -ENOMEM; + rc = -ENOMEM; + goto error_no_hp_info; } memset (hp_slot_ptr->info, 0, sizeof (struct hotplug_slot_info)); hp_slot_ptr->name = (char *) kmalloc (30, GFP_KERNEL); if (!hp_slot_ptr->name) { - iounmap (io_mem); - kfree (hp_slot_ptr->info); - kfree (hp_slot_ptr); - return -ENOMEM; + rc = -ENOMEM; + goto error_no_hp_name; } - hp_slot_ptr->private = alloc_ibm_slot (); - if (!hp_slot_ptr->private) { - iounmap (io_mem); - kfree (hp_slot_ptr->name); - kfree (hp_slot_ptr->info); - kfree (hp_slot_ptr); - return -ENOMEM; + tmp_slot = kmalloc (sizeof (struct slot), GFP_KERNEL); + if (!tmp_slot) { + rc = -ENOMEM; + goto error_no_slot; } + memset (tmp_slot, 0, sizeof (*tmp_slot)); - ((struct slot *)hp_slot_ptr->private)->flag = TRUE; + tmp_slot->flag = TRUE; - ((struct slot *) hp_slot_ptr->private)->capabilities = hpc_ptr->slots[index].slot_cap; + tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap; if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX) - ((struct slot *) hp_slot_ptr->private)->supported_speed = 3; + tmp_slot->supported_speed = 3; else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_100_MAX) == EBDA_SLOT_100_MAX) - ((struct slot *) hp_slot_ptr->private)->supported_speed = 2; + tmp_slot->supported_speed = 2; else if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_66_MAX) == EBDA_SLOT_66_MAX) - ((struct slot *) hp_slot_ptr->private)->supported_speed = 1; + tmp_slot->supported_speed = 1; if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_PCIX_CAP) == EBDA_SLOT_PCIX_CAP) - ((struct slot *) hp_slot_ptr->private)->supported_bus_mode = 1; + tmp_slot->supported_bus_mode = 1; else - ((struct slot *) hp_slot_ptr->private)->supported_bus_mode = 0; + tmp_slot->supported_bus_mode = 0; - ((struct slot *) hp_slot_ptr->private)->bus = hpc_ptr->slots[index].slot_bus_num; + tmp_slot->bus = hpc_ptr->slots[index].slot_bus_num; bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num); if (!bus_info_ptr1) { - iounmap (io_mem); - return -ENODEV; + rc = -ENODEV; + goto error; } - ((struct slot *) hp_slot_ptr->private)->bus_on = bus_info_ptr1; + tmp_slot->bus_on = bus_info_ptr1; bus_info_ptr1 = NULL; - ((struct slot *) hp_slot_ptr->private)->ctrl = hpc_ptr; + tmp_slot->ctrl = hpc_ptr; + tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index; + tmp_slot->number = hpc_ptr->slots[index].slot_num; + tmp_slot->hotplug_slot = hp_slot_ptr; + + hp_slot_ptr->private = tmp_slot; - ((struct slot *) hp_slot_ptr->private)->ctlr_index = hpc_ptr->slots[index].ctl_index; - ((struct slot *) hp_slot_ptr->private)->number = hpc_ptr->slots[index].slot_num; - - ((struct slot *) hp_slot_ptr->private)->hotplug_slot = hp_slot_ptr; rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr); - if (rc) { - iounmap (io_mem); - return rc; - } + if (rc) + goto error; rc = ibmphp_init_devno ((struct slot **) &hp_slot_ptr->private); - if (rc) { - iounmap (io_mem); - return rc; - } + if (rc) + goto error; hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops; // end of registering ibm slot with hotplug core @@ -1057,19 +980,29 @@ } /* each hpc */ list_for_each (list, &ibmphp_slot_head) { - slot_cur = list_entry (list, struct slot, ibm_slot_list); + tmp_slot = list_entry (list, struct slot, ibm_slot_list); - snprintf (slot_cur->hotplug_slot->name, 30, "%s", create_file_name (slot_cur)); - if (chassis_str) - kfree (chassis_str); - if (rxe_str) - kfree (rxe_str); - pci_hp_register (slot_cur->hotplug_slot); + snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot)); + pci_hp_register (tmp_slot->hotplug_slot); } print_ebda_hpc (); print_ibm_slot (); return 0; + +error: + kfree (hp_slot_ptr->private); +error_no_slot: + kfree (hp_slot_ptr->name); +error_no_hp_name: + kfree (hp_slot_ptr->info); +error_no_hp_info: + kfree (hp_slot_ptr); +error_no_hp_slot: + free_ebda_hpc (hpc_ptr); +error_no_hpc: + iounmap (io_mem); + return rc; } /* diff -Nru a/drivers/hotplug/ibmphp_pci.c b/drivers/hotplug/ibmphp_pci.c --- a/drivers/hotplug/ibmphp_pci.c Sun Feb 9 21:13:28 2003 +++ b/drivers/hotplug/ibmphp_pci.c Sun Feb 9 21:13:28 2003 @@ -951,6 +951,7 @@ if (rc) { if (rc == -ENOMEM) { ibmphp_remove_bus (bus, func->busno); + kfree (amount_needed); return rc; } retval = rc; @@ -1621,23 +1622,23 @@ } for (i = 0; i < count; i++) { - if (cur_func->io[count]) { - debug ("io[%d] exists \n", count); + if (cur_func->io[i]) { + debug ("io[%d] exists \n", i); if (the_end > 0) - ibmphp_remove_resource (cur_func->io[count]); - cur_func->io[count] = NULL; + ibmphp_remove_resource (cur_func->io[i]); + cur_func->io[i] = NULL; } - if (cur_func->mem[count]) { - debug ("mem[%d] exists \n", count); + if (cur_func->mem[i]) { + debug ("mem[%d] exists \n", i); if (the_end > 0) - ibmphp_remove_resource (cur_func->mem[count]); - cur_func->mem[count] = NULL; + ibmphp_remove_resource (cur_func->mem[i]); + cur_func->mem[i] = NULL; } - if (cur_func->pfmem[count]) { - debug ("pfmem[%d] exists \n", count); + if (cur_func->pfmem[i]) { + debug ("pfmem[%d] exists \n", i); if (the_end > 0) - ibmphp_remove_resource (cur_func->pfmem[count]); - cur_func->pfmem[count] = NULL; + ibmphp_remove_resource (cur_func->pfmem[i]); + cur_func->pfmem[i] = NULL; } } diff -Nru a/drivers/hotplug/pci_hotplug.h b/drivers/hotplug/pci_hotplug.h --- a/drivers/hotplug/pci_hotplug.h Sun Feb 9 21:13:31 2003 +++ b/drivers/hotplug/pci_hotplug.h Sun Feb 9 21:13:31 2003 @@ -46,8 +46,11 @@ }; struct hotplug_slot; -struct hotplug_slot_core; - +struct hotplug_slot_attribute { + struct attribute attr; + ssize_t (*show)(struct hotplug_slot *, char *); + ssize_t (*store)(struct hotplug_slot *, const char *, size_t); +}; /** * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use * @owner: The module owner of this structure @@ -131,45 +134,13 @@ /* Variables below this are for use only by the hotplug pci core. */ struct list_head slot_list; - struct hotplug_slot_core *core_priv; + struct kobject kobj; }; extern int pci_hp_register (struct hotplug_slot *slot); extern int pci_hp_deregister (struct hotplug_slot *slot); -extern int pci_hp_change_slot_info (const char *name, +extern int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info); - -struct pci_dev_wrapped { - struct pci_dev *dev; - void *data; -}; - -struct pci_bus_wrapped { - struct pci_bus *bus; - void *data; -}; - -struct pci_visit { - int (* pre_visit_pci_bus) (struct pci_bus_wrapped *, - struct pci_dev_wrapped *); - int (* post_visit_pci_bus) (struct pci_bus_wrapped *, - struct pci_dev_wrapped *); - - int (* pre_visit_pci_dev) (struct pci_dev_wrapped *, - struct pci_bus_wrapped *); - int (* visit_pci_dev) (struct pci_dev_wrapped *, - struct pci_bus_wrapped *); - int (* post_visit_pci_dev) (struct pci_dev_wrapped *, - struct pci_bus_wrapped *); -}; - -extern int pci_visit_dev (struct pci_visit *fn, - struct pci_dev_wrapped *wrapped_dev, - struct pci_bus_wrapped *wrapped_parent); - -int pci_is_dev_in_use(struct pci_dev *dev); - -int pci_remove_device_safe(struct pci_dev *dev); #endif diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c --- a/drivers/hotplug/pci_hotplug_core.c Sun Feb 9 21:13:35 2003 +++ b/drivers/hotplug/pci_hotplug_core.c Sun Feb 9 21:13:35 2003 @@ -39,9 +39,9 @@ #include #include #include -#include -#include #include +#include +#include #include "pci_hotplug.h" @@ -67,29 +67,43 @@ ////////////////////////////////////////////////////////////////// -/* Random magic number */ -#define PCIHPFS_MAGIC 0x52454541 +static spinlock_t list_lock; + +static LIST_HEAD(pci_hotplug_slot_list); -struct hotplug_slot_core { - struct dentry *dir_dentry; - struct dentry *power_dentry; - struct dentry *attention_dentry; - struct dentry *latch_dentry; - struct dentry *adapter_dentry; - struct dentry *test_dentry; - struct dentry *max_bus_speed_dentry; - struct dentry *cur_bus_speed_dentry; +static struct subsystem hotplug_slots_subsys; + +static ssize_t hotplug_slot_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct hotplug_slot *slot=container_of(kobj, + struct hotplug_slot,kobj); + struct hotplug_slot_attribute *attribute = + container_of(attr, struct hotplug_slot_attribute, attr); + return attribute->show ? attribute->show(slot, buf) : 0; +} + +static ssize_t hotplug_slot_attr_store(struct kobject *kobj, + struct attribute *attr, const char *buf, size_t len) +{ + struct hotplug_slot *slot=container_of(kobj, + struct hotplug_slot,kobj); + struct hotplug_slot_attribute *attribute = + container_of(attr, struct hotplug_slot_attribute, attr); + return attribute->store ? attribute->store(slot, buf, len) : 0; +} + +static struct sysfs_ops hotplug_slot_sysfs_ops = { + .show = hotplug_slot_attr_show, + .store = hotplug_slot_attr_store, }; -static struct super_operations pcihpfs_ops; -static struct file_operations default_file_operations; -static struct inode_operations pcihpfs_dir_inode_operations; -static struct vfsmount *pcihpfs_mount; /* one of the mounts of our fs for reference counting */ -static int pcihpfs_mount_count; /* times we have mounted our fs */ -static spinlock_t mount_lock; /* protects our mount_count */ -static spinlock_t list_lock; +static struct kobj_type hotplug_slot_ktype = { + .sysfs_ops = &hotplug_slot_sysfs_ops +}; + +static decl_subsys(hotplug_slots, &hotplug_slot_ktype); -static LIST_HEAD(pci_hotplug_slot_list); /* these strings match up with the values in pci_bus_speed */ static char *pci_bus_speed_strings[] = { @@ -115,12 +129,6 @@ "133 MHz PCIX 533", /* 0x13 */ }; -#ifdef CONFIG_PROC_FS -extern struct proc_dir_entry *proc_bus_pci_dir; -static struct proc_dir_entry *slotdir = NULL; -static const char *slotdir_name = "slots"; -#endif - #ifdef CONFIG_HOTPLUG_PCI_CPCI extern int cpci_hotplug_init(int debug); extern void cpci_hotplug_exit(void); @@ -129,438 +137,6 @@ static inline void cpci_hotplug_exit(void) { } #endif -static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, dev_t dev) -{ - struct inode *inode = new_inode(sb); - - if (inode) { - inode->i_mode = mode; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; - inode->i_blksize = PAGE_CACHE_SIZE; - inode->i_blocks = 0; - inode->i_rdev = NODEV; - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; - switch (mode & S_IFMT) { - default: - init_special_inode(inode, mode, dev); - break; - case S_IFREG: - inode->i_fop = &default_file_operations; - break; - case S_IFDIR: - inode->i_op = &pcihpfs_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - - /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; - break; - } - } - return inode; -} - -/* SMP-safe */ -static int pcihpfs_mknod (struct inode *dir, struct dentry *dentry, int mode, dev_t dev) -{ - struct inode *inode = pcihpfs_get_inode(dir->i_sb, mode, dev); - int error = -ENOSPC; - - if (inode) { - d_instantiate(dentry, inode); - dget(dentry); - error = 0; - } - return error; -} - -static int pcihpfs_mkdir (struct inode *dir, struct dentry *dentry, int mode) -{ - return pcihpfs_mknod (dir, dentry, mode | S_IFDIR, 0); -} - -static int pcihpfs_create (struct inode *dir, struct dentry *dentry, int mode) -{ - return pcihpfs_mknod (dir, dentry, mode | S_IFREG, 0); -} - -static inline int pcihpfs_positive (struct dentry *dentry) -{ - return dentry->d_inode && !d_unhashed(dentry); -} - -static int pcihpfs_empty (struct dentry *dentry) -{ - struct list_head *list; - - spin_lock(&dcache_lock); - - list_for_each(list, &dentry->d_subdirs) { - struct dentry *de = list_entry(list, struct dentry, d_child); - if (pcihpfs_positive(de)) { - spin_unlock(&dcache_lock); - return 0; - } - } - - spin_unlock(&dcache_lock); - return 1; -} - -static int pcihpfs_unlink (struct inode *dir, struct dentry *dentry) -{ - int error = -ENOTEMPTY; - - if (pcihpfs_empty(dentry)) { - struct inode *inode = dentry->d_inode; - - lock_kernel(); - inode->i_nlink--; - unlock_kernel(); - dput(dentry); - error = 0; - } - return error; -} - -#define pcihpfs_rmdir pcihpfs_unlink - -/* default file operations */ -static ssize_t default_read_file (struct file *file, char *buf, size_t count, loff_t *ppos) -{ - dbg ("\n"); - return 0; -} - -static ssize_t default_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos) -{ - dbg ("\n"); - return count; -} - -static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) -{ - loff_t retval = -EINVAL; - - lock_kernel(); - switch(orig) { - case 0: - if (offset > 0) { - file->f_pos = offset; - retval = file->f_pos; - } - break; - case 1: - if ((offset + file->f_pos) > 0) { - file->f_pos += offset; - retval = file->f_pos; - } - break; - default: - break; - } - unlock_kernel(); - return retval; -} - -static int default_open (struct inode *inode, struct file *filp) -{ - if (inode->u.generic_ip) - filp->private_data = inode->u.generic_ip; - - return 0; -} - -static struct file_operations default_file_operations = { - .read = default_read_file, - .write = default_write_file, - .open = default_open, - .llseek = default_file_lseek, -}; - -/* file ops for the "power" files */ -static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset); -static ssize_t power_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos); -static struct file_operations power_file_operations = { - .read = power_read_file, - .write = power_write_file, - .open = default_open, - .llseek = default_file_lseek, -}; - -/* file ops for the "attention" files */ -static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset); -static ssize_t attention_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos); -static struct file_operations attention_file_operations = { - .read = attention_read_file, - .write = attention_write_file, - .open = default_open, - .llseek = default_file_lseek, -}; - -/* file ops for the "latch" files */ -static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset); -static struct file_operations latch_file_operations = { - .read = latch_read_file, - .write = default_write_file, - .open = default_open, - .llseek = default_file_lseek, -}; - -/* file ops for the "presence" files */ -static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset); -static struct file_operations presence_file_operations = { - .read = presence_read_file, - .write = default_write_file, - .open = default_open, - .llseek = default_file_lseek, -}; - -/* file ops for the "max bus speed" files */ -static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset); -static struct file_operations max_bus_speed_file_operations = { - .read = max_bus_speed_read_file, - .write = default_write_file, - .open = default_open, - .llseek = default_file_lseek, -}; - -/* file ops for the "current bus speed" files */ -static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset); -static struct file_operations cur_bus_speed_file_operations = { - .read = cur_bus_speed_read_file, - .write = default_write_file, - .open = default_open, - .llseek = default_file_lseek, -}; - -/* file ops for the "test" files */ -static ssize_t test_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos); -static struct file_operations test_file_operations = { - .read = default_read_file, - .write = test_write_file, - .open = default_open, - .llseek = default_file_lseek, -}; - -static struct inode_operations pcihpfs_dir_inode_operations = { - .create = pcihpfs_create, - .lookup = simple_lookup, - .unlink = pcihpfs_unlink, - .mkdir = pcihpfs_mkdir, - .rmdir = pcihpfs_rmdir, - .mknod = pcihpfs_mknod, -}; - -static struct super_operations pcihpfs_ops = { - .statfs = simple_statfs, - .drop_inode = generic_delete_inode, -}; - -static int pcihpfs_fill_super(struct super_block *sb, void *data, int silent) -{ - struct inode *inode; - struct dentry *root; - - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; - sb->s_magic = PCIHPFS_MAGIC; - sb->s_op = &pcihpfs_ops; - inode = pcihpfs_get_inode(sb, S_IFDIR | 0755, 0); - - if (!inode) { - dbg("%s: could not get inode!\n",__FUNCTION__); - return -ENOMEM; - } - - root = d_alloc_root(inode); - if (!root) { - dbg("%s: could not get root dentry!\n",__FUNCTION__); - iput(inode); - return -ENOMEM; - } - sb->s_root = root; - return 0; -} - -static struct super_block *pcihpfs_get_sb(struct file_system_type *fs_type, - int flags, char *dev_name, void *data) -{ - return get_sb_single(fs_type, flags, data, pcihpfs_fill_super); -} - -static struct file_system_type pcihpfs_type = { - .owner = THIS_MODULE, - .name = "pcihpfs", - .get_sb = pcihpfs_get_sb, - .kill_sb = kill_litter_super, -}; - -static int get_mount (void) -{ - struct vfsmount *mnt; - - spin_lock (&mount_lock); - if (pcihpfs_mount) { - mntget(pcihpfs_mount); - ++pcihpfs_mount_count; - spin_unlock (&mount_lock); - goto go_ahead; - } - - spin_unlock (&mount_lock); - mnt = kern_mount (&pcihpfs_type); - if (IS_ERR(mnt)) { - err ("could not mount the fs...erroring out!\n"); - return -ENODEV; - } - spin_lock (&mount_lock); - if (!pcihpfs_mount) { - pcihpfs_mount = mnt; - ++pcihpfs_mount_count; - spin_unlock (&mount_lock); - goto go_ahead; - } - mntget(pcihpfs_mount); - ++pcihpfs_mount_count; - spin_unlock (&mount_lock); - mntput(mnt); - -go_ahead: - dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count); - return 0; -} - -static void remove_mount (void) -{ - struct vfsmount *mnt; - - spin_lock (&mount_lock); - mnt = pcihpfs_mount; - --pcihpfs_mount_count; - if (!pcihpfs_mount_count) - pcihpfs_mount = NULL; - - spin_unlock (&mount_lock); - mntput(mnt); - dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count); -} - - -/** - * pcihpfs_create_by_name - create a file, given a name - * @name: name of file - * @mode: type of file - * @parent: dentry of directory to create it in - * @dentry: resulting dentry of file - * - * There is a bit of overhead in creating a file - basically, we - * have to hash the name of the file, then look it up. This will - * prevent files of the same name. - * We then call the proper vfs_ function to take care of all the - * file creation details. - * This function handles both regular files and directories. - */ -static int pcihpfs_create_by_name (const char *name, mode_t mode, - struct dentry *parent, struct dentry **dentry) -{ - struct dentry *d = NULL; - struct qstr qstr; - int error; - - /* If the parent is not specified, we create it in the root. - * We need the root dentry to do this, which is in the super - * block. A pointer to that is in the struct vfsmount that we - * have around. - */ - if (!parent ) { - if (pcihpfs_mount && pcihpfs_mount->mnt_sb) { - parent = pcihpfs_mount->mnt_sb->s_root; - } - } - - if (!parent) { - dbg("Ah! can not find a parent!\n"); - return -EINVAL; - } - - *dentry = NULL; - qstr.name = name; - qstr.len = strlen(name); - qstr.hash = full_name_hash(name,qstr.len); - - parent = dget(parent); - - down(&parent->d_inode->i_sem); - - d = lookup_hash(&qstr,parent); - - error = PTR_ERR(d); - if (!IS_ERR(d)) { - switch(mode & S_IFMT) { - case 0: - case S_IFREG: - error = vfs_create(parent->d_inode,d,mode); - break; - case S_IFDIR: - error = vfs_mkdir(parent->d_inode,d,mode); - break; - default: - err("cannot create special files\n"); - } - *dentry = d; - } - up(&parent->d_inode->i_sem); - - dput(parent); - return error; -} - -static struct dentry *fs_create_file (const char *name, mode_t mode, - struct dentry *parent, void *data, - struct file_operations *fops) -{ - struct dentry *dentry; - int error; - - dbg("creating file '%s'\n",name); - - error = pcihpfs_create_by_name(name,mode,parent,&dentry); - if (error) { - dentry = NULL; - } else { - if (dentry->d_inode) { - if (data) - dentry->d_inode->u.generic_ip = data; - if (fops) - dentry->d_inode->i_fop = fops; - } - } - - return dentry; -} - -static void fs_remove_file (struct dentry *dentry) -{ - struct dentry *parent = dentry->d_parent; - - if (!parent || !parent->d_inode) - return; - - down(&parent->d_inode->i_sem); - if (pcihpfs_positive(dentry)) { - if (dentry->d_inode) { - if (S_ISDIR(dentry->d_inode->i_mode)) - vfs_rmdir(parent->d_inode,dentry); - else - vfs_unlink(parent->d_inode,dentry); - } - - dput(dentry); - } - up(&parent->d_inode->i_sem); -} - /* Weee, fun with macros... */ #define GET_STATUS(name,type) \ static int get_##name (struct hotplug_slot *slot, type *value) \ @@ -584,80 +160,27 @@ GET_STATUS(max_bus_speed, enum pci_bus_speed) GET_STATUS(cur_bus_speed, enum pci_bus_speed) -static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset) +static ssize_t power_read_file (struct hotplug_slot *slot, char *buf) { - struct hotplug_slot *slot = file->private_data; - unsigned char *page; int retval; - int len; u8 value; - dbg(" count = %d, offset = %lld\n", count, *offset); - - if (*offset < 0) - return -EINVAL; - if (count == 0 || count > 16384) - return 0; - if (*offset != 0) - return 0; - - if (slot == NULL) { - dbg("slot == NULL???\n"); - return -ENODEV; - } - - page = (unsigned char *)__get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - retval = get_power_status (slot, &value); if (retval) goto exit; - len = sprintf (page, "%d\n", value); - - if (copy_to_user (buf, page, len)) { - retval = -EFAULT; - goto exit; - } - *offset += len; - retval = len; - + retval = sprintf (buf, "%d\n", value); exit: - free_page((unsigned long)page); return retval; } -static ssize_t power_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset) +static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf, + size_t count) { - struct hotplug_slot *slot = file->private_data; - char *buff; unsigned long lpower; u8 power; int retval = 0; - if (*offset < 0) - return -EINVAL; - if (count == 0 || count > 16384) - return 0; - if (*offset != 0) - return 0; - - if (slot == NULL) { - dbg("slot == NULL???\n"); - return -ENODEV; - } - - buff = kmalloc (count + 1, GFP_KERNEL); - if (!buff) - return -ENOMEM; - memset (buff, 0x00, count + 1); - - if (copy_from_user ((void *)buff, (void *)ubuff, count)) { - retval = -EFAULT; - goto exit; - } - - lpower = simple_strtoul (buff, NULL, 10); + lpower = simple_strtoul (buf, NULL, 10); power = (u8)(lpower & 0xff); dbg ("power = %d\n", power); @@ -683,87 +206,39 @@ module_put(slot->ops->owner); exit: - kfree (buff); - if (retval) return retval; return count; } -static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset) +static struct hotplug_slot_attribute hotplug_slot_attr_power = { + .attr = {.name = "power", .mode = S_IFREG | S_IRUGO | S_IWUSR}, + .show = power_read_file, + .store = power_write_file +}; + +static ssize_t attention_read_file (struct hotplug_slot *slot, char *buf) { - struct hotplug_slot *slot = file->private_data; - unsigned char *page; int retval; - int len; u8 value; - dbg("count = %d, offset = %lld\n", count, *offset); - - if (*offset < 0) - return -EINVAL; - if (count <= 0) - return 0; - if (*offset != 0) - return 0; - - if (slot == NULL) { - dbg("slot == NULL???\n"); - return -ENODEV; - } - - page = (unsigned char *)__get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - retval = get_attention_status (slot, &value); if (retval) goto exit; - len = sprintf (page, "%d\n", value); - - if (copy_to_user (buf, page, len)) { - retval = -EFAULT; - goto exit; - } - *offset += len; - retval = len; + retval = sprintf (buf, "%d\n", value); exit: - free_page((unsigned long)page); return retval; } -static ssize_t attention_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset) +static ssize_t attention_write_file (struct hotplug_slot *slot, const char *buf, + size_t count) { - struct hotplug_slot *slot = file->private_data; - char *buff; unsigned long lattention; u8 attention; int retval = 0; - if (*offset < 0) - return -EINVAL; - if (count == 0 || count > 16384) - return 0; - if (*offset != 0) - return 0; - - if (slot == NULL) { - dbg("slot == NULL???\n"); - return -ENODEV; - } - - buff = kmalloc (count + 1, GFP_KERNEL); - if (!buff) - return -ENOMEM; - memset (buff, 0x00, count + 1); - - if (copy_from_user ((void *)buff, (void *)ubuff, count)) { - retval = -EFAULT; - goto exit; - } - - lattention = simple_strtoul (buff, NULL, 10); + lattention = simple_strtoul (buf, NULL, 10); attention = (u8)(lattention & 0xff); dbg (" - attention = %d\n", attention); @@ -776,128 +251,63 @@ module_put(slot->ops->owner); exit: - kfree (buff); - if (retval) return retval; return count; } -static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset) +static struct hotplug_slot_attribute hotplug_slot_attr_attention = { + .attr = {.name = "attention", .mode = S_IFREG | S_IRUGO | S_IWUSR}, + .show = attention_read_file, + .store = attention_write_file +}; + +static ssize_t latch_read_file (struct hotplug_slot *slot, char *buf) { - struct hotplug_slot *slot = file->private_data; - unsigned char *page; int retval; - int len; u8 value; - dbg("count = %d, offset = %lld\n", count, *offset); - - if (*offset < 0) - return -EINVAL; - if (count <= 0) - return 0; - if (*offset != 0) - return 0; - - if (slot == NULL) { - dbg("slot == NULL???\n"); - return -ENODEV; - } - - page = (unsigned char *)__get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - retval = get_latch_status (slot, &value); if (retval) goto exit; - len = sprintf (page, "%d\n", value); - - if (copy_to_user (buf, page, len)) { - retval = -EFAULT; - goto exit; - } - *offset += len; - retval = len; + retval = sprintf (buf, "%d\n", value); exit: - free_page((unsigned long)page); return retval; } -static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset) +static struct hotplug_slot_attribute hotplug_slot_attr_latch = { + .attr = {.name = "latch", .mode = S_IFREG | S_IRUGO | S_IWUSR}, + .show = latch_read_file, +}; + +static ssize_t presence_read_file (struct hotplug_slot *slot, char *buf) { - struct hotplug_slot *slot = file->private_data; - unsigned char *page; int retval; - int len; u8 value; - dbg("count = %d, offset = %lld\n", count, *offset); - - if (*offset < 0) - return -EINVAL; - if (count <= 0) - return 0; - if (*offset != 0) - return 0; - - if (slot == NULL) { - dbg("slot == NULL???\n"); - return -ENODEV; - } - - page = (unsigned char *)__get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - retval = get_adapter_status (slot, &value); if (retval) goto exit; - len = sprintf (page, "%d\n", value); - - if (copy_to_user (buf, page, len)) { - retval = -EFAULT; - goto exit; - } - *offset += len; - retval = len; + retval = sprintf (buf, "%d\n", value); exit: - free_page((unsigned long)page); return retval; } +static struct hotplug_slot_attribute hotplug_slot_attr_presence = { + .attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO | S_IWUSR}, + .show = presence_read_file, +}; + static char *unknown_speed = "Unknown bus speed"; -static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset) +static ssize_t max_bus_speed_read_file (struct hotplug_slot *slot, char *buf) { - struct hotplug_slot *slot = file->private_data; - unsigned char *page; char *speed_string; int retval; - int len = 0; enum pci_bus_speed value; - dbg ("count = %d, offset = %lld\n", count, *offset); - - if (*offset < 0) - return -EINVAL; - if (count <= 0) - return 0; - if (*offset != 0) - return 0; - - if (slot == NULL) { - dbg("slot == NULL???\n"); - return -ENODEV; - } - - page = (unsigned char *)__get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - retval = get_max_bus_speed (slot, &value); if (retval) goto exit; @@ -907,47 +317,23 @@ else speed_string = pci_bus_speed_strings[value]; - len = sprintf (page, "%s\n", speed_string); - - if (copy_to_user (buf, page, len)) { - retval = -EFAULT; - goto exit; - } - *offset += len; - retval = len; + retval = sprintf (buf, "%s\n", speed_string); exit: - free_page((unsigned long)page); return retval; } -static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset) +static struct hotplug_slot_attribute hotplug_slot_attr_max_bus_speed = { + .attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR}, + .show = max_bus_speed_read_file, +}; + +static ssize_t cur_bus_speed_read_file (struct hotplug_slot *slot, char *buf) { - struct hotplug_slot *slot = file->private_data; - unsigned char *page; char *speed_string; int retval; - int len = 0; enum pci_bus_speed value; - dbg ("count = %d, offset = %lld\n", count, *offset); - - if (*offset < 0) - return -EINVAL; - if (count <= 0) - return 0; - if (*offset != 0) - return 0; - - if (slot == NULL) { - dbg("slot == NULL???\n"); - return -ENODEV; - } - - page = (unsigned char *)__get_free_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - retval = get_cur_bus_speed (slot, &value); if (retval) goto exit; @@ -957,51 +343,25 @@ else speed_string = pci_bus_speed_strings[value]; - len = sprintf (page, "%s\n", speed_string); - - if (copy_to_user (buf, page, len)) { - retval = -EFAULT; - goto exit; - } - *offset += len; - retval = len; + retval = sprintf (buf, "%s\n", speed_string); exit: - free_page((unsigned long)page); return retval; } -static ssize_t test_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset) +static struct hotplug_slot_attribute hotplug_slot_attr_cur_bus_speed = { + .attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR}, + .show = cur_bus_speed_read_file, +}; + +static ssize_t test_write_file (struct hotplug_slot *slot, const char *buf, + size_t count) { - struct hotplug_slot *slot = file->private_data; - char *buff; unsigned long ltest; u32 test; int retval = 0; - if (*offset < 0) - return -EINVAL; - if (count == 0 || count > 16384) - return 0; - if (*offset != 0) - return 0; - - if (slot == NULL) { - dbg("slot == NULL???\n"); - return -ENODEV; - } - - buff = kmalloc (count + 1, GFP_KERNEL); - if (!buff) - return -ENOMEM; - memset (buff, 0x00, count + 1); - - if (copy_from_user ((void *)buff, (void *)ubuff, count)) { - retval = -EFAULT; - goto exit; - } - - ltest = simple_strtoul (buff, NULL, 10); + ltest = simple_strtoul (buf, NULL, 10); test = (u32)(ltest & 0xffffffff); dbg ("test = %d\n", test); @@ -1014,104 +374,130 @@ module_put(slot->ops->owner); exit: - kfree (buff); - if (retval) return retval; return count; } +static struct hotplug_slot_attribute hotplug_slot_attr_test = { + .attr = {.name = "test", .mode = S_IFREG | S_IRUGO | S_IWUSR}, + .store = test_write_file +}; + +static int has_power_file (struct hotplug_slot *slot) +{ + if ((!slot) || (!slot->ops)) + return -ENODEV; + if ((slot->ops->enable_slot) || + (slot->ops->disable_slot) || + (slot->ops->get_power_status)) + return 0; + return -ENOENT; +} + +static int has_attention_file (struct hotplug_slot *slot) +{ + if ((!slot) || (!slot->ops)) + return -ENODEV; + if ((slot->ops->set_attention_status) || + (slot->ops->get_attention_status)) + return 0; + return -ENOENT; +} + +static int has_latch_file (struct hotplug_slot *slot) +{ + if ((!slot) || (!slot->ops)) + return -ENODEV; + if (slot->ops->get_latch_status) + return 0; + return -ENOENT; +} + +static int has_adapter_file (struct hotplug_slot *slot) +{ + if ((!slot) || (!slot->ops)) + return -ENODEV; + if (slot->ops->get_adapter_status) + return 0; + return -ENOENT; +} + +static int has_max_bus_speed_file (struct hotplug_slot *slot) +{ + if ((!slot) || (!slot->ops)) + return -ENODEV; + if (slot->ops->get_max_bus_speed) + return 0; + return -ENOENT; +} + +static int has_cur_bus_speed_file (struct hotplug_slot *slot) +{ + if ((!slot) || (!slot->ops)) + return -ENODEV; + if (slot->ops->get_cur_bus_speed) + return 0; + return -ENOENT; +} + +static int has_test_file (struct hotplug_slot *slot) +{ + if ((!slot) || (!slot->ops)) + return -ENODEV; + if (slot->ops->hardware_test) + return 0; + return -ENOENT; +} + static int fs_add_slot (struct hotplug_slot *slot) { - struct hotplug_slot_core *core = slot->core_priv; - int result; + if (has_power_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr); + + if (has_attention_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_attention.attr); + + if (has_latch_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_latch.attr); + + if (has_adapter_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr); + + if (has_max_bus_speed_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr); + + if (has_cur_bus_speed_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); + + if (has_test_file(slot) == 0) + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr); - result = get_mount(); - if (result) - return result; - - core->dir_dentry = fs_create_file (slot->name, - S_IFDIR | S_IXUGO | S_IRUGO, - NULL, NULL, NULL); - if (core->dir_dentry != NULL) { - if ((slot->ops->enable_slot) || - (slot->ops->disable_slot) || - (slot->ops->get_power_status)) - core->power_dentry = - fs_create_file ("power", - S_IFREG | S_IRUGO | S_IWUSR, - core->dir_dentry, slot, - &power_file_operations); - - if ((slot->ops->set_attention_status) || - (slot->ops->get_attention_status)) - core->attention_dentry = - fs_create_file ("attention", - S_IFREG | S_IRUGO | S_IWUSR, - core->dir_dentry, slot, - &attention_file_operations); - - if (slot->ops->get_latch_status) - core->latch_dentry = - fs_create_file ("latch", - S_IFREG | S_IRUGO, - core->dir_dentry, slot, - &latch_file_operations); - - if (slot->ops->get_adapter_status) - core->adapter_dentry = - fs_create_file ("adapter", - S_IFREG | S_IRUGO, - core->dir_dentry, slot, - &presence_file_operations); - - if (slot->ops->get_max_bus_speed) - core->max_bus_speed_dentry = - fs_create_file ("max_bus_speed", - S_IFREG | S_IRUGO, - core->dir_dentry, slot, - &max_bus_speed_file_operations); - - if (slot->ops->get_cur_bus_speed) - core->cur_bus_speed_dentry = - fs_create_file ("cur_bus_speed", - S_IFREG | S_IRUGO, - core->dir_dentry, slot, - &cur_bus_speed_file_operations); - - if (slot->ops->hardware_test) - core->test_dentry = - fs_create_file ("test", - S_IFREG | S_IRUGO | S_IWUSR, - core->dir_dentry, slot, - &test_file_operations); - } return 0; } static void fs_remove_slot (struct hotplug_slot *slot) { - struct hotplug_slot_core *core = slot->core_priv; + if (has_power_file(slot) == 0) + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); - if (core->dir_dentry) { - if (core->power_dentry) - fs_remove_file (core->power_dentry); - if (core->attention_dentry) - fs_remove_file (core->attention_dentry); - if (core->latch_dentry) - fs_remove_file (core->latch_dentry); - if (core->adapter_dentry) - fs_remove_file (core->adapter_dentry); - if (core->max_bus_speed_dentry) - fs_remove_file (core->max_bus_speed_dentry); - if (core->cur_bus_speed_dentry) - fs_remove_file (core->cur_bus_speed_dentry); - if (core->test_dentry) - fs_remove_file (core->test_dentry); - fs_remove_file (core->dir_dentry); - } + if (has_attention_file(slot) == 0) + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr); + + if (has_latch_file(slot) == 0) + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr); - remove_mount(); + if (has_adapter_file(slot) == 0) + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr); + + if (has_max_bus_speed_file(slot) == 0) + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr); + + if (has_cur_bus_speed_file(slot) == 0) + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); + + if (has_test_file(slot) == 0) + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); } static struct hotplug_slot *get_slot_from_name (const char *name) @@ -1138,7 +524,6 @@ */ int pci_hp_register (struct hotplug_slot *slot) { - struct hotplug_slot_core *core; int result; if (slot == NULL) @@ -1146,21 +531,21 @@ if ((slot->info == NULL) || (slot->ops == NULL)) return -EINVAL; - core = kmalloc (sizeof (struct hotplug_slot_core), GFP_KERNEL); - if (!core) - return -ENOMEM; - /* make sure we have not already registered this slot */ spin_lock (&list_lock); if (get_slot_from_name (slot->name) != NULL) { spin_unlock (&list_lock); - kfree (core); return -EINVAL; } - memset (core, 0, sizeof (struct hotplug_slot_core)); - slot->core_priv = core; + strncpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN); + kobj_set_kset_s(slot, hotplug_slots_subsys); + if (kobject_register(&slot->kobj)) { + err("Unable to register kobject"); + return -EINVAL; + } + list_add (&slot->slot_list, &pci_hotplug_slot_list); spin_unlock (&list_lock); @@ -1197,68 +582,56 @@ spin_unlock (&list_lock); fs_remove_slot (slot); - kfree(slot->core_priv); dbg ("Removed slot %s from the list\n", slot->name); + kobject_unregister(&slot->kobj); return 0; } -static inline void update_dentry_inode_time (struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - if (inode) { - inode->i_mtime = CURRENT_TIME; - dnotify_parent(dentry, DN_MODIFY); - } -} - /** * pci_hp_change_slot_info - changes the slot's information structure in the core - * @name: the name of the slot whose info has changed + * @slot: pointer to the slot whose info has changed * @info: pointer to the info copy into the slot's info structure * - * A slot with @name must have been registered with the pci + * @slot must have been registered with the pci * hotplug subsystem previously with a call to pci_hp_register(). * * Returns 0 if successful, anything else for an error. */ -int pci_hp_change_slot_info (const char *name, struct hotplug_slot_info *info) +int pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info) { - struct hotplug_slot *temp; - struct hotplug_slot_core *core; - - if (info == NULL) + if ((slot == NULL) || (info == NULL)) return -ENODEV; - spin_lock (&list_lock); - temp = get_slot_from_name (name); - if (temp == NULL) { - spin_unlock (&list_lock); - return -ENODEV; - } - /* - * check all fields in the info structure, and update timestamps - * for the files referring to the fields that have now changed. - */ - core = temp->core_priv; - if ((core->power_dentry) && - (temp->info->power_status != info->power_status)) - update_dentry_inode_time (core->power_dentry); - if ((core->attention_dentry) && - (temp->info->attention_status != info->attention_status)) - update_dentry_inode_time (core->attention_dentry); - if ((core->latch_dentry) && - (temp->info->latch_status != info->latch_status)) - update_dentry_inode_time (core->latch_dentry); - if ((core->adapter_dentry) && - (temp->info->adapter_status != info->adapter_status)) - update_dentry_inode_time (core->adapter_dentry); - if ((core->cur_bus_speed_dentry) && - (temp->info->cur_bus_speed != info->cur_bus_speed)) - update_dentry_inode_time (core->cur_bus_speed_dentry); + * check all fields in the info structure, and update timestamps + * for the files referring to the fields that have now changed. + */ + if ((has_power_file(slot) == 0) && + (slot->info->power_status != info->power_status)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_power.attr); + + if ((has_attention_file(slot) == 0) && + (slot->info->attention_status != info->attention_status)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_attention.attr); + + if ((has_latch_file(slot) == 0) && + (slot->info->latch_status != info->latch_status)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_latch.attr); + + if ((has_adapter_file(slot) == 0) && + (slot->info->adapter_status != info->adapter_status)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_presence.attr); + + if ((has_max_bus_speed_file(slot) == 0) && + (slot->info->max_bus_speed != info->max_bus_speed)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr); + + if ((has_cur_bus_speed_file(slot) == 0) && + (slot->info->cur_bus_speed != info->cur_bus_speed)) + sysfs_update_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); + + memcpy (slot->info, info, sizeof (struct hotplug_slot_info)); - memcpy (temp->info, info, sizeof (struct hotplug_slot_info)); - spin_unlock (&list_lock); return 0; } @@ -1266,32 +639,25 @@ { int result; - spin_lock_init(&mount_lock); spin_lock_init(&list_lock); - dbg("registering filesystem.\n"); - result = register_filesystem(&pcihpfs_type); + kset_set_kset_s(&hotplug_slots_subsys, pci_bus_type.subsys); + result = subsystem_register(&hotplug_slots_subsys); if (result) { - err("register_filesystem failed with %d\n", result); + err("Register subsys with error %d\n", result); goto exit; } - result = cpci_hotplug_init(debug); if (result) { err ("cpci_hotplug_init with error %d\n", result); - goto error_fs; + goto err_subsys; } -#ifdef CONFIG_PROC_FS - /* create mount point for pcihpfs */ - slotdir = proc_mkdir(slotdir_name, proc_bus_pci_dir); -#endif - info (DRIVER_DESC " version: " DRIVER_VERSION "\n"); goto exit; -error_fs: - unregister_filesystem(&pcihpfs_type); +err_subsys: + subsystem_unregister(&hotplug_slots_subsys); exit: return result; } @@ -1299,13 +665,7 @@ static void __exit pci_hotplug_exit (void) { cpci_hotplug_exit(); - - unregister_filesystem(&pcihpfs_type); - -#ifdef CONFIG_PROC_FS - if (slotdir) - remove_proc_entry(slotdir_name, proc_bus_pci_dir); -#endif + subsystem_unregister(&hotplug_slots_subsys); } module_init(pci_hotplug_init); @@ -1320,4 +680,3 @@ EXPORT_SYMBOL_GPL(pci_hp_register); EXPORT_SYMBOL_GPL(pci_hp_deregister); EXPORT_SYMBOL_GPL(pci_hp_change_slot_info); - diff -Nru a/drivers/hotplug/pci_hotplug_util.c b/drivers/hotplug/pci_hotplug_util.c --- a/drivers/hotplug/pci_hotplug_util.c Sun Feb 9 21:13:34 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,217 +0,0 @@ -/* - * PCI HotPlug Utility functions - * - * Copyright (c) 1995,2001 Compaq Computer Corporation - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001 IBM Corp. - * - * All rights reserved. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. 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. - * - * Send feedback to - * - */ - -#include -#include -#include -#include -#include -#include -#include "pci_hotplug.h" - - -#if !defined(CONFIG_HOTPLUG_PCI_MODULE) - #define MY_NAME "pci_hotplug" -#else - #define MY_NAME THIS_MODULE->name -#endif - -#define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0) -#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg) -#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg) -#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg) - - -/* local variables */ -static int debug; - - -/* - * This is code that scans the pci buses. - * Every bus and every function is presented to a custom - * function that can act upon it. - */ - -static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent) -{ - struct list_head *ln; - struct pci_dev *dev; - struct pci_dev_wrapped wrapped_dev; - int result = 0; - - dbg("scanning bus %02x\n", wrapped_bus->bus->number); - - if (fn->pre_visit_pci_bus) { - result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent); - if (result) - return result; - } - - ln = wrapped_bus->bus->devices.next; - while (ln != &wrapped_bus->bus->devices) { - dev = pci_dev_b(ln); - ln = ln->next; - - memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped)); - wrapped_dev.dev = dev; - - result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus); - if (result) - return result; - } - - if (fn->post_visit_pci_bus) - result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent); - - return result; -} - - -static int pci_visit_bridge (struct pci_visit * fn, struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_parent) -{ - struct pci_bus *bus; - struct pci_bus_wrapped wrapped_bus; - int result = 0; - - dbg("scanning bridge %02x, %02x\n", PCI_SLOT(wrapped_dev->dev->devfn), - PCI_FUNC(wrapped_dev->dev->devfn)); - - if (fn->visit_pci_dev) { - result = fn->visit_pci_dev(wrapped_dev, wrapped_parent); - if (result) - return result; - } - - bus = wrapped_dev->dev->subordinate; - if(bus) { - memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped)); - wrapped_bus.bus = bus; - - result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev); - } - return result; -} - - -int pci_visit_dev (struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_parent) -{ - struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL; - int result = 0; - - if (!dev) - return 0; - - if (fn->pre_visit_pci_dev) { - result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent); - if (result) - return result; - } - - switch (dev->class >> 8) { - case PCI_CLASS_BRIDGE_PCI: - result = pci_visit_bridge(fn, wrapped_dev, - wrapped_parent); - if (result) - return result; - break; - default: - dbg("scanning device %02x, %02x\n", - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - if (fn->visit_pci_dev) { - result = fn->visit_pci_dev (wrapped_dev, - wrapped_parent); - if (result) - return result; - } - } - - if (fn->post_visit_pci_dev) - result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent); - - return result; -} - -/** - * pci_is_dev_in_use - query devices' usage - * @dev: PCI device to query - * - * Queries whether a given PCI device is in use by a driver or not. - * Returns 1 if the device is in use, 0 if it is not. - */ -int pci_is_dev_in_use(struct pci_dev *dev) -{ - /* - * dev->driver will be set if the device is in use by a new-style - * driver -- otherwise, check the device's regions to see if any - * driver has claimed them. - */ - - int i; - int inuse = 0; - - if (dev->driver) { - /* Assume driver feels responsible */ - return 1; - } - - for (i = 0; !dev->driver && !inuse && (i < 6); i++) { - if (!pci_resource_start(dev, i)) - continue; - if (pci_resource_flags(dev, i) & IORESOURCE_IO) { - inuse = check_region(pci_resource_start(dev, i), - pci_resource_len(dev, i)); - } else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) { - inuse = check_mem_region(pci_resource_start(dev, i), - pci_resource_len(dev, i)); - } - } - return inuse; -} - -/** - * pci_remove_device_safe - remove an unused hotplug device - * @dev: the device to remove - * - * Delete the device structure from the device lists and - * notify userspace (/sbin/hotplug), but only if the device - * in question is not being used by a driver. - * Returns 0 on success. - */ -int pci_remove_device_safe(struct pci_dev *dev) -{ - if (pci_is_dev_in_use(dev)) { - return -EBUSY; - } - pci_remove_device(dev); - return 0; -} - -EXPORT_SYMBOL(pci_visit_dev); -EXPORT_SYMBOL(pci_is_dev_in_use); -EXPORT_SYMBOL(pci_remove_device_safe); - diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig --- a/drivers/i2c/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/i2c/Kconfig Sun Feb 9 21:13:29 2003 @@ -27,7 +27,7 @@ This I2C support is also available as a module. If you want to compile it as a module, say M here and read . - The module will be called i2c-core.o. + The module will be called i2c-core. config I2C_ALGOBIT tristate "I2C bit-banging interfaces" @@ -40,7 +40,7 @@ This support is also available as a module. If you want to compile it as a module, say M here and read . - The module will be called i2c-algo-bit.o. + The module will be called i2c-algo-bit. config I2C_PHILIPSPAR tristate "Philips style parallel port adapter" @@ -52,7 +52,7 @@ This driver is also available as a module. If you want to compile it as a module, say M here and read . - The module will be called i2c-philips-par.o. + The module will be called i2c-philips-par. Note that if you want support for different parallel port devices, life will be much easier if you compile them all as modules. @@ -67,7 +67,7 @@ This driver is also available as a module. If you want to compile it as a module, say M here and read . - The module will be called i2c-elv.o. + The module will be called i2c-elv. config I2C_VELLEMAN tristate "Velleman K9000 adapter" @@ -79,7 +79,7 @@ This driver is also available as a module. If you want to compile it as a module, say M here and read . - The module will be called i2c-velleman.o. + The module will be called i2c-velleman. config SCx200_I2C tristate "NatSemi SCx200 I2C using GPIO pins" @@ -89,7 +89,7 @@ If you don't know what to do here, say N. - If compiled as a module, it will be called scx200_i2c.o. + If compiled as a module, it will be called scx200_i2c. config SCx200_I2C_SCL int "GPIO pin used for SCL" @@ -115,7 +115,7 @@ If you don't know what to do here, say N. - If compiled as a module, it will be called scx200_acb.o. + If compiled as a module, it will be called scx200_acb. config I2C_ALGOPCF tristate "I2C PCF 8584 interfaces" @@ -128,7 +128,7 @@ This support is also available as a module. If you want to compile it as a module, say M here and read . - The module will be called i2c-algo-pcf.o. + The module will be called i2c-algo-pcf. config I2C_ELEKTOR tristate "Elektor ISA card" @@ -140,15 +140,31 @@ This driver is also available as a module. If you want to compile it as a module, say M here and read . - The module will be called i2c-elektor.o. + The module will be called i2c-elektor. config ITE_I2C_ALGO tristate "ITE I2C Algorithm" depends on MIPS_ITE8172 && I2C + help + This supports the use of the ITE8172 I2C interface found on some MIPS + systems. Say Y if you have one of these. You should also say Y for + the ITE I2C peripheral driver support below. + + This support is also available as a module. If you want to compile + it as a module, say M here and read Documentation/modules.txt. + The module will be called i2c-algo-ite.o. config ITE_I2C_ADAP tristate "ITE I2C Adapter" depends on ITE_I2C_ALGO + help + This supports the ITE8172 I2C peripheral found on some MIPS + systems. Say Y if you have one of these. You should also say Y for + the ITE I2C driver algorithm support above. + + This support is also available as a module. If you want to compile + it as a module, say M here and read Documentation/modules.txt. + The module will be called i2c-adap-ite.o. config I2C_ALGO8XX tristate "MPC8xx CPM I2C interface" @@ -178,7 +194,7 @@ This code is also available as a module. If you want to compile it as a module, say M here and read . - The module will be called i2c-dev.o. + The module will be called i2c-dev. config I2C_PROC tristate "I2C /proc interface (required for hardware sensors)" @@ -189,7 +205,7 @@ This code is also available as a module. If you want to compile it as a module, say M here and read . - The module will be called i2c-proc.o. + The module will be called i2c-proc. source drivers/i2c/busses/Kconfig source drivers/i2c/chips/Kconfig diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile --- a/drivers/i2c/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/i2c/Makefile Sun Feb 9 21:13:28 2003 @@ -2,9 +2,6 @@ # Makefile for the kernel i2c bus driver. # -export-objs := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \ - i2c-algo-ite.o i2c-proc.o i2c-algo-ibm_ocp.o - obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig --- a/drivers/i2c/busses/Kconfig Sun Feb 9 21:13:35 2003 +++ b/drivers/i2c/busses/Kconfig Sun Feb 9 21:13:35 2003 @@ -16,7 +16,7 @@ while the kernel is running. If you want to compile it as a module, say M here and read . - The module will be called i2c-amd756.o. + The module will be called i2c-amd756. You will also need the latest user-space utilties: you can find them in the lm_sensors package, which you can download at @@ -33,7 +33,7 @@ while the kernel is running. If you want to compile it as a module, say M here and read . - The module will be called i2c-amd8111.o. + The module will be called i2c-amd8111. You will also need the latest user-space utilties: you can find them in the lm_sensors package, which you can download at diff -Nru a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig --- a/drivers/i2c/chips/Kconfig Sun Feb 9 21:13:32 2003 +++ b/drivers/i2c/chips/Kconfig Sun Feb 9 21:13:32 2003 @@ -16,7 +16,7 @@ be built as a module which can be inserted and removed while the kernel is running. - The module will be called adm1021.o. + The module will be called adm1021. You will also need the latest user-space utilties: you can find them in the lm_sensors package, which you can download at @@ -31,7 +31,7 @@ TCN75, and National Semi LM77. This can also be built as a module which can be inserted and removed while the kernel is running. - The module will be called lm75.o. + The module will be called lm75. You will also need the latest user-space utilties: you can find them in the lm_sensors package, which you can download at diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c --- a/drivers/i2c/i2c-core.c Sun Feb 9 21:13:29 2003 +++ b/drivers/i2c/i2c-core.c Sun Feb 9 21:13:29 2003 @@ -57,7 +57,7 @@ /**** lock for writing to global variables: the adapter & driver list */ DECLARE_MUTEX(adap_lock); -DECLARE_MUTEX(driver_lock); +static DECLARE_MUTEX(driver_lock); /**** adapter list */ static struct i2c_adapter *adapters[I2C_ADAP_MAX]; diff -Nru a/drivers/i2c/i2c-proc.c b/drivers/i2c/i2c-proc.c --- a/drivers/i2c/i2c-proc.c Sun Feb 9 21:13:32 2003 +++ b/drivers/i2c/i2c-proc.c Sun Feb 9 21:13:32 2003 @@ -39,7 +39,7 @@ struct i2c_adapter *adapter, int addr); static int i2c_parse_reals(int *nrels, void *buffer, int bufsize, long *results, int magnitude); -static int i2c_write_reals(int nrels, void *buffer, int *bufsize, +static int i2c_write_reals(int nrels, void *buffer, size_t *bufsize, long *results, int magnitude); static int i2c_proc_chips(ctl_table * ctl, int write, struct file *filp, void *buffer, @@ -514,7 +514,7 @@ return 0; } -int i2c_write_reals(int nrels, void *buffer, int *bufsize, +int i2c_write_reals(int nrels, void *buffer, size_t *bufsize, long *results, int magnitude) { #define BUFLEN 20 diff -Nru a/drivers/ide/Kconfig b/drivers/ide/Kconfig --- a/drivers/ide/Kconfig Sun Feb 9 21:13:32 2003 +++ b/drivers/ide/Kconfig Sun Feb 9 21:13:32 2003 @@ -31,7 +31,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read and - . The module will be called ide-mod.o. + . The module will be called ide-mod. Do not compile this driver as a module if your root file system (the one containing the directory /) is located on an IDE device. @@ -77,7 +77,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ide-disk.o. Do not compile this driver as a module + will be called ide-disk. Do not compile this driver as a module if your root file system (the one containing the directory /) is located on the IDE disk. If unsure, say Y. @@ -136,7 +136,7 @@ If you want to compile the driver 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 ide-cd.o. + will be called ide-cd. #dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE config BLK_DEV_IDEFLOPPY @@ -162,7 +162,7 @@ If you want to compile the driver 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 ide-floppy.o. + will be called ide-floppy. config BLK_DEV_IDESCSI tristate "SCSI emulation support" @@ -193,6 +193,13 @@ config IDE_TASK_IOCTL bool "IDE Taskfile Access" depends on BLK_DEV_IDE + help + This is a direct raw access to the media. It is a complex but + elegant solution to test and validate the domain of the hardware and + perform below the driver data recover if needed. This is the most + basic form of media-forensics. + + If you are unsure, say N here. #bool ' IDE Taskfile IO' CONFIG_IDE_TASKFILE_IO comment "IDE chipset support/bugfixes" @@ -245,6 +252,10 @@ bool "PCI IDE chipset support" if PCI depends on BLK_DEV_IDE default BLK_DEV_IDEDMA_PMAC if ALL_PPC && BLK_DEV_IDEDMA_PMAC + help + Say Y here for PCI systems which use IDE drive(s). + This option helps the IDE driver to automatically detect and + configure all PCI-based IDE interfaces in your system. config BLK_DEV_GENERIC bool "Generic PCI IDE Chipset Support" @@ -347,6 +358,10 @@ config BLK_DEV_IDEDMA_FORCED bool "Force enable legacy 2.0.X HOSTS to use DMA" depends on BLK_DEV_IDEDMA_PCI + help + This is an old piece of lost code from Linux 2.0 Kernels. + + Generally say N here. config IDEDMA_PCI_AUTO bool "Use PCI DMA by default when available" @@ -383,6 +398,12 @@ config IDEDMA_PCI_WIP bool "ATA Work(s) In Progress (EXPERIMENTAL)" depends on BLK_DEV_IDEDMA_PCI && EXPERIMENTAL + help + If you enable this you will be able to use and test highly + developmental projects. If you say N, the configurator will + simply skip those options. + + It is SAFEST to say N to this question. config IDEDMA_NEW_DRIVE_LISTINGS bool "Good-Bad DMA Model-Firmware (WIP)" @@ -656,6 +677,18 @@ config BLK_DEV_SLC90E66 tristate "SLC90E66 chipset support" depends on BLK_DEV_IDEDMA_PCI + help + This driver ensures (U)DMA support for Victroy66 SouthBridges for + SMsC with Intel NorthBridges. This is an Ultra66 based chipset. + The nice thing about it is that you can mix Ultra/DMA/PIO devices + and it will handle timing cycles. Since this is an improved + look-a-like to the PIIX4 it should be a nice addition. + + If you say Y here, you need to say Y to "Use DMA by default when + available" as well. + + Please read the comments at the top of + drivers/ide/slc90e66.c. config BLK_DEV_TRM290 tristate "Tekram TRM290 chipset support" @@ -880,6 +913,12 @@ config BLK_DEV_4DRIVES bool "Generic 4 drives/port support" depends on IDE_CHIPSETS + help + Certain older chipsets, including the Tekram 690CD, use a single set + of I/O ports at 0x1f0 to control up to four drives, instead of the + customary two drives per port. Support for this can be enabled at + runtime using the "ide0=four" kernel boot parameter if you say Y + here. config BLK_DEV_ALI14XX tristate "ALI M14xx support" diff -Nru a/drivers/ide/Makefile b/drivers/ide/Makefile --- a/drivers/ide/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/ide/Makefile Sun Feb 9 21:13:32 2003 @@ -7,8 +7,6 @@ # Note : at this point, these files are compiled on all systems. # In the future, some of these should be built conditionally. # -export-objs := ide-iops.o ide-taskfile.o ide-proc.o ide.o ide-probe.o ide-dma.o ide-lib.o setup-pci.o ide-io.o - # First come modules that register themselves with the core obj-$(CONFIG_BLK_DEV_IDEPCI) += pci/ diff -Nru a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c --- a/drivers/ide/pci/amd74xx.c Sun Feb 9 21:13:37 2003 +++ b/drivers/ide/pci/amd74xx.c Sun Feb 9 21:13:37 2003 @@ -82,7 +82,7 @@ #include #include -static int amd_base; +static long amd_base; static struct pci_dev *bmide_dev; extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */ diff -Nru a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c --- a/drivers/ide/pci/pdc202xx_new.c Sun Feb 9 21:13:34 2003 +++ b/drivers/ide/pci/pdc202xx_new.c Sun Feb 9 21:13:34 2003 @@ -339,7 +339,7 @@ * fall back to U33 mode. The BIOS INT 13 hooks turn * the clock on then off for each read/write issued. I don't * do that here because it would require modifying the - * kernel, seperating the fop routines from the kernel or + * kernel, separating the fop routines from the kernel or * somehow hooking the fops calls. It may also be possible to * leave the 66Mhz clock on and readjust the timing * parameters. diff -Nru a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c --- a/drivers/ide/pci/pdc202xx_old.c Sun Feb 9 21:13:36 2003 +++ b/drivers/ide/pci/pdc202xx_old.c Sun Feb 9 21:13:36 2003 @@ -400,7 +400,7 @@ * fall back to U33 mode. The BIOS INT 13 hooks turn * the clock on then off for each read/write issued. I don't * do that here because it would require modifying the - * kernel, seperating the fop routines from the kernel or + * kernel, separating the fop routines from the kernel or * somehow hooking the fops calls. It may also be possible to * leave the 66Mhz clock on and readjust the timing * parameters. diff -Nru a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c --- a/drivers/ide/pci/sis5513.c Sun Feb 9 21:13:32 2003 +++ b/drivers/ide/pci/sis5513.c Sun Feb 9 21:13:32 2003 @@ -22,7 +22,7 @@ /* * TODO: - * - Get ridden of SisHostChipInfo[] completness dependancy. + * - Get ridden of SisHostChipInfo[] completness dependency. * - Study drivers/ide/ide-timing.h. * - Are there pre-ATA_16 SiS5513 chips ? -> tune init code for them * or remove ATA_00 define @@ -64,7 +64,7 @@ /* Miscellaneaous flags */ #define SIS5513_LATENCY 0x01 -/* registers layout and init values are chipset family dependant */ +/* registers layout and init values are chipset family dependent */ /* 1/ define families */ #define ATA_00 0x00 #define ATA_16 0x01 diff -Nru a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig --- a/drivers/ieee1394/Kconfig Sun Feb 9 21:13:28 2003 +++ b/drivers/ieee1394/Kconfig Sun Feb 9 21:13:28 2003 @@ -18,7 +18,7 @@ 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 ieee1394.o. + will be called ieee1394. comment "Subsystem Options" depends on IEEE1394 @@ -67,7 +67,7 @@ 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 pcilynx.o. + will be called pcilynx. # Non-maintained pcilynx options # if [ "$CONFIG_IEEE1394_PCILYNX" != "n" ]; then @@ -87,7 +87,7 @@ 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 ohci1394.o. + will be called ohci1394. comment "Protocol Drivers" depends on IEEE1394 @@ -131,7 +131,7 @@ 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 dv1394.o. + will be called dv1394. config IEEE1394_RAWIO tristate "Raw IEEE1394 I/O support" @@ -145,7 +145,7 @@ 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 raw1394.o. + will be called raw1394. config IEEE1394_CMP tristate "IEC61883-1 Plug support" @@ -157,7 +157,7 @@ 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 amdtp.o. + will be called amdtp. config IEEE1394_AMDTP tristate "IEC61883-6 (Audio transmission) support" @@ -172,6 +172,6 @@ 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 amdtp.o. + will be called amdtp. endmenu diff -Nru a/drivers/ieee1394/Makefile b/drivers/ieee1394/Makefile --- a/drivers/ieee1394/Makefile Sun Feb 9 21:13:37 2003 +++ b/drivers/ieee1394/Makefile Sun Feb 9 21:13:37 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux IEEE 1394 implementation # -export-objs := ieee1394_core.o ohci1394.o cmp.o - ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \ highlevel.o csr.o nodemgr.o oui.o dma.o iso.o diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c --- a/drivers/ieee1394/sbp2.c Sun Feb 9 21:13:29 2003 +++ b/drivers/ieee1394/sbp2.c Sun Feb 9 21:13:29 2003 @@ -829,7 +829,7 @@ { struct sbp2scsi_host_info *hi; - hi = (struct sbp2scsi_host_info *) command->Current_SCpnt->host->hostdata[0]; + hi = (struct sbp2scsi_host_info *) command->Current_SCpnt->device->host->hostdata[0]; if (hi == NULL) { printk(KERN_ERR "%s: hi == NULL\n", __FUNCTION__); @@ -2659,7 +2659,7 @@ /* * Pull our host info and scsi id instance data from the scsi command */ - hi = (struct sbp2scsi_host_info *) SCpnt->host->hostdata[0]; + hi = (struct sbp2scsi_host_info *) SCpnt->device->host->hostdata[0]; if (!hi) { SBP2_ERR("sbp2scsi_host_info is NULL - this is bad!"); @@ -2668,7 +2668,7 @@ return(0); } - scsi_id = hi->scsi_id[SCpnt->target]; + scsi_id = hi->scsi_id[SCpnt->device->id]; /* * If scsi_id is null, it means there is no device in this slot, @@ -2684,7 +2684,7 @@ * Until we handle multiple luns, just return selection time-out * to any IO directed at non-zero LUNs */ - if (SCpnt->lun) { + if (SCpnt->device->lun) { SCpnt->result = DID_NO_CONNECT << 16; done (SCpnt); return(0); @@ -2882,8 +2882,8 @@ */ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt) { - struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->host->hostdata[0]; - struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->target]; + struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->device->host->hostdata[0]; + struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->device->id]; struct sbp2_command_info *command; unsigned long flags; @@ -2932,8 +2932,8 @@ */ static int sbp2scsi_reset (Scsi_Cmnd *SCpnt) { - struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->host->hostdata[0]; - struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->target]; + struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->device->host->hostdata[0]; + struct scsi_id_instance_data *scsi_id = hi->scsi_id[SCpnt->device->id]; SBP2_ERR("reset requested"); diff -Nru a/drivers/input/Kconfig b/drivers/input/Kconfig --- a/drivers/input/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/input/Kconfig Sun Feb 9 21:13:29 2003 @@ -21,7 +21,7 @@ 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 will be called input.o. If you want to compile it as a + The module will be called input. If you want to compile it as a module, say M here and read . comment "Userland interfaces" @@ -41,7 +41,7 @@ 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 will be called mousedev.o. If you want to compile it as + The module will be called mousedev. If you want to compile it as a module, say M here and read . config INPUT_MOUSEDEV_PSAUX @@ -82,7 +82,7 @@ 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 will be called joydev.o. If you want to compile it as a + The module will be called joydev. If you want to compile it as a module, say M here and read . config INPUT_TSDEV @@ -97,7 +97,7 @@ 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 will be called tsdev.o. If you want to compile it as a + The module will be called tsdev. If you want to compile it as a module, say M here and read . config INPUT_TSDEV_SCREEN_X @@ -119,7 +119,7 @@ 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 will be called evdev.o. If you want to compile it as a + The module will be called evdev. If you want to compile it as a module, say M here and read . config INPUT_EVBUG @@ -136,7 +136,7 @@ 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 will be called joydev.o. If you want to compile it as a + The module will be called joydev. If you want to compile it as a module, say M here and read . comment "Input I/O drivers" diff -Nru a/drivers/input/Makefile b/drivers/input/Makefile --- a/drivers/input/Makefile Sun Feb 9 21:13:36 2003 +++ b/drivers/input/Makefile Sun Feb 9 21:13:36 2003 @@ -2,10 +2,6 @@ # Makefile for the input core drivers. # -# Objects that export symbols. - -export-objs := input.o - # Each configuration option enables a list of files. obj-$(CONFIG_INPUT) += input.o diff -Nru a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig --- a/drivers/input/gameport/Kconfig Sun Feb 9 21:13:28 2003 +++ b/drivers/input/gameport/Kconfig Sun Feb 9 21:13:28 2003 @@ -18,7 +18,7 @@ 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 will be called gameport.o. If you want to compile it as + The module will be called gameport. If you want to compile it as a module, say M here and read . config SOUND_GAMEPORT @@ -36,7 +36,7 @@ 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 will be called ns558.o. If you want to compile it as a + The module will be called ns558. If you want to compile it as a module, say M here and read . config GAMEPORT_L4 @@ -47,7 +47,7 @@ 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 will be called lightning.o. If you want to compile it as + The module will be called lightning. If you want to compile it as a module, say M here and read . config GAMEPORT_EMU10K1 @@ -59,7 +59,7 @@ 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 will be called emu10k1-gp.o. If you want to compile it as + The module will be called emu10k1-gp. If you want to compile it as a module, say M here and read . config GAMEPORT_VORTEX @@ -71,7 +71,7 @@ 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 will be called vortex.o. If you want to compile it as a + The module will be called vortex. If you want to compile it as a module, say M here and read . config GAMEPORT_FM801 diff -Nru a/drivers/input/gameport/Makefile b/drivers/input/gameport/Makefile --- a/drivers/input/gameport/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/input/gameport/Makefile Sun Feb 9 21:13:28 2003 @@ -2,10 +2,6 @@ # Makefile for the gameport drivers. # -# Objects that export symbols. - -export-objs := gameport.o - # Each configuration option enables a list of files. obj-$(CONFIG_GAMEPORT) += gameport.o diff -Nru a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig --- a/drivers/input/joystick/Kconfig Sun Feb 9 21:13:28 2003 +++ b/drivers/input/joystick/Kconfig Sun Feb 9 21:13:28 2003 @@ -29,7 +29,7 @@ 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 will be called analog.o. If you want to compile it as a + The module will be called analog. If you want to compile it as a module, say M here and read . config JOYSTICK_A3D @@ -41,7 +41,7 @@ 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 will be called a3d.o. If you want to compile it as a + The module will be called a3d. If you want to compile it as a module, say M here and read . config JOYSTICK_ADI @@ -53,7 +53,7 @@ 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 will be called adi.o. If you want to compile it as a + The module will be called adi. If you want to compile it as a module, say M here and read . config JOYSTICK_COBRA @@ -64,7 +64,7 @@ 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 will be called cobra.o. If you want to compile it as a + The module will be called cobra. If you want to compile it as a module, say M here and read . config JOYSTICK_GF2K @@ -76,7 +76,7 @@ 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 will be called gf2k.o. If you want to compile it as a + The module will be called gf2k. If you want to compile it as a module, say M here and read . config JOYSTICK_GRIP @@ -88,7 +88,7 @@ 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 will be called grip.o. If you want to compile it as a + The module will be called grip. If you want to compile it as a module, say M here and read . config JOYSTICK_GRIP_MP @@ -100,7 +100,7 @@ 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 will be called grip_mp.o. If you want to compile it as a + The module will be called grip_mp. If you want to compile it as a module, say M here and read . config JOYSTICK_GUILLEMOT @@ -112,7 +112,7 @@ 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 will be called guillemot.o. If you want to compile it as a + The module will be called guillemot. If you want to compile it as a module, say M here and read . config JOYSTICK_INTERACT @@ -124,7 +124,7 @@ 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 will be called interact.o. If you want to compile it as + The module will be called interact. If you want to compile it as a module, say M here and read . config JOYSTICK_SIDEWINDER @@ -136,7 +136,7 @@ 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 will be called sidewinder.o. If you want to compile it + The module will be called sidewinder. If you want to compile it as a module, say M here and read . config JOYSTICK_TMDC @@ -148,7 +148,7 @@ 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 will be called tmdc.o. If you want to compile it as a + The module will be called tmdc. If you want to compile it as a module, say M here and read . source "drivers/input/joystick/iforce/Kconfig" @@ -162,7 +162,7 @@ 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 will be called warrior.o. If you want to compile it as a + The module will be called warrior. If you want to compile it as a module, say M here and read . config JOYSTICK_MAGELLAN @@ -174,7 +174,7 @@ 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 will be called magellan.o. If you want to compile it as + The module will be called magellan. If you want to compile it as a module, say M here and read . config JOYSTICK_SPACEORB @@ -186,7 +186,7 @@ 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 will be called spaceorb.o. If you want to compile it as + The module will be called spaceorb. If you want to compile it as a module, say M here and read . config JOYSTICK_SPACEBALL @@ -199,7 +199,7 @@ 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 will be called spaceball.o. If you want to compile it as + The module will be called spaceball. If you want to compile it as a module, say M here and read . config JOYSTICK_STINGER @@ -211,7 +211,7 @@ 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 will be called stinger.o. If you want to compile it as a + The module will be called stinger. If you want to compile it as a module, say M here and read . config JOYSTICK_TWIDDLER @@ -223,7 +223,7 @@ 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 will be called twidjoy.o. If you want to compile it as a + The module will be called twidjoy. If you want to compile it as a module, say M here and read . config JOYSTICK_DB9 @@ -238,7 +238,7 @@ 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 will be called db9.o. If you want to compile it as a + The module will be called db9. If you want to compile it as a module, say M here and read . config JOYSTICK_GAMECON @@ -254,7 +254,7 @@ 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 will be called gamecon.o. If you want to compile it as a + The module will be called gamecon. If you want to compile it as a module, say M here and read . config JOYSTICK_TURBOGRAFX @@ -268,7 +268,7 @@ 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 will be called turbografx.o. If you want to compile it + The module will be called turbografx. If you want to compile it as a module, say M here and read . config JOYSTICK_AMIGA @@ -280,7 +280,7 @@ 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 will be called amijoy.o. If you want to compile it as + The module will be called amijoy. If you want to compile it as a module, say M here and read . config INPUT_JOYDUMP @@ -293,6 +293,6 @@ 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 will be called joydump.o. If you want to compile it as + The module will be called joydump. If you want to compile it as a module, say M here and read . diff -Nru a/drivers/input/joystick/iforce/Kconfig b/drivers/input/joystick/iforce/Kconfig --- a/drivers/input/joystick/iforce/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/input/joystick/iforce/Kconfig Sun Feb 9 21:13:29 2003 @@ -11,7 +11,7 @@ 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 will be called iforce.o. If you want to compile it as a + The module will be called iforce. If you want to compile it as a module, say M here and read . config JOYSTICK_IFORCE_USB diff -Nru a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig --- a/drivers/input/keyboard/Kconfig Sun Feb 9 21:13:36 2003 +++ b/drivers/input/keyboard/Kconfig Sun Feb 9 21:13:36 2003 @@ -25,7 +25,7 @@ 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 will be called atkbd.o. If you want to compile it as a + The module will be called atkbd. If you want to compile it as a module, say M here and read . config KEYBOARD_SUNKBD @@ -38,7 +38,7 @@ 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 will be called sunkbd.o. If you want to compile it as a + The module will be called sunkbd. If you want to compile it as a module, say M here and read . config KEYBOARD_XTKBD @@ -52,7 +52,7 @@ 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 will be called xtkbd.o. If you want to compile it as a + The module will be called xtkbd. If you want to compile it as a module, say M here and read . config KEYBOARD_NEWTON @@ -63,7 +63,7 @@ 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 will be called maple_keyb.o. If you want to compile it as a + The module will be called maple_keyb. If you want to compile it as a module, say M here and read . config KEYBOARD_MAPLE @@ -75,7 +75,7 @@ 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 will be called maple_keyb.o. If you want to compile it as a + The module will be called maple_keyb. If you want to compile it as a module, say M here and read . config KEYBOARD_AMIGA @@ -87,6 +87,6 @@ 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 will be called amikbd.o. If you want to compile it as a + The module will be called amikbd. If you want to compile it as a module, say M here and read . diff -Nru a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig --- a/drivers/input/misc/Kconfig Sun Feb 9 21:13:31 2003 +++ b/drivers/input/misc/Kconfig Sun Feb 9 21:13:31 2003 @@ -23,7 +23,7 @@ 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 will be called pcspkr.o. If you want to compile it as a + The module will be called pcspkr. If you want to compile it as a module, say M here and read . config INPUT_SPARCSPKR @@ -37,7 +37,7 @@ 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 will be called pcspkr.o. If you want to compile it as a + The module will be called pcspkr. If you want to compile it as a module, say M here and read . config INPUT_M68K_BEEP @@ -53,7 +53,7 @@ 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 will be called uinput.o. If you want to compile it as a + The module will be called uinput. If you want to compile it as a module, say M here and read . config INPUT_GSC diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig --- a/drivers/input/mouse/Kconfig Sun Feb 9 21:13:35 2003 +++ b/drivers/input/mouse/Kconfig Sun Feb 9 21:13:35 2003 @@ -25,7 +25,7 @@ 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 will be called psmouse.o. If you want to compile it as a + The module will be called psmouse. If you want to compile it as a module, say M here and read . config MOUSE_SERIAL @@ -40,7 +40,7 @@ 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 will be called sermouse.o. If you want to compile it as a + The module will be called sermouse. If you want to compile it as a module, say M here and read . config MOUSE_INPORT @@ -52,7 +52,7 @@ 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 will be called inport.o. If you want to compile it as a + The module will be called inport. If you want to compile it as a module, say M here and read . config MOUSE_ATIXL @@ -70,7 +70,7 @@ 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 will be called logibm.o. If you want to compile it as a + The module will be called logibm. If you want to compile it as a module, say M here and read . config MOUSE_PC110PAD @@ -82,7 +82,7 @@ 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 will be called pc110pad.o. If you want to compile it as a + The module will be called pc110pad. If you want to compile it as a module, say M here and read . config MOUSE_MAPLE @@ -94,7 +94,7 @@ 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 will be called maplemouse.o. If you want to compile it as a + The module will be called maplemouse. If you want to compile it as a module, say M here and read . config MOUSE_AMIGA @@ -106,7 +106,7 @@ 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 will be called amimouse.o. If you want to compile it as a + The module will be called amimouse. If you want to compile it as a module, say M here and read . config MOUSE_RISCPC @@ -118,6 +118,6 @@ 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 will be called rpcmouse.o. If you want to compile it as a + The module will be called rpcmouse. If you want to compile it as a module, say M here and read . diff -Nru a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c --- a/drivers/input/mouse/rpcmouse.c Sun Feb 9 21:13:31 2003 +++ b/drivers/input/mouse/rpcmouse.c Sun Feb 9 21:13:31 2003 @@ -88,7 +88,7 @@ input_register_device(&rpcmouse_dev); - printk(KERN_INFO "input: Acorn RiscPC mouse irq %d", IRQ_VSYNCPULSE); + printk(KERN_INFO "input: Acorn RiscPC mouse\n"); return 0; } diff -Nru a/drivers/input/power.c b/drivers/input/power.c --- a/drivers/input/power.c Sun Feb 9 21:13:34 2003 +++ b/drivers/input/power.c Sun Feb 9 21:13:34 2003 @@ -23,7 +23,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Should you need to contact me, the author, you can do so either by + * Should you need to contact me, the author, you can do so by * e-mail - mail your message to . */ diff -Nru a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig --- a/drivers/input/serio/Kconfig Sun Feb 9 21:13:32 2003 +++ b/drivers/input/serio/Kconfig Sun Feb 9 21:13:32 2003 @@ -15,7 +15,7 @@ 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 will be called serio.o. If you want to compile it + The module will be called serio. If you want to compile it as a module, say M here and read . config SERIO_I8042 @@ -31,7 +31,7 @@ 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 will be called i8042.o. If you want to compile it + The module will be called i8042. If you want to compile it as a module, say M here and read . config SERIO_SERPORT @@ -48,7 +48,7 @@ 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 will be called serport.o. If you want to compile it as a + The module will be called serport. If you want to compile it as a module, say M here and read . config SERIO_CT82C710 @@ -63,7 +63,7 @@ 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 will be called ct82c710.o. If you want to compile it as a + The module will be called ct82c710. If you want to compile it as a module, say M here and read . config SERIO_Q40KBD @@ -83,7 +83,7 @@ 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 will be called parkbd.o. If you want to compile it as a + The module will be called parkbd. If you want to compile it as a module, say M here and read . config SERIO_RPCKBD @@ -96,7 +96,7 @@ 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 will be called rpckbd.o. If you want to compile it as a + The module will be called rpckbd. If you want to compile it as a module, say M here and read . config SERIO_AMBAKMI diff -Nru a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile --- a/drivers/input/serio/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/input/serio/Makefile Sun Feb 9 21:13:28 2003 @@ -2,10 +2,6 @@ # Makefile for the input core drivers. # -# Objects that export symbols. - -export-objs := serio.o - # Each configuration option enables a list of files. obj-$(CONFIG_SERIO) += serio.o diff -Nru a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig --- a/drivers/input/touchscreen/Kconfig Sun Feb 9 21:13:32 2003 +++ b/drivers/input/touchscreen/Kconfig Sun Feb 9 21:13:32 2003 @@ -20,7 +20,7 @@ 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 will be called gunze.o. If you want to compile it as a + The module will be called gunze. If you want to compile it as a module, say M here and read . config TOUCHSCREEN_GUNZE @@ -34,6 +34,6 @@ 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 will be called gunze.o. If you want to compile it as a + The module will be called gunze. If you want to compile it as a module, say M here and read . diff -Nru a/drivers/isdn/capi/Makefile b/drivers/isdn/capi/Makefile --- a/drivers/isdn/capi/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/isdn/capi/Makefile Sun Feb 9 21:13:32 2003 @@ -1,9 +1,5 @@ # Makefile for the CAPI subsystem. -# Objects that export symbols. - -export-objs := kcapi.o capiutil.o capilib.o capifs.o - # Ordering constraints: kernelcapi.o first # Each configuration option enables a list of files. diff -Nru a/drivers/isdn/eicon/Makefile b/drivers/isdn/eicon/Makefile --- a/drivers/isdn/eicon/Makefile Sun Feb 9 21:13:30 2003 +++ b/drivers/isdn/eicon/Makefile Sun Feb 9 21:13:30 2003 @@ -1,9 +1,5 @@ # Makefile for the eicon ISDN device driver -# Objects that export symbols. - -export-objs := Divas_mod.o eicon_mod.o - # Each configuration option enables a list of files. obj-$(CONFIG_ISDN_DRV_EICON_OLD) += eicon.o diff -Nru a/drivers/isdn/eicon/eicon.h b/drivers/isdn/eicon/eicon.h --- a/drivers/isdn/eicon/eicon.h Sun Feb 9 21:13:30 2003 +++ b/drivers/isdn/eicon/eicon.h Sun Feb 9 21:13:30 2003 @@ -305,7 +305,7 @@ * Per card driver data */ typedef struct eicon_card { - eicon_hwif hwif; /* Hardware dependant interface */ + eicon_hwif hwif; /* Hardware dependent interface */ DESCRIPTOR *d; /* IDI Descriptor */ u_char ptype; /* Protocol type (1TR6 or Euro) */ u_char bus; /* Bustype (ISA, MCA, PCI) */ diff -Nru a/drivers/isdn/hardware/avm/Makefile b/drivers/isdn/hardware/avm/Makefile --- a/drivers/isdn/hardware/avm/Makefile Sun Feb 9 21:13:31 2003 +++ b/drivers/isdn/hardware/avm/Makefile Sun Feb 9 21:13:31 2003 @@ -1,9 +1,5 @@ # Makefile for the AVM ISDN device drivers -# Objects that export symbols. - -export-objs := b1dma.o b1pcmcia.o b1.o - # Each configuration option enables a list of files. obj-$(CONFIG_ISDN_DRV_AVMB1_B1ISA) += b1isa.o b1.o diff -Nru a/drivers/isdn/hardware/eicon/Makefile b/drivers/isdn/hardware/eicon/Makefile --- a/drivers/isdn/hardware/eicon/Makefile Sun Feb 9 21:13:35 2003 +++ b/drivers/isdn/hardware/eicon/Makefile Sun Feb 9 21:13:35 2003 @@ -1,9 +1,5 @@ # Makefile for the Eicon DIVA ISDN drivers. -# Objects that export symbols. - -export-objs := diva_didd.o - # Multipart objects. divas-objs := divasmain.o divasfunc.o di.o io.o istream.o diva.o dlist.o divasproc.o diva_dma.o diff -Nru a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c --- a/drivers/isdn/hardware/eicon/diva_didd.c Sun Feb 9 21:13:33 2003 +++ b/drivers/isdn/hardware/eicon/diva_didd.c Sun Feb 9 21:13:33 2003 @@ -120,7 +120,7 @@ return (0); } -static void DIVA_EXIT_FUNCTION remove_proc(void) +static void remove_proc(void) { remove_proc_entry(DRIVERLNAME, proc_net_isdn_eicon); remove_proc_entry(main_proc_dir, proc_net_isdn); diff -Nru a/drivers/isdn/hardware/eicon/io.h b/drivers/isdn/hardware/eicon/io.h --- a/drivers/isdn/hardware/eicon/io.h Sun Feb 9 21:13:37 2003 +++ b/drivers/isdn/hardware/eicon/io.h Sun Feb 9 21:13:37 2003 @@ -174,7 +174,7 @@ word assign; /* list of pending ASSIGNs */ word head; /* head of request queue */ word tail; /* tail of request queue */ - ADAPTER a ; /* not a seperate structure */ + ADAPTER a ; /* not a separate structure */ void (* out)(ADAPTER * a) ; byte (* dpc)(ADAPTER * a) ; byte (* tst_irq)(ADAPTER * a) ; diff -Nru a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile --- a/drivers/isdn/hisax/Makefile Sun Feb 9 21:13:31 2003 +++ b/drivers/isdn/hisax/Makefile Sun Feb 9 21:13:31 2003 @@ -4,10 +4,6 @@ EXTRA_CFLAGS += -DHISAX_MAX_CARDS=$(CONFIG_HISAX_MAX_CARDS) -# Objects that export symbols. - -export-objs := config.o hisax_isac.o hisax_hscx.o - # Each configuration option enables a list of files. obj-$(CONFIG_ISDN_DRV_HISAX) += hisax.o diff -Nru a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c --- a/drivers/isdn/hisax/isdnl2.c Sun Feb 9 21:13:29 2003 +++ b/drivers/isdn/hisax/isdnl2.c Sun Feb 9 21:13:29 2003 @@ -1445,7 +1445,7 @@ } static void -l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg) +l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; @@ -1456,7 +1456,7 @@ } static void -l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg) +l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; @@ -1469,7 +1469,7 @@ } static void -l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg) +l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; @@ -1480,7 +1480,7 @@ } static void -l2_persistant_da(struct FsmInst *fi, int event, void *arg) +l2_persistent_da(struct FsmInst *fi, int event, void *arg) { struct PStack *st = fi->userdata; @@ -1615,14 +1615,14 @@ {ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error}, {ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest}, {ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest}, - {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistant_da}, + {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da}, {ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove}, {ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove}, - {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistant_da}, - {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistant_da}, - {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistant_da}, - {ST_L2_7, EV_L1_DEACTIVATE, l2_persistant_da}, - {ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da}, + {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da}, + {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da}, + {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da}, + {ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da}, + {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da}, }; #define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode)) diff -Nru a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c --- a/drivers/isdn/hisax/l3dss1.c Sun Feb 9 21:13:31 2003 +++ b/drivers/isdn/hisax/l3dss1.c Sun Feb 9 21:13:31 2003 @@ -2169,7 +2169,7 @@ /***********************************************/ /* handle special commands for this protocol. */ -/* Examples are call independant services like */ +/* Examples are call independent services like */ /* remote operations with dummy callref. */ /***********************************************/ static int l3dss1_cmd_global(struct PStack *st, isdn_ctrl *ic) diff -Nru a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c --- a/drivers/isdn/hisax/l3ni1.c Sun Feb 9 21:13:29 2003 +++ b/drivers/isdn/hisax/l3ni1.c Sun Feb 9 21:13:29 2003 @@ -2024,7 +2024,7 @@ /***********************************************/ /* handle special commands for this protocol. */ -/* Examples are call independant services like */ +/* Examples are call independent services like */ /* remote operations with dummy callref. */ /***********************************************/ static int l3ni1_cmd_global(struct PStack *st, isdn_ctrl *ic) diff -Nru a/drivers/isdn/hysdn/Kconfig b/drivers/isdn/hysdn/Kconfig --- a/drivers/isdn/hysdn/Kconfig Sun Feb 9 21:13:35 2003 +++ b/drivers/isdn/hysdn/Kconfig Sun Feb 9 21:13:35 2003 @@ -6,7 +6,7 @@ depends on m && PROC_FS help Say Y here if you have one of Hypercope's active PCI ISDN cards - Champ, Ergo and Metro. You will then get a module called hysdn.o. + Champ, Ergo and Metro. You will then get a module called hysdn. Please read the file for more information. diff -Nru a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c --- a/drivers/isdn/hysdn/hysdn_boot.c Sun Feb 9 21:13:31 2003 +++ b/drivers/isdn/hysdn/hysdn_boot.c Sun Feb 9 21:13:31 2003 @@ -78,7 +78,7 @@ } /* DecryptBuf */ /********************************************************************************/ -/* pof_handle_data executes the required actions dependant on the active record */ +/* pof_handle_data executes the required actions dependent on the active record */ /* id. If successful 0 is returned, a negative value shows an error. */ /********************************************************************************/ static int diff -Nru a/drivers/isdn/i4l/Makefile b/drivers/isdn/i4l/Makefile --- a/drivers/isdn/i4l/Makefile Sun Feb 9 21:13:30 2003 +++ b/drivers/isdn/i4l/Makefile Sun Feb 9 21:13:30 2003 @@ -1,9 +1,5 @@ # Makefile for the kernel ISDN subsystem and device drivers. -# Objects that export symbols. - -export-objs := isdn_common.o - # Each configuration option enables a list of files. obj-$(CONFIG_ISDN) += isdn.o diff -Nru a/drivers/isdn/sc/Kconfig b/drivers/isdn/sc/Kconfig --- a/drivers/isdn/sc/Kconfig Sun Feb 9 21:13:31 2003 +++ b/drivers/isdn/sc/Kconfig Sun Feb 9 21:13:31 2003 @@ -9,6 +9,6 @@ driver currently builds only in a modularized version ( = code which can be inserted in and removed from the running kernel whenever you want, details in ); the module will - be called sc.o. See and + be called sc. See and for more information. diff -Nru a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile --- a/drivers/macintosh/Makefile Sun Feb 9 21:13:35 2003 +++ b/drivers/macintosh/Makefile Sun Feb 9 21:13:35 2003 @@ -2,17 +2,6 @@ # Makefile for the Macintosh-specific device drivers. # -# Objects that export symbols. - -export-objs := adb.o mac_hid.o via-pmu.o - -# Object file lists. - -obj-y := -obj-m := -obj-n := -obj- := - # Each configuration option enables a list of files. obj-$(CONFIG_PMAC_PBOOK) += mediabay.o diff -Nru a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c --- a/drivers/macintosh/adb.c Sun Feb 9 21:13:37 2003 +++ b/drivers/macintosh/adb.c Sun Feb 9 21:13:37 2003 @@ -246,10 +246,10 @@ { strcpy(current->comm, "kadbprobe"); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigfillset(¤t->blocked); flush_signals(current); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); printk(KERN_INFO "adb: starting probe task...\n"); do_adb_reset_bus(); diff -Nru a/drivers/mca/Makefile b/drivers/mca/Makefile --- a/drivers/mca/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/mca/Makefile Sun Feb 9 21:13:32 2003 @@ -5,4 +5,3 @@ obj-$(CONFIG_MCA_PROC_FS) += mca-proc.o obj-$(CONFIG_MCA_LEGACY) += mca-legacy.o -export-objs := mca-bus.o mca-legacy.o mca-proc.o mca-driver.o diff -Nru a/drivers/md/Kconfig b/drivers/md/Kconfig --- a/drivers/md/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/md/Kconfig Sun Feb 9 21:13:29 2003 @@ -41,7 +41,7 @@ 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 linear.o. + will be called linear. If unsure, say Y. @@ -63,7 +63,7 @@ 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 raid0.o. + will be called raid0. If unsure, say Y. @@ -85,7 +85,7 @@ learn where to get the supporting user space utilities raidtools. If you want to use such a RAID-1 set, say Y. This code is also - available as a module called raid1.o ( = code which can be inserted + available as a module called raid1 ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -110,7 +110,7 @@ learn where to get the supporting user space utilities raidtools. If you want to use such a RAID-4/RAID-5 set, say Y. This code is - also available as a module called raid5.o ( = code which can be + also available as a module called raid5 ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -141,7 +141,7 @@ Higher level volume managers such as LVM2 use this driver. If you want to compile this as a module, say M here and read - . The module will be called dm-mod.o. + . The module will be called dm-mod. If unsure, say N. diff -Nru a/drivers/md/Makefile b/drivers/md/Makefile --- a/drivers/md/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/md/Makefile Sun Feb 9 21:13:32 2003 @@ -2,7 +2,6 @@ # Makefile for the kernel software RAID and LVM drivers. # -export-objs := md.o xor.o dm-table.o dm-target.o dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \ dm-ioctl.o diff -Nru a/drivers/md/md.c b/drivers/md/md.c --- a/drivers/md/md.c Sun Feb 9 21:13:30 2003 +++ b/drivers/md/md.c Sun Feb 9 21:13:30 2003 @@ -2444,9 +2444,9 @@ static inline void flush_curr_signals(void) { - spin_lock(¤t->sig->siglock); + spin_lock(¤t->sighand->siglock); flush_signals(current); - spin_unlock(¤t->sig->siglock); + spin_unlock(¤t->sighand->siglock); } int md_thread(void * arg) diff -Nru a/drivers/media/Kconfig b/drivers/media/Kconfig --- a/drivers/media/Kconfig Sun Feb 9 21:13:30 2003 +++ b/drivers/media/Kconfig Sun Feb 9 21:13:30 2003 @@ -21,7 +21,7 @@ Documentation/video4linux/API.html. Documentation for V4L2 is available on the web at http://bytesex.org/v4l/ - This driver is also available as a module called videodev.o ( = code + This driver is also available as a module called videodev ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . diff -Nru a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile --- a/drivers/media/dvb/dvb-core/Makefile Sun Feb 9 21:13:37 2003 +++ b/drivers/media/dvb/dvb-core/Makefile Sun Feb 9 21:13:37 2003 @@ -2,8 +2,6 @@ # Makefile for the kernel DVB device drivers. # -export-objs := dvb_ksyms.o - dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ dvb_frontend.o dvb_i2c.o dvb_net.o dvb_ksyms.o diff -Nru a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig --- a/drivers/media/dvb/frontends/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/media/dvb/frontends/Kconfig Sun Feb 9 21:13:29 2003 @@ -31,7 +31,7 @@ This tuner module needs some microcode located in a file called "Sc_main.mc" in the windows driver. Please pass the module parameter - mcfile="/PATH/FILENAME" when loading alps_tdlb7.o. + mcfile="/PATH/FILENAME" when loading alps_tdlb7. If you don't know what tuner module is soldered on your DVB adapter simply enable all supported frontends, the diff -Nru a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig --- a/drivers/media/radio/Kconfig Sun Feb 9 21:13:33 2003 +++ b/drivers/media/radio/Kconfig Sun Feb 9 21:13:33 2003 @@ -23,7 +23,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-cadet.o. + will be called radio-cadet. config RADIO_RTRACK tristate "AIMSlab RadioTrack (aka RadioReveal) support" @@ -51,7 +51,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-aimslab.o. + will be called radio-aimslab. config RADIO_RTRACK_PORT hex "RadioTrack i/o port (0x20f or 0x30f)" @@ -76,7 +76,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-rtrack2.o. + will be called radio-rtrack2. config RADIO_RTRACK2_PORT hex "RadioTrack II i/o port (0x20c or 0x30c)" @@ -101,7 +101,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-aztech.o. + will be called radio-aztech. config RADIO_AZTECH_PORT hex "Aztech/Packard Bell I/O port (0x350 or 0x358)" @@ -127,7 +127,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-gemtek.o. + will be called radio-gemtek. config RADIO_GEMTEK_PORT hex "GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)" @@ -153,7 +153,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-gemtek-pci.o. + will be called radio-gemtek-pci. config RADIO_MAXIRADIO tristate "Guillemot MAXI Radio FM 2000 radio" @@ -170,7 +170,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-maxiradio.o. + will be called radio-maxiradio. config RADIO_MAESTRO tristate "Maestro on board radio" @@ -187,7 +187,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-maestro.o. + will be called radio-maestro. config RADIO_MIROPCM20 tristate "miroSOUND PCM20 radio" @@ -205,7 +205,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called miropcm20.o. + will be called miropcm20. config RADIO_MIROPCM20_RDS tristate "miroSOUND PCM20 radio RDS user interface (EXPERIMENTAL)" @@ -221,7 +221,7 @@ availability of RDS is reported over V4L by the basic driver already. Here RDS can be read from files in /dev/v4l/rds. - As module the driver will be called miropcm20-rds.o. + As module the driver will be called miropcm20-rds. config RADIO_SF16FMI tristate "SF16FMI Radio" @@ -240,7 +240,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-sf16fmi.o. + will be called radio-sf16fmi. config RADIO_TERRATEC tristate "TerraTec ActiveRadio ISA Standalone" @@ -263,7 +263,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-terratec.o. + will be called radio-terratec. config RADIO_TERRATEC_PORT hex "Terratec i/o port (normally 0x590)" @@ -280,7 +280,7 @@ This is a driver for the Trust FM radio cards. Say Y if you have such a card and want to use it under Linux. - This driver is also available as a module called radio-trust.o ( = + This driver is also available as a module called radio-trust ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -308,7 +308,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-typhoon.o. + will be called radio-typhoon. config RADIO_TYPHOON_PROC_FS bool "Support for /proc/radio-typhoon" @@ -354,7 +354,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called radio-zoltrix.o. + will be called radio-zoltrix. config RADIO_ZOLTRIX_PORT hex "ZOLTRIX I/O port (0x20c or 0x30c)" diff -Nru a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile --- a/drivers/media/radio/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/media/radio/Makefile Sun Feb 9 21:13:32 2003 @@ -2,11 +2,6 @@ # Makefile for the kernel character device drivers. # -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := miropcm20-rds-core.o - miropcm20-objs := miropcm20-rds-core.o miropcm20-radio.o obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o diff -Nru a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c --- a/drivers/media/radio/radio-zoltrix.c Sun Feb 9 21:13:37 2003 +++ b/drivers/media/radio/radio-zoltrix.c Sun Feb 9 21:13:37 2003 @@ -2,7 +2,7 @@ * (c) 1998 C. van Schaik * * BUGS - * Due to the inconsistancy in reading from the signal flags + * Due to the inconsistency in reading from the signal flags * it is difficult to get an accurate tuned signal. * * It seems that the card is not linear to 0 volume. It cuts off diff -Nru a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig --- a/drivers/media/video/Kconfig Sun Feb 9 21:13:36 2003 +++ b/drivers/media/video/Kconfig Sun Feb 9 21:13:36 2003 @@ -19,7 +19,7 @@ config VIDEO_BT848 tristate "BT848 Video For Linux" - depends on VIDEO_DEV && PCI && I2C_ALGOBIT + depends on VIDEO_DEV && PCI && I2C_ALGOBIT && SOUND ---help--- Support for BT848 based frame grabber/overlay boards. This includes the Miro, Hauppauge and STB boards. Please read the material in @@ -28,7 +28,7 @@ If you say Y or M here, you need to say Y or M to "I2C support" and "I2C bit-banging interfaces" in the character device section. - This driver is available as a module called bttv.o ( = code + This driver is available as a module called bttv ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -38,7 +38,7 @@ depends on VIDEO_DEV help Say Y if you have such a thing. This driver is also available as a - module called pms.o ( = code which can be inserted in and removed + module called pms ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -52,7 +52,7 @@ Otherwise, or if you don't understand a word, say N. See for more info. - Saying M will compile this driver as a module (planb.o). + Saying M will compile this driver as a module (planb). config VIDEO_BWQCAM tristate "Quickcam BW Video For Linux" @@ -61,7 +61,7 @@ Say Y have if you the black and white version of the QuickCam camera. See the next option for the color version. - This driver is also available as a module called bw-qcam.o ( = code + This driver is also available as a module called bw-qcam ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -74,7 +74,7 @@ Connectix QuickCam. If you have one of these cameras, say Y here, otherwise say N. This driver does not work with the original monochrome QuickCam, QuickCam VC or QuickClip. It is also available - as a module (c-qcam.o). + as a module (c-qcam). Read for more information. config VIDEO_W9966 @@ -85,7 +85,7 @@ Currently tested with the LifeView FlyCam Supra. If you have one of these cameras, say Y here otherwise say N. - This driver is also available as a module (w9966.o). + This driver is also available as a module (w9966). Check out for more information. @@ -103,7 +103,7 @@ Please read for more information. - This driver is also available as a module (cpia.o). + This driver is also available as a module (cpia). config VIDEO_CPIA_PP tristate "CPiA Parallel Port Lowlevel Support" @@ -113,7 +113,7 @@ Vision's CPiA (Colour Processor Interface ASIC), such as the Creative Webcam II. If you have the parallel port version of one of these cameras, say Y here, otherwise say N. It is also available - as a module (cpia_pp.o). + as a module (cpia_pp). config VIDEO_CPIA_USB tristate "CPiA USB Lowlevel Support" @@ -123,7 +123,7 @@ (Colour Processor Interface ASIC), such as the Creative Webcam II. If you have the USB version of one of these cameras, say Y here, otherwise say N. This will not work with the Creative Webcam III. - It is also available as a module (cpia_usb.o). + It is also available as a module (cpia_usb). config VIDEO_SAA5249 tristate "SAA5249 Teletext processor" @@ -132,7 +132,7 @@ Support for I2C bus based teletext using the SAA5249 chip. At the moment this is only useful on some European WinTV cards. - This driver is also available as a module called saa5249.o ( = code + This driver is also available as a module called saa5249 ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -177,10 +177,16 @@ config VIDEO_ZORAN_DC10 tristate "Miro DC10(+) support" depends on VIDEO_ZORAN + help + Say Y to support the Pinnacle Systems Studio DC10 plus TV/Video + card. Vendor page at . config VIDEO_ZORAN_LML33 tristate "Linux Media Labs LML33 support" depends on VIDEO_ZORAN + help + Say Y here to support the Linux Media Labs LML33 TV/Video card. + Resources page is at . config VIDEO_ZR36120 tristate "Zoran ZR36120/36125 Video For Linux" @@ -191,7 +197,7 @@ and Buster boards. Please read the material in for more information. - This driver is also available as a module called zr36120.o ( = code + This driver is also available as a module called zr36120 ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -207,7 +213,7 @@ If you say Y or M here, you need to say Y or M to "Sony Programmable I/O Control Device" in the character device section. - This driver is available as a module called meye.o ( = code + This driver is available as a module called meye ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -219,7 +225,7 @@ This is a video4linux driver for Philips SAA7130/7134 based TV cards. - This driver is available as a module called saa7134.o ( = code + This driver is available as a module called saa7134 ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . diff -Nru a/drivers/media/video/Makefile b/drivers/media/video/Makefile --- a/drivers/media/video/Makefile Sun Feb 9 21:13:31 2003 +++ b/drivers/media/video/Makefile Sun Feb 9 21:13:31 2003 @@ -2,12 +2,6 @@ # Makefile for the video capture/playback device drivers. # -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := videodev.o v4l2-common.o v4l1-compat.o \ - bttv-if.o cpia.o video-buf.o - bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ bttv-risc.o bttv-vbi.o zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o diff -Nru a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c --- a/drivers/media/video/bt819.c Sun Feb 9 21:13:29 2003 +++ b/drivers/media/video/bt819.c Sun Feb 9 21:13:29 2003 @@ -48,18 +48,8 @@ static unsigned short normal_i2c[] = {34>>1, I2C_CLIENT_END }; static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; -static unsigned short probe[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; -static unsigned short probe_range[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; -static unsigned short ignore[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; -static unsigned short ignore_range[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; -static unsigned force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; - -static struct i2c_client_address_data addr_data = { - normal_i2c , normal_i2c_range, - probe , probe_range, - ignore , ignore_range, - force -}; + +I2C_CLIENT_INSMOD; static struct i2c_client client_template; @@ -100,10 +90,6 @@ /* ----------------------------------------------------------------------- */ -static int bt819_probe(struct i2c_adapter *adap) -{ - return i2c_probe(adap, &addr_data, bt819_attach); -} static int bt819_setbit(struct bt819 *dev, int subaddr, int bit, int data) { @@ -211,6 +197,10 @@ MOD_INC_USE_COUNT; return 0; } +static int bt819_probe(struct i2c_adapter *adap) +{ + return i2c_probe(adap, &addr_data, bt819_attach); +} static int bt819_detach(struct i2c_client *client) { @@ -448,21 +438,19 @@ /* ----------------------------------------------------------------------- */ static struct i2c_driver i2c_driver_bt819 = { - "bt819", /* name */ - I2C_DRIVERID_BT819, /* ID */ - I2C_DF_NOTIFY, - bt819_probe, - bt819_detach, - bt819_command + .name = "bt819", /* name */ + .id = I2C_DRIVERID_BT819, /* ID */ + .flags = I2C_DF_NOTIFY, + .attach_adapter = bt819_probe, + .detach_client = bt819_detach, + .command = bt819_command + }; static struct i2c_client client_template = { - "bt819_client", - -1, - 0, - 0, - NULL, - &i2c_driver_bt819 + .name = "bt819_client", + .id = -1, + .driver = &i2c_driver_bt819 }; static int bt819_setup(void) diff -Nru a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c --- a/drivers/media/video/bt856.c Sun Feb 9 21:13:28 2003 +++ b/drivers/media/video/bt856.c Sun Feb 9 21:13:28 2003 @@ -82,6 +82,7 @@ int contrast; int hue; int sat; + struct semaphore lock; }; #define I2C_BT856 0x88 @@ -90,11 +91,6 @@ /* ----------------------------------------------------------------------- */ -static int bt856_probe(struct i2c_adapter *adap) -{ - return i2c_probe(adap, &addr_data , bt856_attach); -} - static int bt856_setbit(struct bt856 *dev, int subaddr, int bit, int data) { return i2c_smbus_write_byte_data(dev->client, subaddr,(dev->reg[subaddr] & ~(1 << bit)) | (data ? (1 << bit) : 0)); @@ -134,7 +130,7 @@ encoder->norm = VIDEO_MODE_NTSC; encoder->enable = 1; - DEBUG(printk(KERN_INFO "%s-bt856: attach\n", encoder->bus->name)); + DEBUG(printk(KERN_INFO "%s-bt856: attach\n", encoder->client->name)); i2c_smbus_write_byte_data(client, 0xdc, 0x18); encoder->reg[0xdc] = 0x18; @@ -167,6 +163,10 @@ return 0; } +static int bt856_probe(struct i2c_adapter *adap) +{ + return i2c_probe(adap, &addr_data , bt856_attach); +} static int bt856_detach(struct i2c_client *client) { @@ -299,21 +299,19 @@ /* ----------------------------------------------------------------------- */ static struct i2c_driver i2c_driver_bt856 = { - "bt856", /* name */ - I2C_DRIVERID_BT856, /* ID */ - I2C_DF_NOTIFY, - bt856_probe, - bt856_detach, - bt856_command + .owner = THIS_MODULE, + .name = "bt856", /* name */ + .id = I2C_DRIVERID_BT856, /* ID */ + .flags = I2C_DF_NOTIFY, + .attach_adapter = bt856_probe, + .detach_client = bt856_detach, + .command = bt856_command }; static struct i2c_client client_template = { - "bt856_client", - -1, - 0, - 0, - NULL, - &i2c_driver_bt856 + .name = "bt856_client", + .id = -1, + .driver = &i2c_driver_bt856 }; static int bt856_init(void) diff -Nru a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c --- a/drivers/media/video/bttv-driver.c Sun Feb 9 21:13:34 2003 +++ b/drivers/media/video/bttv-driver.c Sun Feb 9 21:13:34 2003 @@ -247,7 +247,7 @@ },{ .v4l2_id = V4L2_STD_PAL_N, .name = "PAL-N", - .Fsc 35468950, + .Fsc = 35468950, .swidth = 768, .sheight = 576, .totalwidth = 1135, diff -Nru a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c --- a/drivers/media/video/saa5249.c Sun Feb 9 21:13:34 2003 +++ b/drivers/media/video/saa5249.c Sun Feb 9 21:13:34 2003 @@ -280,17 +280,17 @@ { sigset_t oldblocked = current->blocked; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigfillset(¤t->blocked); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule_timeout(delay); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = oldblocked; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } diff -Nru a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c --- a/drivers/media/video/saa7185.c Sun Feb 9 21:13:28 2003 +++ b/drivers/media/video/saa7185.c Sun Feb 9 21:13:28 2003 @@ -186,7 +186,7 @@ { int i; struct saa7185 *encoder; - struct i2c_client client; + struct i2c_client *client; client = kmalloc(sizeof(*client), GFP_KERNEL); if (client == NULL) @@ -194,14 +194,14 @@ client_template.adapter = adap; client_template.addr = addr; memcpy(client, &client_template, sizeof(*client)); - encoder = kmalloc(sizeof(*decoder), GFP_KERNEL); + encoder = kmalloc(sizeof(*encoder), GFP_KERNEL); if (encoder == NULL) { kfree(client); return -ENOMEM; } - memset(encoder, 0, sizeof(*decoder)); + memset(encoder, 0, sizeof(*encoder)); strcpy(client->name, "saa7185"); encoder->client = client; client->data = encoder; @@ -221,7 +221,7 @@ printk(KERN_INFO "%s_attach: chip version %d\n", client->name, i2c_smbus_read_byte(client) >> 5); } - init_MUTEX(&decoder->lock); + init_MUTEX(&encoder->lock); i2c_attach_client(client); MOD_INC_USE_COUNT; return 0; @@ -355,6 +355,7 @@ /* ----------------------------------------------------------------------- */ static struct i2c_driver i2c_driver_saa7185 = { + .owner = THIS_MODULE, .name = "saa7185", /* name */ .id = I2C_DRIVERID_SAA7185B, /* ID */ .flags = I2C_DF_NOTIFY, diff -Nru a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c --- a/drivers/media/video/stradis.c Sun Feb 9 21:13:36 2003 +++ b/drivers/media/video/stradis.c Sun Feb 9 21:13:36 2003 @@ -241,12 +241,6 @@ } } -static void detach_inform(struct saa7146 *saa, int id) -{ - int i; - i = saa->nr; -} - static void I2CBusScan(struct saa7146 *saa) { int i; @@ -1323,9 +1317,12 @@ clip_draw_rectangle(clipmap, 0, 0, 1024, -(saa->win.y)); } -static int saa_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +static int saa_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long argl) { - struct saa7146 *saa = (struct saa7146 *) dev; + struct saa7146 *saa = file->private_data; + void *arg = (void *)argl; + switch (cmd) { case VIDIOCGCAP: { @@ -1809,24 +1806,23 @@ return 0; } -static int saa_mmap(struct video_device *dev, const char *adr, - unsigned long size) +static int saa_mmap(struct file *file, struct vm_area_struct *vma) { - struct saa7146 *saa = (struct saa7146 *) dev; + struct saa7146 *saa = file->private_data; printk(KERN_DEBUG "stradis%d: saa_mmap called\n", saa->nr); return -EINVAL; } -static long saa_read(struct video_device *dev, char *buf, - unsigned long count, int nonblock) +static ssize_t saa_read(struct file *file, char *buf, + size_t count, loff_t *ppos) { return -EINVAL; } -static long saa_write(struct video_device *dev, const char *buf, - unsigned long count, int nonblock) +static ssize_t saa_write(struct file *file, const char *buf, + size_t count, loff_t *ppos) { - struct saa7146 *saa = (struct saa7146 *) dev; + struct saa7146 *saa = file->private_data; unsigned long todo = count; int blocksize, split; unsigned long flags; @@ -1945,11 +1941,23 @@ return count; } -static int saa_open(struct video_device *dev, int flags) +static int saa_open(struct inode *inode, struct file *file) { - struct saa7146 *saa = (struct saa7146 *) dev; + struct saa7146 *saa = NULL; + unsigned int minor = minor(inode->i_rdev); + int i; + + for (i = 0; i < SAA7146_MAX; i++) { + if (saa7146s[i].video_dev.minor == minor) { + saa = &saa7146s[i]; + } + } + if (saa == NULL) { + return -ENODEV; + } + file->private_data = saa; - saa->video_dev.busy = 0; + //saa->video_dev.busy = 0; /* old hack to support multiple open */ saa->user++; if (saa->user > 1) return 0; /* device open already, don't reset */ @@ -1957,29 +1965,37 @@ return 0; } -static void saa_close(struct video_device *dev) +static int saa_release(struct inode *inode, struct file *file) { - struct saa7146 *saa = (struct saa7146 *) dev; + struct saa7146 *saa = file->private_data; saa->user--; - saa->video_dev.busy = 0; + //saa->video_dev.busy = 0; /* old hack to support multiple open */ if (saa->user > 0) /* still someone using device */ - return; + return 0; saawrite(0x007f0000, SAA7146_MC1); /* stop all overlay dma */ + return 0; } -/* template for video_device-structure */ -static struct video_device saa_template = +static struct file_operations saa_fops = { .owner = THIS_MODULE, - .name = "SAA7146A", - .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY, - .hardware = VID_HARDWARE_SAA7146, .open = saa_open, - .close = saa_close, + .release = saa_release, + .ioctl = saa_ioctl, .read = saa_read, + .llseek = no_llseek, .write = saa_write, - .ioctl = saa_ioctl, .mmap = saa_mmap, +}; + +/* template for video_device-structure */ +static struct video_device saa_template = +{ + .name = "SAA7146A", + .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY, + .hardware = VID_HARDWARE_SAA7146, + .fops = &saa_fops, + .minor = -1, }; static int configure_saa7146(struct pci_dev *dev, int num) diff -Nru a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c --- a/drivers/media/video/zr36120.c Sun Feb 9 21:13:32 2003 +++ b/drivers/media/video/zr36120.c Sun Feb 9 21:13:32 2003 @@ -86,7 +86,7 @@ * 0x28 and 0x2C. How you do that is left as an exercise * to the impatient reader :) */ -#define T 1 /* to seperate the bools from the ints */ +#define T 1 /* to separate the bools from the ints */ #define F 0 static struct tvcard tvcards[] = { /* reported working by */ diff -Nru a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig --- a/drivers/message/fusion/Kconfig Sun Feb 9 21:13:37 2003 +++ b/drivers/message/fusion/Kconfig Sun Feb 9 21:13:37 2003 @@ -21,10 +21,10 @@ If you have Fusion MPT hardware and want to use it, you can say Y or M here to add MPT (base + ScsiHost) drivers. - = build lib (fusion.o), and link [static] into the kernel [2] + = build lib (fusion), and link [static] into the kernel [2] proper - = compiled as [dynamic] modules [3] named: (mptbase.o, - mptscsih.o) + = compiled as [dynamic] modules [3] named: (mptbase, + mptscsih) [2] In order enable capability to boot the linux kernel natively from a Fusion MPT target device, you MUST @@ -39,9 +39,9 @@ If you say Y or M here you will get a choice of these additional protocol and support module options: Module Name: - Enhanced SCSI error reporting (isense.o) - Fusion MPT misc device (ioctl) driver (mptctl.o) - Fusion MPT LAN driver (mptlan.o) + Enhanced SCSI error reporting (isense) + Fusion MPT misc device (ioctl) driver (mptctl) + Fusion MPT LAN driver (mptlan) --- Fusion MPT is trademark of LSI Logic Corporation, and its @@ -95,7 +95,7 @@ ASC/ASCQ=29h/00h "LOGICAL UNIT NOT READY, INITIALIZING CMD. REQUIRED" Say M for "Enhanced SCSI error reporting" to compile this optional module, - creating a driver named: isense.o. + creating a driver named: isense. NOTE: Support for building this feature into the kernel is not available, due to kernel size considerations. @@ -114,7 +114,7 @@ of the MPT adapter firmware. Refer to readme file(s) distributed with the Fusion MPT linux driver for additional details. - If enabled by saying M to this, a driver named: mptctl.o + If enabled by saying M to this, a driver named: mptctl will be compiled. If unsure whether you really want or need this, say N. @@ -131,7 +131,7 @@ Installing this driver requires the knowledge to configure and activate a new network interface, "fc0", using standard Linux tools. - If enabled by saying M to this, a driver named: mptlan.o + If enabled by saying M to this, a driver named: mptlan will be compiled. If unsure whether you really want or need this, say N. diff -Nru a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile --- a/drivers/message/fusion/Makefile Sun Feb 9 21:13:33 2003 +++ b/drivers/message/fusion/Makefile Sun Feb 9 21:13:33 2003 @@ -46,8 +46,6 @@ #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC -export-objs := mptbase.o mptscsih.o mptlan.o mptctl.o isense.o - obj-$(CONFIG_FUSION) += mptbase.o mptscsih.o obj-$(CONFIG_FUSION_ISENSE) += isense.o obj-$(CONFIG_FUSION_CTL) += mptctl.o diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c --- a/drivers/message/fusion/mptscsih.c Sun Feb 9 21:13:31 2003 +++ b/drivers/message/fusion/mptscsih.c Sun Feb 9 21:13:31 2003 @@ -775,7 +775,7 @@ if (dlen >= SCSI_STD_INQUIRY_BYTES) { mptscsih_initTarget(hd, hd->port, - sc->target, + sc->device->id, pScsiReq->LUN[1], sc->buffer, dlen); @@ -845,7 +845,7 @@ /* GEM Workaround. */ if (hd->is_spi) - mptscsih_no_negotiate(hd, sc->target); + mptscsih_no_negotiate(hd, sc->device->id); break; case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ @@ -857,7 +857,7 @@ /* GEM Workaround. */ if (hd->is_spi) - mptscsih_no_negotiate(hd, sc->target); + mptscsih_no_negotiate(hd, sc->device->id); break; case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ @@ -916,7 +916,7 @@ ) { mptscsih_initTarget(hd, hd->port, - sc->target, + sc->device->id, pScsiReq->LUN[1], sc->buffer, xfer_cnt); @@ -1000,7 +1000,7 @@ ) { mptscsih_initTarget(hd, hd->port, - sc->target, + sc->device->id, pScsiReq->LUN[1], sc->buffer, xfer_cnt); @@ -1594,10 +1594,10 @@ if (time - last_queue_full > 10 * HZ) { char *ioc_str = "ioc?"; - if (sc->host != NULL && sc->host->hostdata != NULL) - ioc_str = ((MPT_SCSI_HOST *)sc->host->hostdata)->ioc->name; + if (sc->device && sc->device->host != NULL && sc->device->host->hostdata != NULL) + ioc_str = ((MPT_SCSI_HOST *)sc->device->host->hostdata)->ioc->name; printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n", - ioc_str, 0, sc->target, sc->lun); + ioc_str, 0, sc->device->id, sc->device->lun); last_queue_full = time; } } @@ -2576,9 +2576,9 @@ int issueCmd; did_errcode = 0; - hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata; - target = SCpnt->target; - lun = SCpnt->lun; + hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; + target = SCpnt->device->id; + lun = SCpnt->device->lun; SCpnt->scsi_done = done; pTarget = hd->Targets[target]; @@ -3159,7 +3159,7 @@ /* If we can't locate our host adapter structure, return FAILED status. */ - if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL) { + if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) { SCpnt->result = DID_RESET << 16; SCpnt->scsi_done(SCpnt); nehprintk((KERN_WARNING MYNAM ": mptscsih_abort: " @@ -3227,7 +3227,7 @@ hd->abortSCpnt = SCpnt; if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, - SCpnt->target, SCpnt->lun, ctx2abort, NO_SLEEP) + SCpnt->device->id, SCpnt->device->lun, ctx2abort, NO_SLEEP) < 0) { /* The TM request failed and the subsequent FW-reload failed! @@ -3263,7 +3263,7 @@ /* If we can't locate our host adapter structure, return FAILED status. */ - if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL){ + if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ nehprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: " "Can't locate host! (sc=%p)\n", SCpnt)); @@ -3292,7 +3292,7 @@ } if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, - SCpnt->target, 0, 0, NO_SLEEP) + SCpnt->device->id, 0, 0, NO_SLEEP) < 0){ /* The TM request failed and the subsequent FW-reload failed! * Fatal error case. @@ -3323,7 +3323,7 @@ /* If we can't locate our host adapter structure, return FAILED status. */ - if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL){ + if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ nehprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: " "Can't locate host! (sc=%p)\n", SCpnt ) ); @@ -3385,7 +3385,7 @@ int status = SUCCESS; /* If we can't locate the host to reset, then we failed. */ - if ((hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata) == NULL){ + if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ nehprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: " "Can't locate host! (sc=%p)\n", SCpnt ) ); @@ -4237,7 +4237,7 @@ pReq->LUN[1], target->dev_vol_name); else - sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->target, sc->lun); + sprintf(devFoo, "%d:%d:%d", hd->ioc->id, sc->device->id, sc->device->lun); thisIo.DevIDStr = devFoo; /* fubar */ thisIo.dataPtr = NULL; @@ -4261,7 +4261,7 @@ MPT_SCSI_HOST *hd; int i; - hd = (MPT_SCSI_HOST *) sc->host->hostdata; + hd = (MPT_SCSI_HOST *) sc->device->host->hostdata; for (i = 0; i < hd->ioc->req_depth; i++) { if (hd->ScsiLookup[i] == sc) { diff -Nru a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig --- a/drivers/message/i2o/Kconfig Sun Feb 9 21:13:28 2003 +++ b/drivers/message/i2o/Kconfig Sun Feb 9 21:13:28 2003 @@ -22,7 +22,7 @@ inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . You will get modules called - i2o_core.o and i2o_config.o. + i2o_core and i2o_config. If unsure, say N. @@ -33,7 +33,7 @@ Say Y for support of PCI bus I2O interface adapters. Currently this is the only variety supported, so you should say Y. - This support is also available as a module called i2o_pci.o ( = code + This support is also available as a module called i2o_pci ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -45,7 +45,7 @@ Include support for the I2O Block OSM. The Block OSM presents disk and other structured block devices to the operating system. - This support is also available as a module called i2o_block.o ( = + This support is also available as a module called i2o_block ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -58,7 +58,7 @@ support for token ring or FDDI if you wish to use token ring or FDDI I2O cards with this driver. - This support is also available as a module called i2o_lan.o ( = code + This support is also available as a module called i2o_lan ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -71,7 +71,7 @@ I2O controller. You can use both the SCSI and Block OSM together if you wish. - This support is also available as a module called i2o_scsi.o ( = + This support is also available as a module called i2o_scsi ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -84,7 +84,7 @@ able to read I2O related information from the virtual directory /proc/i2o. - This support is also available as a module called i2o_proc.o ( = + This support is also available as a module called i2o_proc ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . diff -Nru a/drivers/message/i2o/Makefile b/drivers/message/i2o/Makefile --- a/drivers/message/i2o/Makefile Sun Feb 9 21:13:34 2003 +++ b/drivers/message/i2o/Makefile Sun Feb 9 21:13:34 2003 @@ -5,8 +5,6 @@ # In the future, some of these should be built conditionally. # -export-objs := i2o_core.o - obj-$(CONFIG_I2O_PCI) += i2o_pci.o obj-$(CONFIG_I2O) += i2o_core.o i2o_config.o obj-$(CONFIG_I2O_BLOCK) += i2o_block.o diff -Nru a/drivers/mtd/Makefile b/drivers/mtd/Makefile --- a/drivers/mtd/Makefile Sun Feb 9 21:13:31 2003 +++ b/drivers/mtd/Makefile Sun Feb 9 21:13:31 2003 @@ -4,8 +4,6 @@ # Based on: # $Id: Makefile,v 1.66 2002/04/23 13:52:14 mag Exp $ -export-objs := mtdcore.o mtdpart.o redboot.o cmdline.o afs.o mtdconcat.o - obj-y += chips/ maps/ devices/ nand/ # *** BIG UGLY NOTE *** diff -Nru a/drivers/mtd/chips/Makefile b/drivers/mtd/chips/Makefile --- a/drivers/mtd/chips/Makefile Sun Feb 9 21:13:30 2003 +++ b/drivers/mtd/chips/Makefile Sun Feb 9 21:13:30 2003 @@ -3,8 +3,6 @@ # # $Id: Makefile,v 1.7 2001/10/05 06:53:51 dwmw2 Exp $ -export-objs := chipreg.o gen_probe.o - # *** BIG UGLY NOTE *** # # The removal of get_module_symbol() and replacement with diff -Nru a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c --- a/drivers/mtd/chips/jedec.c Sun Feb 9 21:13:33 2003 +++ b/drivers/mtd/chips/jedec.c Sun Feb 9 21:13:33 2003 @@ -608,7 +608,7 @@ /* Poll the flash for erasure completion, specs say this can take as long as 480 seconds to do all the sectors (for a 2 meg flash). - Erasure time is dependant on chip age, temp and wear.. */ + Erasure time is dependent on chip age, temp and wear.. */ /* This being a generic routine assumes a 32 bit bus. It does read32s and bundles interleved chips into the same grouping. This will work diff -Nru a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c --- a/drivers/mtd/devices/blkmtd.c Sun Feb 9 21:13:28 2003 +++ b/drivers/mtd/devices/blkmtd.c Sun Feb 9 21:13:28 2003 @@ -305,10 +305,10 @@ DEBUG(1, "blkmtd: writetask: starting (pid = %d)\n", tsk->pid); daemonize(); strcpy(tsk->comm, "blkmtdd"); - spin_lock_irq(&tsk->sig->siglock); + spin_lock_irq(&tsk->sighand->siglock); sigfillset(&tsk->blocked); recalc_sigpending(); - spin_unlock_irq(&tsk->sig->siglock); + spin_unlock_irq(&tsk->sighand->siglock); if(alloc_kiovec(1, &iobuf)) { printk("blkmtd: write_queue_task cant allocate kiobuf\n"); diff -Nru a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c --- a/drivers/mtd/ftl.c Sun Feb 9 21:13:35 2003 +++ b/drivers/mtd/ftl.c Sun Feb 9 21:13:35 2003 @@ -841,7 +841,7 @@ return -EROFS; } - DEBUG(0, "ftl_cs: ftl_open(%s)\n", inode->i_bdev->b_disk->disk_name); + DEBUG(0, "ftl_cs: ftl_open(%s)\n", inode->i_bdev->bd_disk->disk_name); atomic_inc(&partition->open); @@ -855,7 +855,7 @@ partition_t *part = inode->i_bdev->bd_disk->private_data; int i; - DEBUG(0, "ftl_cs: ftl_close(%s)\n", inode->i_bdev->b_disk->disk_name); + DEBUG(0, "ftl_cs: ftl_close(%s)\n", inode->i_bdev->bd_disk->disk_name); /* Wait for any pending erase operations to complete */ if (part->mtd->sync) diff -Nru a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig --- a/drivers/mtd/maps/Kconfig Sun Feb 9 21:13:36 2003 +++ b/drivers/mtd/maps/Kconfig Sun Feb 9 21:13:36 2003 @@ -137,7 +137,7 @@ If you don't know what to do here, say N. - If compiled as a module, it will be called scx200_docflash.o. + If compiled as a module, it will be called scx200_docflash. config MTD_L440GX tristate "BIOS flash chip on Intel L440GX boards" diff -Nru a/drivers/mtd/maps/elan-104nc.c b/drivers/mtd/maps/elan-104nc.c --- a/drivers/mtd/maps/elan-104nc.c Sun Feb 9 21:13:32 2003 +++ b/drivers/mtd/maps/elan-104nc.c Sun Feb 9 21:13:32 2003 @@ -27,7 +27,7 @@ 16 bit I/O port (0x22) for some sort of paging. -The single flash device is divided into 3 partition which appear as seperate +The single flash device is divided into 3 partition which appear as separate MTD devices. Linux thinks that the I/O port is used by the PIC and hence check_region() will diff -Nru a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c --- a/drivers/mtd/maps/sa1100-flash.c Sun Feb 9 21:13:30 2003 +++ b/drivers/mtd/maps/sa1100-flash.c Sun Feb 9 21:13:30 2003 @@ -512,6 +512,37 @@ #define h3xxx_set_vpp NULL #endif +#ifdef CONFIG_SA1100_HACKKIT +static struct mtd_partition hackkit_partitions[] = { + { + .name = "BLOB", + .size = 0x00040000, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, { + .name = "config", + .size = 0x00040000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "kernel", + .size = 0x00100000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "initrd", + .size = 0x00180000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "rootfs", + .size = 0x700000, + .offset = MTDPART_OFS_APPEND, + }, { + .name = "data", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; +#endif + #ifdef CONFIG_SA1100_HUW_WEBPANEL static struct mtd_partition huw_webpanel_partitions[] = { { @@ -847,6 +878,12 @@ if (machine_is_h3xxx()) { *parts = h3xxx_partitions; nb_parts = ARRAY_SIZE(h3xxx_partitions); + } +#endif +#ifdef CONFIG_SA1100_HACKKIT + if (machine_is_hackkit()) { + *parts = hackkit_partitions; + nb_parts = ARRAY_SIZE(hackkit_partitions); } #endif #ifdef CONFIG_SA1100_HUW_WEBPANEL diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c --- a/drivers/mtd/mtdblock.c Sun Feb 9 21:13:31 2003 +++ b/drivers/mtd/mtdblock.c Sun Feb 9 21:13:31 2003 @@ -453,10 +453,10 @@ /* we might get involved when memory gets low, so use PF_MEMALLOC */ tsk->flags |= PF_MEMALLOC; strcpy(tsk->comm, "mtdblockd"); - spin_lock_irq(&tsk->sig->siglock); + spin_lock_irq(&tsk->sighand->siglock); sigfillset(&tsk->blocked); recalc_sigpending(); - spin_unlock_irq(&tsk->sig->siglock); + spin_unlock_irq(&tsk->sighand->siglock); daemonize(); while (!leaving) { diff -Nru a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile --- a/drivers/mtd/nand/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/mtd/nand/Makefile Sun Feb 9 21:13:28 2003 @@ -3,8 +3,6 @@ # # $Id: Makefile,v 1.5 2001/09/19 22:39:59 dwmw2 Exp $ -export-objs := nand.o nand_ecc.o - nandobjs-y := nand.o nandobjs-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c --- a/drivers/net/3c509.c Sun Feb 9 21:13:28 2003 +++ b/drivers/net/3c509.c Sun Feb 9 21:13:28 2003 @@ -103,6 +103,10 @@ static int el3_debug = 2; #endif +/* Used to do a global count of all the cards in the system. Must be + * a global variable so that the mca/eisa probe routines can increment + * it */ +static int el3_cards = 0; /* To minimize the size of the driver source I only define operating constants if they are used several times. You'll need the manual @@ -167,16 +171,15 @@ /* skb send-queue */ int head, size; struct sk_buff *queue[SKB_QUEUE_SIZE]; - char mca_slot; #ifdef CONFIG_PM struct pm_dev *pmdev; #endif -#ifdef __ISAPNP__ - struct pnp_dev *pnpdev; -#endif -#ifdef CONFIG_EISA - struct eisa_device *edev; -#endif + enum { + EL3_MCA, + EL3_PNP, + EL3_EISA, + } type; /* type of device */ + struct device *dev; }; static int id_port __initdata = 0x110; /* Start with 0x110 to avoid new sound cards.*/ static struct net_device *el3_root_dev; @@ -200,6 +203,8 @@ static int el3_resume(struct pm_dev *pdev); static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data); #endif +/* generic device remove for all device types */ +static int el3_device_remove (struct device *device); #ifdef CONFIG_EISA struct eisa_device_id el3_eisa_ids[] = { @@ -209,31 +214,46 @@ }; static int el3_eisa_probe (struct device *device); -static int el3_eisa_remove (struct device *device); struct eisa_driver el3_eisa_driver = { .id_table = el3_eisa_ids, .driver = { .name = "3c509", .probe = el3_eisa_probe, - .remove = __devexit_p (el3_eisa_remove) + .remove = __devexit_p (el3_device_remove) } }; #endif #ifdef CONFIG_MCA -struct el3_mca_adapters_struct { - char* name; - int id; +static int el3_mca_probe(struct device *dev); + +static short el3_mca_adapter_ids[] __initdata = { + 0x627c, + 0x627d, + 0x62db, + 0x62f6, + 0x62f7, + 0x0000 +}; + +static char *el3_mca_adapter_names[] __initdata = { + "3Com 3c529 EtherLink III (10base2)", + "3Com 3c529 EtherLink III (10baseT)", + "3Com 3c529 EtherLink III (test mode)", + "3Com 3c529 EtherLink III (TP or coax)", + "3Com 3c529 EtherLink III (TP)", + NULL }; -static struct el3_mca_adapters_struct el3_mca_adapters[] __initdata = { - { "3Com 3c529 EtherLink III (10base2)", 0x627c }, - { "3Com 3c529 EtherLink III (10baseT)", 0x627d }, - { "3Com 3c529 EtherLink III (test mode)", 0x62db }, - { "3Com 3c529 EtherLink III (TP or coax)", 0x62f6 }, - { "3Com 3c529 EtherLink III (TP)", 0x62f7 }, - { NULL, 0 }, +static struct mca_driver el3_mca_driver = { + .id_table = el3_mca_adapter_ids, + .driver = { + .name = "3c529", + .bus = &mca_bus_type, + .probe = el3_mca_probe, + .remove = __devexit_p(el3_device_remove), + }, }; #endif /* CONFIG_MCA */ @@ -264,12 +284,12 @@ }; static u16 el3_isapnp_phys_addr[8][3]; -#endif /* __ISAPNP__ */ static int nopnp; +#endif /* __ISAPNP__ */ /* With the driver model introduction for EISA devices, both init * and cleanup have been split : - * - EISA devices probe/remove starts in el3_eisa_probe/el3_eisa_remove + * - EISA devices probe/remove starts in el3_eisa_probe/el3_device_remove * - MCA/ISA still use el3_probe * * Both call el3_common_init/el3_common_remove. */ @@ -278,10 +298,9 @@ { struct el3_private *lp = dev->priv; short i; - -#ifdef CONFIG_EISA - if (!lp->edev) /* EISA devices are not chained */ -#endif + + el3_cards++; + if (!lp->dev) /* probed devices are not chained */ { lp->next_dev = el3_root_dev; el3_root_dev = dev; @@ -337,17 +356,13 @@ struct el3_private *lp = dev->priv; (void) lp; /* Keep gcc quiet... */ -#ifdef CONFIG_MCA - if(lp->mca_slot!=-1) - mca_mark_as_unused(lp->mca_slot); -#endif #ifdef CONFIG_PM if (lp->pmdev) pm_unregister(lp->pmdev); #endif #ifdef __ISAPNP__ - if (lp->pnpdev) - pnp_device_detach(lp->pnpdev); + if (lp->type == EL3_PNP) + pnp_device_detach(to_pnp_dev(lp->dev)); #endif unregister_netdev (dev); @@ -363,76 +378,11 @@ int ioaddr, irq, if_port; u16 phys_addr[3]; static int current_tag; - int mca_slot = -1; #ifdef __ISAPNP__ static int pnp_cards; struct pnp_dev *idev = NULL; #endif /* __ISAPNP__ */ -#ifdef CONFIG_MCA - /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, heavily - * modified by Chris Beauregard (cpbeaure@csclub.uwaterloo.ca) - * to support standard MCA probing. - * - * redone for multi-card detection by ZP Gu (zpg@castle.net) - * now works as a module - */ - - if( MCA_bus ) { - int slot, j; - u_char pos4, pos5; - - for( j = 0; el3_mca_adapters[j].name != NULL; j ++ ) { - slot = 0; - while( slot != MCA_NOTFOUND ) { - slot = mca_find_unused_adapter( - el3_mca_adapters[j].id, slot ); - if( slot == MCA_NOTFOUND ) break; - - /* if we get this far, an adapter has been - * detected and is enabled - */ - - pos4 = mca_read_stored_pos( slot, 4 ); - pos5 = mca_read_stored_pos( slot, 5 ); - - ioaddr = ((short)((pos4&0xfc)|0x02)) << 8; - irq = pos5 & 0x0f; - - /* probing for a card at a particular IO/IRQ */ - if(dev && ((dev->irq >= 1 && dev->irq != irq) || - (dev->base_addr >= 1 && dev->base_addr != ioaddr))) { - slot++; /* probing next slot */ - continue; - } - - printk("3c509: found %s at slot %d\n", - el3_mca_adapters[j].name, slot + 1 ); - - /* claim the slot */ - mca_set_adapter_name(slot, el3_mca_adapters[j].name); - mca_set_adapter_procfn(slot, NULL, NULL); - mca_mark_as_used(slot); - - if_port = pos4 & 0x03; - if (el3_debug > 2) { - printk("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port); - } - EL3WINDOW(0); - for (i = 0; i < 3; i++) { - phys_addr[i] = htons(read_eeprom(ioaddr, i)); - } - - mca_slot = slot; - - goto found; - } - } - /* if we get here, we didn't find an MCA adapter */ - return -ENODEV; - } -#endif /* CONFIG_MCA */ - #ifdef __ISAPNP__ if (nopnp == 1) goto no_pnp; @@ -580,7 +530,7 @@ /* Free the interrupt so that some other card can use it. */ outw(0x0f00, ioaddr + WN0_IRQ); - found: + dev = init_etherdev(NULL, sizeof(struct el3_private)); if (dev == NULL) { release_region(ioaddr, EL3_IO_EXTENT); @@ -594,13 +544,80 @@ dev->if_port = if_port; lp = dev->priv; #ifdef __ISAPNP__ - lp->pnpdev = idev; + lp->dev = &idev->dev; #endif - lp->mca_slot = mca_slot; return el3_common_init (dev); } +#ifdef CONFIG_MCA +static int __init el3_mca_probe(struct device *device) { + /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, + * heavily modified by Chris Beauregard + * (cpbeaure@csclub.uwaterloo.ca) to support standard MCA + * probing. + * + * redone for multi-card detection by ZP Gu (zpg@castle.net) + * now works as a module */ + + struct el3_private *lp; + short i; + int ioaddr, irq, if_port; + u16 phys_addr[3]; + struct net_device *dev = NULL; + u_char pos4, pos5; + struct mca_device *mdev = to_mca_device(device); + int slot = mdev->slot; + + pos4 = mca_device_read_stored_pos(mdev, 4); + pos5 = mca_device_read_stored_pos(mdev, 5); + + ioaddr = ((short)((pos4&0xfc)|0x02)) << 8; + irq = pos5 & 0x0f; + + + printk("3c529: found %s at slot %d\n", + el3_mca_adapter_names[mdev->index], slot + 1); + + /* claim the slot */ + strncpy(device->name, el3_mca_adapter_names[mdev->index], + sizeof(device->name)); + mca_device_set_claim(mdev, 1); + + if_port = pos4 & 0x03; + + irq = mca_device_transform_irq(mdev, irq); + ioaddr = mca_device_transform_ioport(mdev, ioaddr); + if (el3_debug > 2) { + printk("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port); + } + EL3WINDOW(0); + for (i = 0; i < 3; i++) { + phys_addr[i] = htons(read_eeprom(ioaddr, i)); + } + + dev = init_etherdev(NULL, sizeof(struct el3_private)); + if (dev == NULL) { + release_region(ioaddr, EL3_IO_EXTENT); + return -ENOMEM; + } + + SET_MODULE_OWNER(dev); + + memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr)); + dev->base_addr = ioaddr; + dev->irq = irq; + dev->if_port = if_port; + lp = dev->priv; + lp->dev = device; + lp->type = EL3_MCA; + device->driver_data = dev; + + return el3_common_init (dev); +} + +#endif /* CONFIG_MCA */ + #ifdef CONFIG_EISA static int __init el3_eisa_probe (struct device *device) { @@ -642,25 +659,26 @@ dev->irq = irq; dev->if_port = if_port; lp = dev->priv; - lp->mca_slot = -1; - lp->edev = edev; + lp->dev = device; + lp->type = EL3_EISA; eisa_set_drvdata (edev, dev); return el3_common_init (dev); } +#endif -static int __devexit el3_eisa_remove (struct device *device) +/* This remove works for all device types. + * + * The net dev must be stored in the driver_data field */ +static int __devexit el3_device_remove (struct device *device) { - struct eisa_device *edev; struct net_device *dev; - edev = to_eisa_device (device); - dev = eisa_get_drvdata (edev); + dev = device->driver_data; 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. @@ -1080,7 +1098,7 @@ free_irq(dev->irq, dev); /* Switching back to window 0 disables the IRQ. */ EL3WINDOW(0); - if (!lp->edev) { + if (lp->type != EL3_EISA) { /* But we explicitly zero the IRQ line select anyway. Don't do * it on EISA cards, it prevents the module from getting an * IRQ after unload+reload... */ @@ -1530,7 +1548,7 @@ static int __init el3_init_module(void) { - int el3_cards = 0; + el3_cards = 0; if (debug >= 0) el3_debug = debug; @@ -1548,8 +1566,9 @@ if (eisa_driver_register (&el3_eisa_driver) < 0) { eisa_driver_unregister (&el3_eisa_driver); } - else - el3_cards++; /* Found an eisa card */ +#endif +#ifdef CONFIG_MCA + mca_register_driver(&el3_mca_driver); #endif return el3_cards ? 0 : -ENODEV; } @@ -1568,6 +1587,9 @@ #ifdef CONFIG_EISA eisa_driver_unregister (&el3_eisa_driver); +#endif +#ifdef CONFIG_MCA + mca_unregister_driver(&el3_mca_driver); #endif } diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c --- a/drivers/net/8139too.c Sun Feb 9 21:13:28 2003 +++ b/drivers/net/8139too.c Sun Feb 9 21:13:28 2003 @@ -1589,10 +1589,10 @@ unsigned long timeout; daemonize(); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigemptyset(¤t->blocked); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); strncpy (current->comm, dev->name, sizeof(current->comm) - 1); current->comm[sizeof(current->comm) - 1] = '\0'; @@ -1604,9 +1604,9 @@ } while (!signal_pending (current) && (timeout > 0)); if (signal_pending (current)) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); flush_signals(current); - spin_unlock_irq(¤t->sig->siglock); + 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 Sun Feb 9 21:13:35 2003 +++ b/drivers/net/Kconfig Sun Feb 9 21:13:35 2003 @@ -55,7 +55,7 @@ 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 dummy.o. If you want to use more than one dummy + will be called dummy. If you want to use more than one dummy device at a time, you need to compile this driver as a module. Instead of 'dummy', the devices will then be called 'dummy0', 'dummy1' etc. @@ -80,7 +80,7 @@ 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 bonding.o. + will be called bonding. config EQUALIZER tristate "EQL (serial line load balancing) support" @@ -101,7 +101,7 @@ 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 will be called eql.o. If you want to compile it as a + The module will be called eql. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -125,7 +125,7 @@ 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 will be called tun.o. If you want to compile it as a + The module will be called tun. If you want to compile it as a module, say M here and read . If you don't know what to use this for, you don't need it. @@ -150,7 +150,7 @@ 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 will be called ethertap.o. If you want to compile it as a + The module will be called ethertap. If you want to compile it as a module, say M here and read . If you don't know what to use this for, you don't need it. @@ -167,7 +167,7 @@ provided by your regular phone modem. At present this driver only compiles as a module, so say M here if - you have this card. The module will be called sb1000.o. Then read + you have this card. The module will be called sb1000. Then read for information on how to use this module, as it needs special ppp scripts for establishing a connection. Further documentation and the necessary scripts can be @@ -212,6 +212,14 @@ kernel: saying N will just cause the configurator to skip all the questions about Ethernet network cards. If unsure, say N. +config MII + tristate "generic Media Independent Interface device support" + depends on NET_ETHERNET + help + Most ethernet controllers have MII transceiver either as an external + or internal device. It is safe to say Y or M here even if your + ethernet card lack MII. + config ARM_AM79C961A bool "ARM EBSA110 AM79C961A support" depends on NET_ETHERNET && ARM && ARCH_EBSA110 @@ -229,7 +237,7 @@ motherboard will usually use a MACE (Medium Access Control for Ethernet) interface. Say Y to include support for the MACE chip. - This driver is also available as a module called mace.o ( = code + This driver is also available as a module called mace ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -252,7 +260,7 @@ Say Y for support of BMAC Ethernet interfaces. These are used on G3 computers. - This driver is also available as a module called bmac.o ( = code + This driver is also available as a module called bmac ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -263,7 +271,7 @@ help Say Y if your machine has this type of Ethernet network card. - This driver is also available as a module called oaknet.o ( = code + This driver is also available as a module called oaknet ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -277,7 +285,7 @@ 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 ariadne.o. If you want to compile it as + want). The module is called ariadne. If you want to compile it as a module, say M here and read . config ARIADNE2 @@ -290,7 +298,7 @@ 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 will be called ariadne2.o. If you want to compile it as + The module will be called ariadne2. If you want to compile it as a module, say M here and read . config NE2K_ZORRO @@ -306,7 +314,7 @@ 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 a2065.o. If you want to compile it as a + want). The module is called a2065. If you want to compile it as a module, say M here and read . config HYDRA @@ -317,7 +325,7 @@ 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 hydra.o. If you want to compile it as a + want). The module is called hydra. If you want to compile it as a module, say M here and read . config APNE @@ -329,7 +337,7 @@ 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 apne.o. If you want to compile it as a + want). The module is called apne. If you want to compile it as a module, say M here and read . config APOLLO_ELPLUS @@ -363,7 +371,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . This module will - be called mac89x0.o. + be called mac89x0. config MACSONIC tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)" @@ -379,7 +387,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . This module will - be called macsonic.o. + be called macsonic. config MACMACE bool "Macintosh (AV) onboard MACE ethernet (EXPERIMENTAL)" @@ -529,7 +537,7 @@ cards are based on the AMD Lance chipset, which is better known via the NE2100 cards. - This support is also available as a module called sunlance.o ( = + This support is also available as a module called sunlance ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -543,7 +551,7 @@ both PCI and Sbus devices. This driver also supports the "qfe" quad 100baseT device available in both PCI and Sbus configurations. - This support is also available as a module called sunhme.o ( = code + This support is also available as a module called sunhme ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -555,7 +563,7 @@ This driver supports the "be" interface available as an Sbus option. This is Sun's older 100baseT Ethernet device. - This support is also available as a module called sunbmac.o ( = code + This support is also available as a module called sunbmac ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -568,7 +576,7 @@ an Sbus option. Note that this is not the same as Quad FastEthernet "qfe" which is supported by the Happy Meal driver instead. - This support is also available as a module called sunqe.o ( = code + This support is also available as a module called sunqe ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -606,7 +614,7 @@ 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 will be called 3c501.o. If you want to compile it as a + The module will be called 3c501. If you want to compile it as a module, say M here and read as well as . @@ -620,7 +628,7 @@ 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 will be called 3c503.o. If you want to compile it as a + The module will be called 3c503. If you want to compile it as a module, say M here and read as well as . @@ -637,7 +645,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called 3c505.o. + called 3c505. config EL16 tristate "3c507 \"EtherLink 16\" support (EXPERIMENTAL)" @@ -649,7 +657,7 @@ 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 will be called 3c507.o. If you want to compile it as a + The module will be called 3c507. If you want to compile it as a module, say M here and read as well as . @@ -669,7 +677,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called 3c509.o. + called 3c509. config 3C515 tristate "3c515 ISA \"Fast EtherLink\"" @@ -683,7 +691,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called 3c515.o. + called 3c515. config ELMC tristate "3c523 \"EtherLink/MC\" support" @@ -695,7 +703,7 @@ 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 will be called 3c523.o. If you want to compile it as a + The module will be called 3c523. If you want to compile it as a module, say M here and read as well as . @@ -709,7 +717,7 @@ 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 will be called 3c527.o. If you want to compile it as a + The module will be called 3c527. If you want to compile it as a module, say M here and read as well as . @@ -749,7 +757,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called lance.o. + recommended. The module will be called lance. config NET_VENDOR_SMC bool "Western Digital/SMC cards" @@ -774,7 +782,7 @@ 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 will be called wd.o. If you want to compile it as a + The module will be called wd. If you want to compile it as a module, say M here and read as well as . @@ -788,7 +796,7 @@ 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 will be called smc-mca.o. If you want to compile it as a + The module will be called smc-mca. If you want to compile it as a module, say M here and read as well as . @@ -809,7 +817,7 @@ 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 will be called smc-ultra.o. If you want to compile it as + The module will be called smc-ultra. If you want to compile it as a module, say M here and read as well as . @@ -823,7 +831,7 @@ 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 will be called smc-ultra32.o. If you want to compile it + The module will be called smc-ultra32. If you want to compile it as a module, say M here and read as well as . @@ -840,7 +848,7 @@ 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 will be called smc9194.o. If you want to compile it as a + The module will be called smc9194. If you want to compile it as a module, say M here and read as well as . @@ -868,7 +876,7 @@ 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 will be called ni5010.o. If you want to compile it as a + The module will be called ni5010. If you want to compile it as a module, say M here and read as well as . @@ -882,7 +890,7 @@ 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 will be called ni52.o. If you want to compile it as a + The module will be called ni52. If you want to compile it as a module, say M here and read as well as . @@ -896,7 +904,7 @@ 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 will be called ni65.o. If you want to compile it as a + The module will be called ni65. If you want to compile it as a module, say M here and read as well as . @@ -915,7 +923,7 @@ If you want to compile it as a module, say M here and read as well as . The module will be - called at1700.o. + called at1700. config DEPCA tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support" @@ -931,7 +939,7 @@ say M here and read as well as . The module will be called - depca.o. + depca. config HP100 tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support" @@ -945,7 +953,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called hp100.o. + called hp100. config NET_ISA bool "Other ISA cards" @@ -974,7 +982,7 @@ 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 will be called e2100.o. If you want to compile it as a + The module will be called e2100. If you want to compile it as a module, say M here and read as well as . @@ -992,7 +1000,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called ewrk3.o. + called ewrk3. config EEXPRESS tristate "EtherExpress 16 support" @@ -1009,7 +1017,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called eexpress.o. + called eexpress. config EEXPRESS_PRO tristate "EtherExpressPro support/EtherExpress 10 (i82595) support" @@ -1023,7 +1031,7 @@ 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 will be called eepro.o. If you want to compile it as a + The module will be called eepro. If you want to compile it as a module, say M here and read as well as . @@ -1040,7 +1048,7 @@ 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 will be called fmv18x.o. If you want to compile it as a + The module will be called fmv18x. If you want to compile it as a module, say M here and read as well as . @@ -1054,7 +1062,7 @@ 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 will be called hp-plus.o. If you want to compile it as a + The module will be called hp-plus. If you want to compile it as a module, say M here and read as well as . @@ -1068,7 +1076,7 @@ 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 will be called hp.o. If you want to compile it as a + The module will be called hp. If you want to compile it as a module, say M here and read as well as . @@ -1090,7 +1098,7 @@ 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 will be called eth16i.o. If you want to compile it as a + The module will be called eth16i. If you want to compile it as a module, say M here and read as well as . @@ -1111,7 +1119,7 @@ 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 will be called ne.o. If you want to compile it as a + The module will be called ne. If you want to compile it as a module, say M here and read as well as . @@ -1137,7 +1145,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called ewrk3.o. + called ewrk3. config SK_G16 tristate "SK_G16 support (OBSOLETE)" @@ -1160,7 +1168,7 @@ 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 sk_mca.o. If you want to compile it as a + The module is called sk_mca. If you want to compile it as a module, say M here and read as well as . @@ -1174,7 +1182,7 @@ 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 will be called ne2.o. If you want to compile it as a + The module will be called ne2. If you want to compile it as a module, say M here and read as well as . @@ -1218,7 +1226,7 @@ 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 will be called pcnet32.o. If you want to compile it as a + The module will be called pcnet32. If you want to compile it as a module, say M here and read as well as . @@ -1232,7 +1240,7 @@ 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 will be called amd8111e.o. If you want to compile it as a + The module will be called amd8111e. If you want to compile it as a module, say M here and read as well as . @@ -1248,7 +1256,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called starfire.o. + recommended. The module will be called starfire. config AC3200 tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)" @@ -1260,7 +1268,7 @@ 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 will be called ac3200.o. If you want to compile it as a + The module will be called ac3200. If you want to compile it as a module, say M here and read as well as . @@ -1276,7 +1284,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called apricot.o. + called apricot. config B44 tristate "Broadcom 4400 ethernet support (EXPERIMENTAL)" @@ -1290,7 +1298,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called b44.o. + called b44. config CS89x0 tristate "CS89x0 support" @@ -1306,7 +1314,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called cs89x.o. + called cs89x. config DGRS tristate "Digi Intl. RightSwitch SE-X support" @@ -1321,7 +1329,7 @@ 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 will be called dgrs.o. If you want to compile it as a + The module will be called dgrs. If you want to compile it as a module, say M here and read as well as . @@ -1335,7 +1343,7 @@ 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 will be called eepro100.o. If you want to compile it as + The module will be called eepro100. If you want to compile it as a module, say M here and read as well as . @@ -1412,7 +1420,7 @@ 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 will be called e100.o. If you want to compile it as a + The module will be called e100. If you want to compile it as a module, say M here and read as well as . @@ -1426,7 +1434,7 @@ 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 will be called lne390.o. If you want to compile it as a + The module will be called lne390. If you want to compile it as a module, say M here and read as well as . @@ -1465,7 +1473,7 @@ 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 will be called ne2k-pci.o. If you want to compile it as + The module will be called ne2k-pci. If you want to compile it as a module, say M here and read as well as . @@ -1480,7 +1488,7 @@ 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 will be called ne3210.o. If you want to compile it as a + The module will be called ne3210. If you want to compile it as a module, say M here and read as well as . @@ -1494,7 +1502,7 @@ 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 will be called es3210.o. If you want to compile it as a + The module will be called es3210. If you want to compile it as a module, say M here and read as well as . @@ -1510,7 +1518,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read Documentation/modules.txt. This is recommended. - The module will be called 8139cp.o. + The module will be called 8139cp. config 8139TOO tristate "RealTek RTL-8139 PCI Fast Ethernet Adapter support" @@ -1525,7 +1533,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called 8139too.o. + recommended. The module will be called 8139too. config 8139TOO_PIO bool "Use PIO instead of MMIO" @@ -1584,7 +1592,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called sis900.o. + recommended. The module will be called sis900. config EPIC100 tristate "SMC EtherPower II" @@ -1628,7 +1636,7 @@ 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 will be called tlan.o. If you want to compile it as a + The module will be called tlan. If you want to compile it as a module, say M here and read as well as . @@ -1643,7 +1651,7 @@ 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 will be called via-rhine.o. If you want to compile it as + The module will be called via-rhine. If you want to compile it as a module, say M here and read as well as . @@ -1706,7 +1714,7 @@ If you want to compile this driver as a module however ( = 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 atp.o. + . The module will be called atp. config DE600 tristate "D-Link DE600 pocket adapter support" @@ -1724,7 +1732,7 @@ which can be inserted in and removed from the running kernel whenever you want), say M here and read . - The module will be called de600.o. + The module will be called de600. config DE620 tristate "D-Link DE620 pocket adapter support" @@ -1742,7 +1750,7 @@ which can be inserted in and removed from the running kernel whenever you want), say M here and read . - The module will be called de620.o. + The module will be called de620. config SGISEEQ bool "SGI Seeq ethernet controller support" @@ -1804,7 +1812,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called acenic.o. + recommended. The module will be called acenic. config ACENIC_OMIT_TIGON_I bool "Omit support for old Tigon I based AceNICs" @@ -1831,7 +1839,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called dl2k.o. + recommended. The module will be called dl2k. config E1000 tristate "Intel(R) PRO/1000 Gigabit Ethernet support" @@ -1873,7 +1881,7 @@ 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 will be called e1000.o. If you want to compile it as a + The module will be called e1000. If you want to compile it as a module, say M here and read as well as . @@ -1890,7 +1898,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called myri_sbus.o. + recommended. The module will be called myri_sbus. config NS83820 tristate "National Semiconduct DP83820 support" @@ -1914,7 +1922,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called hamachi.o. + called hamachi. config YELLOWFIN tristate "Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)" @@ -1929,7 +1937,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called yellowfin.o. + recommended. The module will be called yellowfin. config R8169 tristate "Realtek 8169 gigabit ethernet support" @@ -1940,7 +1948,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called r8169.o. + recommended. The module will be called r8169. config SK98LIN tristate "SysKonnect SK-98xx support" @@ -1968,7 +1976,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called sk98lin.o. + recommended. The module will be called sk98lin. config TIGON3 tristate "Broadcom Tigon3 support" @@ -1979,7 +1987,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called tg3.o. + recommended. The module will be called tg3. endmenu @@ -2036,7 +2044,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called skfp.o. + recommended. The module will be called skfp. config HIPPI bool "HIPPI driver support (EXPERIMENTAL)" @@ -2059,7 +2067,7 @@ 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 will be called rrunner.o. If you want to compile it as a + The module will be called rrunner. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -2108,7 +2116,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called plip.o. If unsure, say Y or M, in case you buy a laptop + called plip. If unsure, say Y or M, in case you buy a laptop later. config PPP @@ -2140,7 +2148,7 @@ inserted in and removed from the running kernel whenever you want). If you said Y to "Version information on all symbols" above, then you cannot compile the PPP driver into the kernel; you can then only - compile it as a module. The module will be called ppp_generic.o. + compile it as a module. The module will be called ppp_generic. If you want to compile it as a module, say M here and read as well as . @@ -2231,7 +2239,7 @@ and is patent-free. Note that the BSD compression code will always be compiled as a - module; it is called bsd_comp.o and will show up in the directory + module; it is called bsd_comp and will show up in the directory modules once you have said "make modules". If unsure, say N. config PPPOE @@ -2287,7 +2295,7 @@ inserted in and removed from the running kernel whenever you want), say M here and read as well as . The module will be - called slip.o. + called slip. config SLIP_COMPRESSED bool "CSLIP compressed headers" @@ -2374,7 +2382,7 @@ You can also 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 strip.o. + called strip. config ARLAN tristate "Aironet Arlan 655 & IC2200 DS support" @@ -2404,7 +2412,7 @@ 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 will be called aironet4500_core.o. If you want to + The module will be called aironet4500_core. If you want to compile it as a module, say M here and read as well as . @@ -2434,7 +2442,7 @@ 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 will be called aironet4500_card.o. If you want to + The module will be called aironet4500_card. If you want to compile it as a module, say M here and read . @@ -2481,7 +2489,7 @@ 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 will be called aironet4500_proc.o. If you want to + The module will be called aironet4500_proc. If you want to compile it as a module, say M here and read . @@ -2517,7 +2525,7 @@ The driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called iph5526.o. For general information about + The module will be called iph5526. For general information about modules read . config RCPCI @@ -2527,7 +2535,7 @@ This is a driver for hardware which provides a Virtual Private Network (VPN). Say Y if you have it. - This code is also available as a module called rcpci.o ( = code + This code is also available as a module called rcpci ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -2552,7 +2560,7 @@ 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 will be called shaper.o. If you want to compile it as a + The module will be called shaper. If you want to compile it as a module, say M here and read . If unsure, say N. diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile --- a/drivers/net/Makefile Sun Feb 9 21:13:30 2003 +++ b/drivers/net/Makefile Sun Feb 9 21:13:30 2003 @@ -2,12 +2,6 @@ # Makefile for the Linux network (ethercard) device drivers. # -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := 8390.o arlan.o aironet4500_core.o aironet4500_card.o \ - ppp_async.o ppp_generic.o slhc.o pppox.o auto_irq.o \ - net_init.o mii.o rcpci-objs := rcpci45.o rclanmtl.o ifeq ($(CONFIG_ISDN_PPP),y) @@ -63,6 +57,7 @@ # end link order section # +obj-$(CONFIG_MII) += mii.o obj-$(CONFIG_AIRONET4500) += aironet4500_core.o obj-$(CONFIG_AIRONET4500_CS) += aironet4500_core.o obj-$(CONFIG_AIRONET4500_NONCS) += aironet4500_card.o @@ -199,3 +194,6 @@ obj-$(CONFIG_NET_TULIP) += tulip/ obj-$(CONFIG_HAMRADIO) += hamradio/ obj-$(CONFIG_IRDA) += irda/ + + +include $(TOPDIR)/drivers/usb/net/Makefile.mii diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c --- a/drivers/net/Space.c Sun Feb 9 21:13:29 2003 +++ b/drivers/net/Space.c Sun Feb 9 21:13:29 2003 @@ -224,6 +224,9 @@ #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/acenic.c b/drivers/net/acenic.c --- a/drivers/net/acenic.c Sun Feb 9 21:13:32 2003 +++ b/drivers/net/acenic.c Sun Feb 9 21:13:32 2003 @@ -482,7 +482,7 @@ * * One advantagous side effect of this allocation approach is that the * entire rx processing can be done without holding any spin lock - * since the rx rings and registers are totally independant of the tx + * since the rx rings and registers are totally independent of the tx * ring and its registers. This of course includes the kmalloc's of * new skb's. Thus start_xmit can run in parallel with rx processing * and the memory allocation on SMP systems. diff -Nru a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig --- a/drivers/net/appletalk/Kconfig Sun Feb 9 21:13:31 2003 +++ b/drivers/net/appletalk/Kconfig Sun Feb 9 21:13:31 2003 @@ -68,7 +68,7 @@ If you say M here, the AppleTalk-IP support will be compiled as a module ( = code which can be inserted in and removed from the running kernel whenever you want, read - ). The module is called ipddp.o. + ). The module is called ipddp. In this case, you will be able to use both encapsulation and decapsulation simultaneously, by loading two copies of the module and specifying different values for the module option ipddp_mode. diff -Nru a/drivers/net/appletalk/Makefile b/drivers/net/appletalk/Makefile --- a/drivers/net/appletalk/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/net/appletalk/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for drivers/net/appletalk # -export-objs := - obj-$(CONFIG_IPDDP) += ipddp.o obj-$(CONFIG_COPS) += cops.o obj-$(CONFIG_LTPC) += ltpc.o diff -Nru a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig --- a/drivers/net/arcnet/Kconfig Sun Feb 9 21:13:36 2003 +++ b/drivers/net/arcnet/Kconfig Sun Feb 9 21:13:36 2003 @@ -23,7 +23,7 @@ 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 will be called arcnet.o. If you want to compile it as a + The module will be called arcnet. If you want to compile it as a module, say M here and read as well as . @@ -71,7 +71,7 @@ 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 will be called com90xx.o. If you want to compile it as a + The module will be called com90xx. If you want to compile it as a module, say M here and read as well as . @@ -86,7 +86,7 @@ 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 will be called com90io.o. If you want to compile it as a + The module will be called com90io. If you want to compile it as a module, say M here and read as well as . @@ -101,7 +101,7 @@ 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 will be called arc-rimi.o. If you want to compile + want). The module will be called arc-rimi. If you want to compile it as a module, say M here and read as well as . @@ -115,7 +115,7 @@ 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 will be called com20020.o. If you want to compile it as + The module will be called com20020. If you want to compile it as a module, say M here and read as well as . diff -Nru a/drivers/net/arcnet/Makefile b/drivers/net/arcnet/Makefile --- a/drivers/net/arcnet/Makefile Sun Feb 9 21:13:34 2003 +++ b/drivers/net/arcnet/Makefile Sun Feb 9 21:13:34 2003 @@ -1,8 +1,6 @@ # Makefile for linux/drivers/net/arcnet # -export-objs := arcnet.o com20020.o - obj-$(CONFIG_ARCNET) += arcnet.o obj-$(CONFIG_ARCNET_1201) += rfc1201.o obj-$(CONFIG_ARCNET_1051) += rfc1051.o diff -Nru a/drivers/net/arlan.c b/drivers/net/arlan.c --- a/drivers/net/arlan.c Sun Feb 9 21:13:33 2003 +++ b/drivers/net/arlan.c Sun Feb 9 21:13:33 2003 @@ -1188,34 +1188,31 @@ { struct net_device *dev; + struct arlan_private *ap; ARLAN_DEBUG_ENTRY("arlan_allocate_device"); - if (!devs) - dev = init_etherdev(0, sizeof(struct arlan_private)); - else - { + if (!devs) { + dev = init_etherdev(0, sizeof(struct arlan_private) + sizeof(struct arlan_shmem)); + if (!dev) { + printk(KERN_ERR "ARLAN: init_etherdev failed\n"); + return 0; + } + ap = dev->priv; + ap->config = dev->priv + sizeof(struct arlan_private); + ap->init_etherdev_alloc = 1; + } else { dev = devs; - dev->priv = kmalloc(sizeof(struct arlan_private), GFP_KERNEL); - }; - - if (dev == NULL || dev->priv == NULL) - { - printk(KERN_CRIT "init_etherdev failed "); - return 0; + dev->priv = kmalloc(sizeof(struct arlan_private) + sizeof(struct arlan_shmem), GFP_KERNEL); + if (!dev->priv) { + printk(KERN_ERR "ARLAN: kmalloc of dev->priv failed\n"); + return 0; + } + ap = dev->priv; + ap->config = dev->priv + sizeof(struct arlan_private); + memset(ap, 0, sizeof(*ap)); } - memset(dev->priv,0,sizeof(struct arlan_private)); - - ((struct arlan_private *) dev->priv)->conf = - kmalloc(sizeof(struct arlan_shmem), GFP_KERNEL); - - if (dev == NULL || dev->priv == NULL || - ((struct arlan_private *) dev->priv)->conf == NULL) - { - return 0; - printk(KERN_CRIT " No memory at arlan_allocate_device \n"); - } /* Fill in the 'dev' fields. */ dev->base_addr = 0; dev->mem_start = 0; @@ -2017,32 +2014,24 @@ ARLAN_DEBUG_ENTRY("init_module"); if (channelSet != channelSetUNKNOWN || channelNumber != channelNumberUNKNOWN || systemId != systemIdUNKNOWN) - { - printk(KERN_WARNING "arlan: wrong module params for multiple devices\n "); - return -1; - } + return -EINVAL; + numDevices = arlan_find_devices(); if (numDevices == 0) - { - printk(KERN_ERR "arlan: no devices found \n"); - return -1; - } + return -ENODEV; siteName = kmalloc(100, GFP_KERNEL); if(siteName==NULL) - { - printk(KERN_ERR "arlan: No memory for site name.\n"); - return -1; - } + return -ENOMEM; + for (i = 0; i < numDevices && i < MAX_ARLANS; i++) { if (!arlan_allocate_device(i, NULL)) - return -1; + return -ENOMEM; + if (arlan_device[i] == NULL) - { - printk(KERN_CRIT "arlan: Not Enough memory \n"); - return -1; - } + return -ENOMEM; + if (probe) arlan_probe_everywhere(arlan_device[i]); // arlan_command(arlan_device[i], ARLAN_COMMAND_POWERDOWN ); @@ -2056,6 +2045,7 @@ void cleanup_module(void) { int i = 0; + struct arlan_private ap; ARLAN_DEBUG_ENTRY("cleanup_module"); @@ -2069,13 +2059,14 @@ // release_mem_region(virt_to_phys(arlan_device[i]->mem_start), 0x2000 ); unregister_netdev(arlan_device[i]); - if (arlan_device[i]->priv) - { - if (((struct arlan_private *) arlan_device[i]->priv)->conf) - kfree(((struct arlan_private *) arlan_device[i]->priv)->conf); + ap = arlan_device[i]->priv; + if (ap->init_etherdev_alloc) { kfree(arlan_device[i]); + arlan_device[i] = NULL; + } else { + kfree(ap); + ap = NULL; } - arlan_device[i] = NULL; } } ARLAN_DEBUG_EXIT("cleanup_module"); diff -Nru a/drivers/net/arlan.h b/drivers/net/arlan.h --- a/drivers/net/arlan.h Sun Feb 9 21:13:32 2003 +++ b/drivers/net/arlan.h Sun Feb 9 21:13:32 2003 @@ -410,6 +410,7 @@ int out_time10; int in_bytes10; int out_bytes10; + int init_etherdev_alloc; }; diff -Nru a/drivers/net/declance.c b/drivers/net/declance.c --- a/drivers/net/declance.c Sun Feb 9 21:13:33 2003 +++ b/drivers/net/declance.c Sun Feb 9 21:13:33 2003 @@ -279,7 +279,7 @@ lp->tx_old - lp->tx_new-1) /* The lance control ports are at an absolute address, machine and tc-slot - * dependant. + * dependent. * DECstations do only 32-bit access and the LANCE uses 16 bit addresses, * so we have to give the structure an extra member making rap pointing * at the right address diff -Nru a/drivers/net/e100/Makefile b/drivers/net/e100/Makefile --- a/drivers/net/e100/Makefile Sun Feb 9 21:13:36 2003 +++ b/drivers/net/e100/Makefile Sun Feb 9 21:13:36 2003 @@ -4,5 +4,5 @@ obj-$(CONFIG_E100) += e100.o -e100-objs := e100_main.o e100_config.o e100_proc.o e100_phy.o \ +e100-objs := e100_main.o e100_config.o e100_phy.o \ e100_eeprom.o e100_test.o diff -Nru a/drivers/net/e100/e100.h b/drivers/net/e100/e100.h --- a/drivers/net/e100/e100.h Sun Feb 9 21:13:30 2003 +++ b/drivers/net/e100/e100.h Sun Feb 9 21:13:30 2003 @@ -56,7 +56,6 @@ #include #include -#include #include #define E100_REGS_LEN 1 @@ -926,20 +925,7 @@ struct cfg_params params; /* adapter's command line parameters */ - struct proc_dir_entry *proc_parent; - char *id_string; - char *cable_status; - char *mdix_status; - - /* Variables for HWI */ - int saved_open_circut; - int saved_short_circut; - int saved_distance; - int saved_i; - int saved_same; - unsigned char hwi_started; - struct timer_list hwi_timer; /* hwi timer id */ u32 speed_duplex_caps; /* adapter's speed/duplex capabilities */ diff -Nru a/drivers/net/e100/e100_main.c b/drivers/net/e100/e100_main.c --- a/drivers/net/e100/e100_main.c Sun Feb 9 21:13:32 2003 +++ b/drivers/net/e100/e100_main.c Sun Feb 9 21:13:32 2003 @@ -83,13 +83,15 @@ #include "e100_phy.h" #include "e100_vendor.h" -#ifdef CONFIG_PROC_FS -extern int e100_create_proc_subdir(struct e100_private *, char *); -extern void e100_remove_proc_subdir(struct e100_private *, char *); -#else -#define e100_create_proc_subdir(X, Y) 0 -#define e100_remove_proc_subdir(X, Y) do {} while(0) -#endif +static char e100_gstrings_stats[][ETH_GSTRING_LEN] = { + "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors", + "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions", + "rx_length_errors", "rx_over_errors", "rx_crc_errors", + "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors", + "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors", + "tx_heartbeat_errors", "tx_window_errors", +}; +#define E100_STATS_LEN sizeof(e100_gstrings_stats) / ETH_GSTRING_LEN static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *); static void e100_get_speed_duplex_caps(struct e100_private *); @@ -135,7 +137,7 @@ /* Global Data structures and variables */ char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation"; -char e100_driver_version[]="2.1.29-k1"; +char e100_driver_version[]="2.1.29-k4"; const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver"; char e100_short_driver_name[] = "e100"; static int e100nics = 0; @@ -150,15 +152,6 @@ .priority = 0 }; #endif -static int e100_notify_netdev(struct notifier_block *, unsigned long event, void *ptr); - -struct notifier_block e100_notifier_netdev = { - .notifier_call = e100_notify_netdev, - .next = NULL, - .priority = 0 -}; - -static void e100_get_mdix_status(struct e100_private *bdp); /*********************************************************************/ /*! This is a GCC extension to ANSI C. @@ -196,6 +189,7 @@ char *e100_get_brand_msg(struct e100_private *); static u8 e100_pci_setup(struct pci_dev *, struct e100_private *); static u8 e100_sw_init(struct e100_private *); +static void e100_tco_workaround(struct e100_private *); static unsigned char e100_alloc_space(struct e100_private *); static void e100_dealloc_space(struct e100_private *); static int e100_alloc_tcb_pool(struct e100_private *); @@ -213,7 +207,7 @@ static unsigned char e100_clr_cntrs(struct e100_private *); static unsigned char e100_load_microcode(struct e100_private *); -static unsigned char e100_hw_init(struct e100_private *, u32); +static unsigned char e100_hw_init(struct e100_private *); static unsigned char e100_setup_iaaddr(struct e100_private *, u8 *); static unsigned char e100_update_stats(struct e100_private *bdp); @@ -349,8 +343,6 @@ u32 e100_rx_srv(struct e100_private *); void e100_watchdog(struct net_device *); -static void e100_do_hwi(struct net_device *); -static void e100_hwi_restore(struct e100_private *); void e100_refresh_txthld(struct e100_private *); void e100_manage_adaptive_ifs(struct e100_private *); void e100_clear_pools(struct e100_private *); @@ -610,10 +602,6 @@ bdp->watchdog_timer.data = (unsigned long) dev; bdp->watchdog_timer.function = (void *) &e100_watchdog; - init_timer(&bdp->hwi_timer); - bdp->hwi_timer.data = (unsigned long) dev; - bdp->hwi_timer.function = (void *) &e100_do_hwi; - if ((rc = e100_pci_setup(pcid, bdp)) != 0) { goto err_dealloc; } @@ -686,21 +674,6 @@ bdp->device->name, e100_get_brand_msg(bdp)); e100_print_brd_conf(bdp); bdp->id_string = e100_get_brand_msg(bdp); - e100_get_mdix_status(bdp); - - if (netif_carrier_ok(bdp->device)) - bdp->cable_status = "Cable OK"; - else { - if (bdp->rev_id < D102_REV_ID) - bdp->cable_status = "Not supported"; - else - bdp->cable_status = "Not available"; - } - - if (e100_create_proc_subdir(bdp, bdp->ifname) < 0) { - printk(KERN_ERR "e100: Failed to create proc dir for %s\n", - bdp->device->name); - } bdp->wolsupported = 0; bdp->wolopts = 0; @@ -766,8 +739,6 @@ unregister_netdev(dev); - e100_remove_proc_subdir(bdp, bdp->ifname); - e100_sw_reset(bdp, PORT_SELECTIVE_RESET); if (bdp->non_tx_command_state != E100_NON_TX_IDLE) { @@ -804,7 +775,6 @@ #ifdef CONFIG_PM register_reboot_notifier(&e100_notifier_reboot); #endif - register_netdevice_notifier(&e100_notifier_netdev); } return ret; @@ -816,7 +786,6 @@ #ifdef CONFIG_PM unregister_reboot_notifier(&e100_notifier_reboot); #endif - unregister_netdevice_notifier(&e100_notifier_netdev); pci_unregister_driver(&e100_driver); } @@ -1265,7 +1234,7 @@ /* read NIC's part number */ e100_rd_pwa_no(bdp); - if (!e100_hw_init(bdp, PORT_SOFTWARE_RESET)) { + if (!e100_hw_init(bdp)) { printk(KERN_ERR "e100: hw init failed\n"); return false; } @@ -1314,10 +1283,46 @@ return 1; } +static void __devinit +e100_tco_workaround(struct e100_private *bdp) +{ + int i; + + /* Do software reset */ + e100_sw_reset(bdp, PORT_SOFTWARE_RESET); + + /* Do a dummy LOAD CU BASE command. */ + /* This gets us out of pre-driver to post-driver. */ + e100_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE); + + /* Wait 20 msec for reset to take effect */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 50 + 1); + + /* disable interrupts since they are enabled */ + /* after device reset */ + e100_disable_clear_intr(bdp); + + /* Wait for command to be cleared up to 1 sec */ + for (i=0; i<100; i++) { + if (!readb(&bdp->scb->scb_cmd_low)) + break; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 100 + 1); + } + + /* Wait for TCO request bit in PMDR register to be clear */ + for (i=0; i<50; i++) { + if (!(readb(&bdp->scb->scb_ext.d101m_scb.scb_pmdr) & BIT_1)) + break; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 100 + 1); + } +} + /** * e100_hw_init - initialized tthe hardware * @bdp: atapter's private data struct - * @reset_cmd: s/w reset or selective reset * * This routine performs a reset on the adapter, and configures the adapter. * This includes configuring the 82557 LAN controller, validating and setting @@ -1329,13 +1334,16 @@ * false - If the adapter failed initialization */ unsigned char __devinit -e100_hw_init(struct e100_private *bdp, u32 reset_cmd) +e100_hw_init(struct e100_private *bdp) { if (!e100_phy_init(bdp)) return false; - /* Issue a software reset to the e100 */ - e100_sw_reset(bdp, reset_cmd); + e100_sw_reset(bdp, PORT_SELECTIVE_RESET); + + /* Only 82559 or above needs TCO workaround */ + if (bdp->rev_id >= D101MA_REV_ID) + e100_tco_workaround(bdp); /* Load the CU BASE (set to 0, because we use linear mode) */ if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE, 0)) @@ -1391,6 +1399,7 @@ u32 next_phys; /* the next phys addr */ u16 txcommand = CB_S_BIT | CB_TX_SF_BIT; + bdp->tx_count = 0; if (bdp->flags & USE_IPCB) { txcommand |= CB_IPCB_TRANSMIT | CB_CID_DEFAULT; } else if (bdp->flags & IS_BACHELOR) { @@ -1634,7 +1643,6 @@ if (!netif_running(dev)) { return; } - e100_get_mdix_status(bdp); /* check if link state has changed */ if (e100_phy_check(bdp)) { @@ -1647,37 +1655,10 @@ e100_config_fc(bdp); e100_config(bdp); - bdp->cable_status = "Cable OK"; } else { printk(KERN_ERR "e100: %s NIC Link is Down\n", bdp->device->name); - if (bdp->rev_id < D102_REV_ID) - bdp->cable_status = "Not supported"; - else { - /* Initiate hwi, ie, cable diagnostic */ - bdp->saved_open_circut = 0xffff; - bdp->saved_short_circut = 0xffff; - bdp->saved_distance = 0xffff; - bdp->saved_i = 0; - bdp->saved_same = 0; - bdp->hwi_started = 1; - - /* Disable MDI/MDI-X auto switching */ - e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr, - MDI_MDIX_RESET_ALL_MASK); - - /* Set to 100 Full as required by hwi test */ - e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, - BMCR_SPEED100 | BMCR_FULLDPLX); - - /* Enable and execute HWI test */ - e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr, - (HWI_TEST_ENABLE | HWI_TEST_EXECUTE)); - - /* Launch hwi timer in 1 msec */ - mod_timer(&(bdp->hwi_timer), jiffies + (HZ / 1000) ); - } } } @@ -1836,10 +1817,8 @@ bdp->drv_stats.rx_intr_pkts += e100_rx_srv(bdp); /* clean up after tx'ed packets */ - if (intr_status & (SCB_STATUS_ACK_CNA | SCB_STATUS_ACK_CX)) { - bdp->tx_count = 0; /* restart tx interrupt batch count */ + if (intr_status & (SCB_STATUS_ACK_CNA | SCB_STATUS_ACK_CX)) e100_tx_srv(bdp); - } e100_set_intr_mask(bdp); } @@ -2147,11 +2126,12 @@ tcb->tcb_thrshld = bdp->tx_thld; tcb->tcb_hdr.cb_cmd |= __constant_cpu_to_le16(CB_S_BIT); - /* set the I bit on the modulo tcbs, so we will get an interrupt * to - * clean things up */ - if (!(++bdp->tx_count % TX_FRAME_CNT)) { + /* Set I (Interrupt) bit on every (TX_FRAME_CNT)th packet */ + if (!(++bdp->tx_count % TX_FRAME_CNT)) tcb->tcb_hdr.cb_cmd |= __constant_cpu_to_le16(CB_I_BIT); - } + else + /* Clear I bit on other packets */ + tcb->tcb_hdr.cb_cmd &= ~__constant_cpu_to_le16(CB_I_BIT); tcb->tcb_skb = skb; @@ -3054,12 +3034,6 @@ if (bdp->device->flags & IFF_UP) { e100_disable_clear_intr(bdp); del_timer_sync(&bdp->watchdog_timer); - del_timer_sync(&bdp->hwi_timer); - /* If in middle of cable diag, */ - if (bdp->hwi_started) { - bdp->hwi_started = 0; - e100_hwi_restore(bdp); - } netif_carrier_off(bdp->device); netif_stop_queue(bdp->device); bdp->last_tcb = NULL; @@ -3205,6 +3179,22 @@ case ETHTOOL_SEEPROM: rc = e100_ethtool_eeprom(dev, ifr); break; + case ETHTOOL_GSTATS: { + struct { + struct ethtool_stats cmd; + uint64_t data[E100_STATS_LEN]; + } stats = { {ETHTOOL_GSTATS, E100_STATS_LEN} }; + struct e100_private *bdp = dev->priv; + void *addr = ifr->ifr_data; + int i; + + for(i = 0; i < E100_STATS_LEN; i++) + stats.data[i] = + ((unsigned long *)&bdp->drv_stats.net_stats)[i]; + if(copy_to_user(addr, &stats, sizeof(stats))) + return -EFAULT; + return 0; + } case ETHTOOL_GWOL: case ETHTOOL_SWOL: rc = e100_ethtool_wol(dev, ifr); @@ -3456,6 +3446,7 @@ sizeof (info.fw_version) - 1); strncpy(info.bus_info, bdp->pdev->slot_name, sizeof (info.bus_info) - 1); + info.n_stats = E100_STATS_LEN; info.regdump_len = E100_REGS_LEN * sizeof(u32); info.eedump_len = (bdp->eeprom_size << 1); info.testinfo_len = E100_MAX_TEST_RES; @@ -3816,6 +3807,19 @@ test_strings[i]); } break; + case ETH_SS_STATS: { + char *strings = NULL; + void *addr = ifr->ifr_data; + info.len = E100_STATS_LEN; + strings = *e100_gstrings_stats; + if(copy_to_user(ifr->ifr_data, &info, sizeof(info))) + return -EFAULT; + addr += offsetof(struct ethtool_gstrings, data); + if(copy_to_user(addr, strings, + info.len * ETH_GSTRING_LEN)) + return -EFAULT; + return 0; + } default: return -EOPNOTSUPP; } @@ -4054,29 +4058,6 @@ spin_unlock_bh(&(bdp->bd_non_tx_lock)); } -int e100_notify_netdev(struct notifier_block *nb, unsigned long event, void *p) -{ - struct e100_private *bdp; - struct net_device *netdev = p; - - if(netdev == NULL) - return NOTIFY_DONE; - - switch(event) { - case NETDEV_CHANGENAME: - if(netdev->open == e100_open) { - bdp = netdev->priv; - /* rename the proc nodes the easy way */ - e100_remove_proc_subdir(bdp, bdp->ifname); - memcpy(bdp->ifname, netdev->name, IFNAMSIZ); - bdp->ifname[IFNAMSIZ-1] = 0; - e100_create_proc_subdir(bdp, bdp->ifname); - } - break; - } - return NOTIFY_DONE; -} - #ifdef CONFIG_PM static int e100_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) @@ -4139,128 +4120,6 @@ return 0; } #endif /* CONFIG_PM */ - -static void -e100_get_mdix_status(struct e100_private *bdp) -{ - if (bdp->rev_id < D102_REV_ID) { - if (netif_carrier_ok(bdp->device)) - bdp->mdix_status = "MDI"; - else - bdp->mdix_status = "None"; - } else { - u16 ctrl_reg; - /* Read the MDIX control register */ - e100_mdi_read(bdp, MII_NCONFIG, bdp->phy_addr, &ctrl_reg); - if (ctrl_reg & MDI_MDIX_CONFIG_IS_OK) { - if (ctrl_reg & MDI_MDIX_STATUS) - bdp->mdix_status = "MDI-X"; - else - bdp->mdix_status = "MDI"; - } else - bdp->mdix_status = "None"; - } -} - -static void -e100_do_hwi(struct net_device *dev) -{ - struct e100_private *bdp = dev->priv; - u16 ctrl_reg; - int distance, open_circut, short_circut; - - e100_mdi_read(bdp, HWI_CONTROL_REG, bdp->phy_addr, &ctrl_reg); - - distance = ctrl_reg & HWI_TEST_DISTANCE; - open_circut = ctrl_reg & HWI_TEST_HIGHZ_PROBLEM; - short_circut = ctrl_reg & HWI_TEST_LOWZ_PROBLEM; - - if ((distance == bdp->saved_distance) && - (open_circut == bdp->saved_open_circut) && - (short_circut == bdp->saved_short_circut)) - bdp->saved_same++; - else { - bdp->saved_same = 0; - bdp->saved_distance = distance; - bdp->saved_open_circut = open_circut; - bdp->saved_short_circut = short_circut; - } - - if (bdp->saved_same == MAX_SAME_RESULTS) { - if ((open_circut && !(short_circut)) || - (!(open_circut) && short_circut)) { - - u8 near_end = ((distance * HWI_REGISTER_GRANULARITY) < - HWI_NEAR_END_BOUNDARY); - if (open_circut) { - if (near_end) - bdp->cable_status = "Open Circut Near End"; - else - bdp->cable_status = "Open Circut Far End"; - } else { - if (near_end) - bdp->cable_status = "Short Circut Near End"; - else - bdp->cable_status = "Short Circut Far End"; - } - goto done; - } - } - else if (bdp->saved_i == HWI_MAX_LOOP) { - bdp->cable_status = "Test failed"; - goto done; - } - - /* Do another hwi test */ - e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr, - (HWI_TEST_ENABLE | HWI_TEST_EXECUTE)); - bdp->saved_i++; - /* relaunch hwi timer in 1 msec */ - mod_timer(&(bdp->hwi_timer), jiffies + (HZ / 1000) ); - return; - -done: - e100_hwi_restore(bdp); - bdp->hwi_started = 0; - return; -} - -static void e100_hwi_restore(struct e100_private *bdp) -{ - u16 control = 0; - - /* Restore speed, duplex and autoneg before */ - /* hwi test, i.e., cable diagnostic */ - - /* Reset hwi test */ - e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr, HWI_RESET_ALL_MASK); - - if ((bdp->params.e100_speed_duplex == E100_AUTONEG) && - (bdp->rev_id >= D102_REV_ID)) - /* Enable MDI/MDI-X auto switching */ - e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr, - MDI_MDIX_AUTO_SWITCH_ENABLE); - - switch (bdp->params.e100_speed_duplex) { - case E100_SPEED_10_HALF: - break; - case E100_SPEED_10_FULL: - control = BMCR_FULLDPLX; - break; - case E100_SPEED_100_HALF: - control = BMCR_SPEED100; - break; - case E100_SPEED_100_FULL: - control = BMCR_SPEED100 | BMCR_FULLDPLX; - break; - case E100_AUTONEG: - control = BMCR_ANENABLE | BMCR_ANRESTART; - break; - } - /* Restore original speed/duplex */ - e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, control); - return; -} #ifdef E100_CU_DEBUG unsigned char diff -Nru a/drivers/net/e100/e100_proc.c b/drivers/net/e100/e100_proc.c --- a/drivers/net/e100/e100_proc.c Sun Feb 9 21:13:31 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,474 +0,0 @@ -/******************************************************************************* - - - Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. - - 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. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - Linux NICS - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 -*******************************************************************************/ - -/********************************************************************** -* * -* INTEL CORPORATION * -* * -* This software is supplied under the terms of the license included * -* above. All use of this driver must be in accordance with the terms * -* of that license. * -* * -* Module Name: e100_proc.c * -* * -* Abstract: Functions to handle the proc file system. * -* Create the proc directories and files and run read and * -* write requests from the user * -* * -* Environment: This file is intended to be specific to the Linux * -* operating system. * -* * -**********************************************************************/ - -#include - -#ifdef CONFIG_PROC_FS -#include "e100.h" -/* MDI sleep time is at least 50 ms, in jiffies */ -#define MDI_SLEEP_TIME ((HZ / 20) + 1) -/***************************************************************************/ -/* /proc File System Interaface Support Functions */ -/***************************************************************************/ - -static struct proc_dir_entry *adapters_proc_dir = 0; - -/* externs from e100_main.c */ -extern char e100_short_driver_name[]; -extern char e100_driver_version[]; -extern struct net_device_stats *e100_get_stats(struct net_device *dev); -extern char *e100_get_brand_msg(struct e100_private *bdp); -extern int e100_mdi_write(struct e100_private *, u32, u32, u16); - -static void e100_proc_cleanup(void); -static unsigned char e100_init_proc_dir(void); - -#define ADAPTERS_PROC_DIR "PRO_LAN_Adapters" -#define WRITE_BUF_MAX_LEN 20 -#define READ_BUF_MAX_LEN 256 -#define E100_PE_LEN 25 - -#define bdp_drv_off(off) (unsigned long)(offsetof(struct e100_private, drv_stats.off)) -#define bdp_prm_off(off) (unsigned long)(offsetof(struct e100_private, params.off)) - -typedef struct _e100_proc_entry { - char *name; - read_proc_t *read_proc; - write_proc_t *write_proc; - unsigned long offset; /* offset into bdp. ~0 means no value, pass NULL. */ -} e100_proc_entry; - -static int -generic_read(char *page, char **start, off_t off, int count, int *eof, int len) -{ - if (len <= off + count) - *eof = 1; - - *start = page + off; - len -= off; - if (len > count) - len = count; - - if (len < 0) - len = 0; - - return len; -} - -static int -read_ulong(char *page, char **start, off_t off, - int count, int *eof, unsigned long l) -{ - int len; - - len = sprintf(page, "%lu\n", l); - - return generic_read(page, start, off, count, eof, len); -} - -static int -read_gen_ulong(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - unsigned long val = 0; - - if (data) - val = *((unsigned long *) data); - - return read_ulong(page, start, off, count, eof, val); -} - -static int -read_hwaddr(char *page, char **start, off_t off, - int count, int *eof, unsigned char *hwaddr) -{ - int len; - - len = sprintf(page, "%02X:%02X:%02X:%02X:%02X:%02X\n", - hwaddr[0], hwaddr[1], hwaddr[2], - hwaddr[3], hwaddr[4], hwaddr[5]); - - return generic_read(page, start, off, count, eof, len); -} - -static int -read_descr(char *page, char **start, off_t off, int count, int *eof, void *data) -{ - struct e100_private *bdp = data; - int len; - - len = sprintf(page, "%s\n", bdp->id_string); - - return generic_read(page, start, off, count, eof, len); -} - -static int -read_permanent_hwaddr(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct e100_private *bdp = data; - unsigned char *hwaddr = bdp->perm_node_address; - - return read_hwaddr(page, start, off, count, eof, hwaddr); -} - -static int -read_part_number(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct e100_private *bdp = data; - int len; - - len = sprintf(page, "%06lx-%03x\n", - (unsigned long) (bdp->pwa_no >> 8), - (unsigned int) (bdp->pwa_no & 0xFF)); - - return generic_read(page, start, off, count, eof, len); -} - -static void -set_led(struct e100_private *bdp, u16 led_mdi_op) -{ - e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL, - bdp->phy_addr, led_mdi_op); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(MDI_SLEEP_TIME); - - /* turn led ownership to the chip */ - e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL, - bdp->phy_addr, PHY_82555_LED_NORMAL_CONTROL); -} - -static int -write_blink_led_timer(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct e100_private *bdp = data; - char s_blink_op[WRITE_BUF_MAX_LEN + 1]; - char *res; - unsigned long i_blink_op; - - if (!buffer) - return -EINVAL; - - if (count > WRITE_BUF_MAX_LEN) { - count = WRITE_BUF_MAX_LEN; - } - if (copy_from_user(s_blink_op, buffer, count)) - return -EFAULT; - s_blink_op[count] = '\0'; - i_blink_op = simple_strtoul(s_blink_op, &res, 0); - if (res == s_blink_op) { - return -EINVAL; - } - - switch (i_blink_op) { - - case LED_OFF: - set_led(bdp, PHY_82555_LED_OFF); - break; - case LED_ON: - if (bdp->rev_id >= D101MA_REV_ID) - set_led(bdp, PHY_82555_LED_ON_559); - else - set_led(bdp, PHY_82555_LED_ON_PRE_559); - - break; - default: - return -EINVAL; - } - - return count; -} - -static e100_proc_entry e100_proc_list[] = { - {"Description", read_descr, 0, 0}, - {"Permanent_HWaddr", read_permanent_hwaddr, 0, 0}, - {"Part_Number", read_part_number, 0, 0}, - {"\n",}, - {"Rx_TCP_Checksum_Good", read_gen_ulong, 0, ~0}, - {"Rx_TCP_Checksum_Bad", read_gen_ulong, 0, ~0}, - {"Tx_TCP_Checksum_Good", read_gen_ulong, 0, ~0}, - {"Tx_TCP_Checksum_Bad", read_gen_ulong, 0, ~0}, - {"\n",}, - {"Tx_Abort_Late_Coll", read_gen_ulong, 0, bdp_drv_off(tx_late_col)}, - {"Tx_Deferred_Ok", read_gen_ulong, 0, bdp_drv_off(tx_ok_defrd)}, - {"Tx_Single_Coll_Ok", read_gen_ulong, 0, bdp_drv_off(tx_one_retry)}, - {"Tx_Multi_Coll_Ok", read_gen_ulong, 0, bdp_drv_off(tx_mt_one_retry)}, - {"Rx_Long_Length_Errors", read_gen_ulong, 0, ~0}, - {"\n",}, - {"Tx_Flow_Control_Pause", read_gen_ulong, 0, bdp_drv_off(xmt_fc_pkts)}, - {"Rx_Flow_Control_Pause", read_gen_ulong, 0, bdp_drv_off(rcv_fc_pkts)}, - {"Rx_Flow_Control_Unsup", read_gen_ulong, 0, bdp_drv_off(rcv_fc_unsupported)}, - {"\n",}, - {"Tx_TCO_Packets", read_gen_ulong, 0, bdp_drv_off(xmt_tco_pkts)}, - {"Rx_TCO_Packets", read_gen_ulong, 0, bdp_drv_off(rcv_tco_pkts)}, - {"\n",}, - {"Rx_Interrupt_Packets", read_gen_ulong, 0, bdp_drv_off(rx_intr_pkts)}, - {"Identify_Adapter", 0, write_blink_led_timer, 0}, - {"", 0, 0, 0} -}; - -static int -read_info(char *page, char **start, off_t off, int count, int *eof, void *data) -{ - struct e100_private *bdp = data; - e100_proc_entry *pe; - int tmp; - void *val; - int len = 0; - - for (pe = e100_proc_list; pe->name[0]; pe++) { - if (pe->name[0] == '\n') { - len += sprintf(page + len, "\n"); - continue; - } - - if (pe->read_proc) { - if ((len + READ_BUF_MAX_LEN + E100_PE_LEN + 1) >= - PAGE_SIZE) - break; - - if (pe->offset != ~0) - val = ((char *) bdp) + pe->offset; - else - val = NULL; - - len += sprintf(page + len, "%-" - __MODULE_STRING(E100_PE_LEN) - "s ", pe->name); - len += pe->read_proc(page + len, start, 0, - READ_BUF_MAX_LEN + 1, &tmp, val); - } - } - - return generic_read(page, start, off, count, eof, len); -} - -static struct proc_dir_entry * -create_proc_rw(char *name, void *data, struct proc_dir_entry *parent, - read_proc_t * read_proc, write_proc_t * write_proc) -{ - struct proc_dir_entry *pdep; - mode_t mode = S_IFREG; - - if (write_proc) { - mode |= S_IWUSR; - if (read_proc) { - mode |= S_IRUSR; - } - - } else if (read_proc) { - mode |= S_IRUGO; - } - - if (!(pdep = create_proc_entry(name, mode, parent))) - return NULL; - - pdep->read_proc = read_proc; - pdep->write_proc = write_proc; - pdep->data = data; - return pdep; -} - -void -e100_remove_proc_subdir(struct e100_private *bdp, char *name) -{ - e100_proc_entry *pe; - char info[256]; - int len; - - /* If our root /proc dir was not created, there is nothing to remove */ - if (adapters_proc_dir == NULL) { - return; - } - - len = strlen(bdp->ifname); - strncpy(info, bdp->ifname, sizeof (info)); - strncat(info + len, ".info", sizeof (info) - len); - - if (bdp->proc_parent) { - for (pe = e100_proc_list; pe->name[0]; pe++) { - if (pe->name[0] == '\n') - continue; - - remove_proc_entry(pe->name, bdp->proc_parent); - } - - remove_proc_entry(bdp->ifname, adapters_proc_dir); - bdp->proc_parent = NULL; - } - - remove_proc_entry(info, adapters_proc_dir); - - /* try to remove the main /proc dir, if it's empty */ - e100_proc_cleanup(); -} - -int -e100_create_proc_subdir(struct e100_private *bdp) -{ - struct proc_dir_entry *dev_dir; - e100_proc_entry *pe; - char info[256]; - int len; - void *data; - - /* create the main /proc dir if needed */ - if (!adapters_proc_dir) { - if (!e100_init_proc_dir()) - return -ENOMEM; - } - - strncpy(info, bdp->ifname, sizeof (info)); - len = strlen(info); - strncat(info + len, ".info", sizeof (info) - len); - - /* info */ - if (!(create_proc_rw(info, bdp, adapters_proc_dir, read_info, 0))) { - e100_proc_cleanup(); - return -ENOMEM; - } - - dev_dir = create_proc_entry(bdp->ifname, S_IFDIR, - adapters_proc_dir); - bdp->proc_parent = dev_dir; - - if (!dev_dir) { - e100_remove_proc_subdir(bdp, bdp->ifname); - return -ENOMEM; - } - - for (pe = e100_proc_list; pe->name[0]; pe++) { - if (pe->name[0] == '\n') - continue; - - if (pe->offset != ~0) - data = ((char *) bdp) + pe->offset; - else - data = NULL; - - if (!(create_proc_rw(pe->name, data, dev_dir, - pe->read_proc, pe->write_proc))) { - e100_remove_proc_subdir(bdp, bdp->ifname); - return -ENOMEM; - } - } - - return 0; -} - -/**************************************************************************** - * Name: e100_init_proc_dir - * - * Description: This routine creates the top-level /proc directory for the - * driver in /proc/net - * - * Arguments: none - * - * Returns: true on success, false on fail - * - ***************************************************************************/ -static unsigned char -e100_init_proc_dir(void) -{ - int len; - - /* first check if adapters_proc_dir already exists */ - len = strlen(ADAPTERS_PROC_DIR); - for (adapters_proc_dir = proc_net->subdir; - adapters_proc_dir; adapters_proc_dir = adapters_proc_dir->next) { - - if ((adapters_proc_dir->namelen == len) && - (!memcmp(adapters_proc_dir->name, ADAPTERS_PROC_DIR, len))) - break; - } - - if (!adapters_proc_dir) - adapters_proc_dir = - create_proc_entry(ADAPTERS_PROC_DIR, S_IFDIR, proc_net); - - if (!adapters_proc_dir) - return false; - - return true; -} - -/**************************************************************************** - * Name: e100_proc_cleanup - * - * Description: This routine clears the top-level /proc directory, if empty. - * - * Arguments: none - * - * Returns: none - * - ***************************************************************************/ -static void -e100_proc_cleanup(void) -{ - struct proc_dir_entry *de; - - if (adapters_proc_dir == NULL) { - return; - } - - /* check if subdir list is empty before removing adapters_proc_dir */ - for (de = adapters_proc_dir->subdir; de; de = de->next) { - /* ignore . and .. */ - if (*(de->name) != '.') - break; - } - - if (de) - return; - - remove_proc_entry(ADAPTERS_PROC_DIR, proc_net); - adapters_proc_dir = NULL; -} - -#endif /* CONFIG_PROC_FS */ diff -Nru a/drivers/net/e1000/Makefile b/drivers/net/e1000/Makefile --- a/drivers/net/e1000/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/net/e1000/Makefile Sun Feb 9 21:13:28 2003 @@ -32,5 +32,4 @@ obj-$(CONFIG_E1000) += e1000.o -e1000-objs := e1000_main.o e1000_hw.o e1000_ethtool.o e1000_param.o \ - e1000_proc.o +e1000-objs := e1000_main.o e1000_hw.o e1000_ethtool.o e1000_param.o diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h --- a/drivers/net/e1000/e1000.h Sun Feb 9 21:13:28 2003 +++ b/drivers/net/e1000/e1000.h Sun Feb 9 21:13:28 2003 @@ -157,9 +157,6 @@ struct e1000_adapter { struct timer_list watchdog_timer; struct timer_list phy_info_timer; -#ifdef CONFIG_PROC_FS - struct list_head proc_list_head; -#endif struct vlan_group *vlgrp; char *id_string; uint32_t bd_number; diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c --- a/drivers/net/e1000/e1000_ethtool.c Sun Feb 9 21:13:32 2003 +++ b/drivers/net/e1000/e1000_ethtool.c Sun Feb 9 21:13:32 2003 @@ -39,6 +39,16 @@ extern void e1000_down(struct e1000_adapter *adapter); extern void e1000_reset(struct e1000_adapter *adapter); +static char e1000_gstrings_stats[][ETH_GSTRING_LEN] = { + "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors", + "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions", + "rx_length_errors", "rx_over_errors", "rx_crc_errors", + "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors", + "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors", + "tx_heartbeat_errors", "tx_window_errors", +}; +#define E1000_STATS_LEN sizeof(e1000_gstrings_stats) / ETH_GSTRING_LEN + static void e1000_ethtool_gset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd) { @@ -173,6 +183,7 @@ strncpy(drvinfo->version, e1000_driver_version, 32); strncpy(drvinfo->fw_version, "N/A", 32); strncpy(drvinfo->bus_info, adapter->pdev->slot_name, 32); + drvinfo->n_stats = E1000_STATS_LEN; #define E1000_REGS_LEN 32 drvinfo->regdump_len = E1000_REGS_LEN * sizeof(uint32_t); drvinfo->eedump_len = e1000_eeprom_size(&adapter->hw); @@ -209,18 +220,24 @@ struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff) { struct e1000_hw *hw = &adapter->hw; - int i, max_len, first_word, last_word; - - if(eeprom->len == 0) - return -EINVAL; + int max_len, first_word, last_word; + int ret_val = 0; + int i; + + if(eeprom->len == 0) { + ret_val = -EINVAL; + goto geeprom_error; + } eeprom->magic = hw->vendor_id | (hw->device_id << 16); max_len = e1000_eeprom_size(hw); - if(eeprom->offset > eeprom->offset + eeprom->len) - return -EINVAL; - + if(eeprom->offset > eeprom->offset + eeprom->len) { + ret_val = -EINVAL; + goto geeprom_error; + } + if((eeprom->offset + eeprom->len) > max_len) eeprom->len = (max_len - eeprom->offset); @@ -230,7 +247,8 @@ for(i = 0; i <= (last_word - first_word); i++) e1000_read_eeprom(hw, first_word + i, &eeprom_buff[i]); - return 0; +geeprom_error: + return ret_val; } static int @@ -238,9 +256,10 @@ struct ethtool_eeprom *eeprom, void *user_data) { struct e1000_hw *hw = &adapter->hw; - uint16_t eeprom_buff[256]; - int i, max_len, first_word, last_word; + uint16_t *eeprom_buff; + int max_len, first_word, last_word; void *ptr; + int i; if(eeprom->len == 0) return -EOPNOTSUPP; @@ -255,6 +274,10 @@ first_word = eeprom->offset >> 1; last_word = (eeprom->offset + eeprom->len - 1) >> 1; + eeprom_buff = kmalloc(max_len, GFP_KERNEL); + if(eeprom_buff == NULL) + return -ENOMEM; + ptr = (void *)eeprom_buff; if(eeprom->offset & 1) { @@ -269,8 +292,10 @@ e1000_read_eeprom(hw, last_word, &eeprom_buff[last_word - first_word]); } - if(copy_from_user(ptr, user_data, eeprom->len)) + if(copy_from_user(ptr, user_data, eeprom->len)) { + kfree(eeprom_buff); return -EFAULT; + } for(i = 0; i <= (last_word - first_word); i++) e1000_write_eeprom(hw, first_word + i, eeprom_buff[i]); @@ -279,6 +304,8 @@ if(first_word <= EEPROM_CHECKSUM_REG) e1000_update_eeprom_checksum(hw); + kfree(eeprom_buff); + return 0; } @@ -438,6 +465,28 @@ return -EFAULT; return 0; } + case ETHTOOL_GSTRINGS: { + struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS }; + char *strings = NULL; + + if(copy_from_user(&gstrings, addr, sizeof(gstrings))) + return -EFAULT; + switch(gstrings.string_set) { + case ETH_SS_STATS: + gstrings.len = E1000_STATS_LEN; + strings = *e1000_gstrings_stats; + break; + default: + return -EOPNOTSUPP; + } + if(copy_to_user(addr, &gstrings, sizeof(gstrings))) + return -EFAULT; + addr += offsetof(struct ethtool_gstrings, data); + if(copy_to_user(addr, strings, + gstrings.len * ETH_GSTRING_LEN)) + return -EFAULT; + return 0; + } case ETHTOOL_GREGS: { struct ethtool_regs regs = {ETHTOOL_GREGS}; uint32_t regs_buff[E1000_REGS_LEN]; @@ -493,26 +542,40 @@ } case ETHTOOL_GEEPROM: { struct ethtool_eeprom eeprom = {ETHTOOL_GEEPROM}; - uint16_t eeprom_buff[256]; + uint16_t *eeprom_buff; void *ptr; - int err; + int max_len, err = 0; - if(copy_from_user(&eeprom, addr, sizeof(eeprom))) - return -EFAULT; + max_len = e1000_eeprom_size(&adapter->hw); - if((err = e1000_ethtool_geeprom(adapter, - &eeprom, eeprom_buff))) - return err; + eeprom_buff = kmalloc(max_len, GFP_KERNEL); - if(copy_to_user(addr, &eeprom, sizeof(eeprom))) - return -EFAULT; + if(eeprom_buff == NULL) + return -ENOMEM; + + if(copy_from_user(&eeprom, addr, sizeof(eeprom))) { + err = -EFAULT; + goto err_geeprom_ioctl; + } + + if((err = e1000_ethtool_geeprom(adapter, &eeprom, + eeprom_buff))) + goto err_geeprom_ioctl; + + if(copy_to_user(addr, &eeprom, sizeof(eeprom))) { + err = -EFAULT; + goto err_geeprom_ioctl; + } addr += offsetof(struct ethtool_eeprom, data); ptr = ((void *)eeprom_buff) + (eeprom.offset & 1); if(copy_to_user(addr, ptr, eeprom.len)) - return -EFAULT; - return 0; + err = -EFAULT; + +err_geeprom_ioctl: + kfree(eeprom_buff); + return err; } case ETHTOOL_SEEPROM: { struct ethtool_eeprom eeprom; @@ -525,6 +588,20 @@ addr += offsetof(struct ethtool_eeprom, data); return e1000_ethtool_seeprom(adapter, &eeprom, addr); + } + case ETHTOOL_GSTATS: { + struct { + struct ethtool_stats cmd; + uint64_t data[E1000_STATS_LEN]; + } stats = { {ETHTOOL_GSTATS, E1000_STATS_LEN} }; + int i; + + for(i = 0; i < E1000_STATS_LEN; i++) + stats.data[i] = + ((unsigned long *)&adapter->net_stats)[i]; + if(copy_to_user(addr, &stats, sizeof(stats))) + return -EFAULT; + return 0; } default: return -EOPNOTSUPP; diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c --- a/drivers/net/e1000/e1000_main.c Sun Feb 9 21:13:31 2003 +++ b/drivers/net/e1000/e1000_main.c Sun Feb 9 21:13:31 2003 @@ -59,7 +59,7 @@ char e1000_driver_name[] = "e1000"; char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; -char e1000_driver_version[] = "4.4.19-k1"; +char e1000_driver_version[] = "4.4.19-k3"; char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation."; /* e1000_pci_tbl - PCI Device ID Table @@ -171,7 +171,6 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter); static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); -static int e1000_notify_netdev(struct notifier_block *, unsigned long event, void *ptr); static int e1000_suspend(struct pci_dev *pdev, uint32_t state); #ifdef CONFIG_PM static int e1000_resume(struct pci_dev *pdev); @@ -183,17 +182,9 @@ .priority = 0 }; -struct notifier_block e1000_notifier_netdev = { - .notifier_call = e1000_notify_netdev, - .next = NULL, - .priority = 0 -}; - /* Exported from other modules */ extern void e1000_check_options(struct e1000_adapter *adapter); -extern void e1000_proc_dev_setup(struct e1000_adapter *adapter); -extern void e1000_proc_dev_free(struct e1000_adapter *adapter); extern int e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr); static struct pci_driver e1000_driver = { @@ -229,10 +220,8 @@ printk(KERN_INFO "%s\n", e1000_copyright); ret = pci_module_init(&e1000_driver); - if(ret >= 0) { + if(ret >= 0) register_reboot_notifier(&e1000_notifier_reboot); - register_netdevice_notifier(&e1000_notifier_netdev); - } return ret; } @@ -249,7 +238,6 @@ e1000_exit_module(void) { unregister_reboot_notifier(&e1000_notifier_reboot); - unregister_netdevice_notifier(&e1000_notifier_netdev); pci_unregister_driver(&e1000_driver); } @@ -433,10 +421,8 @@ netdev->features = NETIF_F_SG; } -#ifdef NETIF_F_TSO if(adapter->hw.mac_type >= e1000_82544) netdev->features |= NETIF_F_TSO; -#endif if(pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; @@ -490,7 +476,6 @@ printk(KERN_INFO "%s: %s\n", netdev->name, adapter->id_string); e1000_check_options(adapter); - e1000_proc_dev_setup(adapter); /* Initial Wake on LAN setting * If APM wake is enabled in the EEPROM, @@ -548,8 +533,6 @@ e1000_phy_hw_reset(&adapter->hw); - e1000_proc_dev_free(adapter); - iounmap(adapter->hw.hw_addr); pci_release_regions(pdev); @@ -1314,7 +1297,6 @@ static inline boolean_t e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb, int tx_flags) { -#ifdef NETIF_F_TSO struct e1000_context_desc *context_desc; int i; uint8_t ipcss, ipcso, tucss, tucso, hdr_len; @@ -1358,7 +1340,6 @@ return TRUE; } -#endif return FALSE; } @@ -1398,6 +1379,8 @@ { struct e1000_desc_ring *tx_ring = &adapter->tx_ring; int len, offset, size, count, i; + int tso = skb_shinfo(skb)->tso_size; + int nr_frags = skb_shinfo(skb)->nr_frags; int f; len = skb->len - skb->data_len; @@ -1409,6 +1392,10 @@ while(len) { i = (i + 1) % tx_ring->count; size = min(len, adapter->max_data_per_txd); + /* Workaround for premature desc write-backs + * in TSO mode. Append 4-byte sentinel desc */ + if(tso && !nr_frags && size == len && size > 4) + size -= 4; tx_ring->buffer_info[i].length = size; tx_ring->buffer_info[i].dma = pci_map_single(adapter->pdev, @@ -1422,7 +1409,7 @@ count++; } - for(f = 0; f < skb_shinfo(skb)->nr_frags; f++) { + for(f = 0; f < nr_frags; f++) { struct skb_frag_struct *frag; frag = &skb_shinfo(skb)->frags[f]; @@ -1432,6 +1419,10 @@ while(len) { i = (i + 1) % tx_ring->count; size = min(len, adapter->max_data_per_txd); + /* Workaround for premature desc write-backs + * in TSO mode. Append 4-byte sentinel desc */ + if(tso && f == (nr_frags-1) && size == len && size > 4) + size -= 4; tx_ring->buffer_info[i].length = size; tx_ring->buffer_info[i].dma = pci_map_page(adapter->pdev, @@ -1439,6 +1430,7 @@ frag->page_offset + offset, size, PCI_DMA_TODEVICE); + tx_ring->buffer_info[i].time_stamp = jiffies; len -= size; offset += size; @@ -1520,13 +1512,8 @@ for(f = 0; f < skb_shinfo(skb)->nr_frags; f++) count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size, adapter->max_data_per_txd); -#ifdef NETIF_F_TSO if((skb_shinfo(skb)->tso_size) || (skb->ip_summed == CHECKSUM_HW)) count++; -#else - if(skb->ip_summed == CHECKSUM_HW) - count++; -#endif if(E1000_DESC_UNUSED(&adapter->tx_ring) < count) { netif_stop_queue(netdev); @@ -1823,7 +1810,10 @@ #ifdef CONFIG_E1000_NAPI if (netif_rx_schedule_prep(netdev)) { - e1000_irq_disable(adapter); + /* Disable interrupts and enable polling */ + atomic_inc(&adapter->irq_sem); + E1000_WRITE_REG(&adapter->hw, IMC, ~0); + E1000_WRITE_FLUSH(&adapter->hw); __netif_rx_schedule(netdev); } #else @@ -2425,29 +2415,6 @@ if(pci_dev_driver(pdev) == &e1000_driver) e1000_suspend(pdev, 3); } - } - return NOTIFY_DONE; -} - -static int -e1000_notify_netdev(struct notifier_block *nb, unsigned long event, void *p) -{ - struct e1000_adapter *adapter; - struct net_device *netdev = p; - if(netdev == NULL) - return NOTIFY_DONE; - - switch(event) { - case NETDEV_CHANGENAME: - if(netdev->open == e1000_open) { - adapter = netdev->priv; - /* rename the proc nodes the easy way */ - e1000_proc_dev_free(adapter); - memcpy(adapter->ifname, netdev->name, IFNAMSIZ); - adapter->ifname[IFNAMSIZ-1] = 0; - e1000_proc_dev_setup(adapter); - } - break; } return NOTIFY_DONE; } diff -Nru a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h --- a/drivers/net/e1000/e1000_osdep.h Sun Feb 9 21:13:29 2003 +++ b/drivers/net/e1000/e1000_osdep.h Sun Feb 9 21:13:29 2003 @@ -27,7 +27,7 @@ *******************************************************************************/ -/* glue for the OS independant part of e1000 +/* glue for the OS independent part of e1000 * includes register access macros */ diff -Nru a/drivers/net/e1000/e1000_proc.c b/drivers/net/e1000/e1000_proc.c --- a/drivers/net/e1000/e1000_proc.c Sun Feb 9 21:13:34 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,702 +0,0 @@ -/******************************************************************************* - - - Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved. - - 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. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - Linux NICS - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - -/* - * Proc fs support. - * - * Read-only files created by driver (if CONFIG_PROC_FS): - * - * /proc/net/PRO_LAN_Adapters/.info - * /proc/net/PRO_LAN_Adapters// - * - * where is the system device name, i.e eth0. - * is the driver attribute name. - * - * There is one file for each driver attribute, where the contents - * of the file is the attribute value. The ethx.info file contains - * a list of all driver attributes in one file. - * - */ - -#include "e1000.h" - -#ifdef CONFIG_PROC_FS - -#include - -#define ADAPTERS_PROC_DIR "PRO_LAN_Adapters" -#define TAG_MAX_LENGTH 32 -#define LINE_MAX_LENGTH 80 -#define FIELD_MAX_LENGTH LINE_MAX_LENGTH - TAG_MAX_LENGTH - 3 - -extern char e1000_driver_name[]; -extern char e1000_driver_version[]; - -/* - * The list of driver proc attributes is stored in a proc_list link - * list. The list is build with proc_list_setup and is used to - * build the proc fs nodes. The private data for each node is the - * corresponding link in the link list. - */ - -struct proc_list { - struct list_head list; /* link list */ - char tag[TAG_MAX_LENGTH + 1]; /* attribute name */ - void *data; /* attribute data */ - size_t len; /* sizeof data */ - char *(*func)(void *, size_t, char *); /* format data func */ -}; - -static int -e1000_proc_read(char *page, char **start, off_t off, int count, int *eof) -{ - int len = strlen(page); - - page[len++] = '\n'; - - if(len <= off + count) - *eof = 1; - *start = page + off; - len -= off; - if(len > count) - len = count; - if(len < 0) - len = 0; - - return len; -} - -static int -e1000_proc_info_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct list_head *proc_list_head = data, *curr; - struct proc_list *elem; - char *p = page; - char buf[FIELD_MAX_LENGTH + 1]; - - list_for_each(curr, proc_list_head) { - elem = list_entry(curr, struct proc_list, list); - - if (p - page + LINE_MAX_LENGTH >= PAGE_SIZE) - break; - - if(!strlen(elem->tag)) - p += sprintf(p, "\n"); - else - p += sprintf(p, "%-*.*s %.*s\n", - TAG_MAX_LENGTH, TAG_MAX_LENGTH, - elem->tag, FIELD_MAX_LENGTH, - elem->func(elem->data, elem->len, buf)); - } - - *p = '\0'; - - return e1000_proc_read(page, start, off, count, eof); -} - -static int -e1000_proc_single_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct proc_list *elem = data; - - sprintf(page, "%.*s", FIELD_MAX_LENGTH, elem->func(elem->data, - elem->len, page)); - - return e1000_proc_read(page, start, off, count, eof); -} - -static void -e1000_proc_dirs_free(char *name, struct list_head *proc_list_head) -{ - struct proc_dir_entry *intel_proc_dir, *proc_dir; - char info_name[strlen(name) + strlen(".info")]; - - for(intel_proc_dir = proc_net->subdir; intel_proc_dir; - intel_proc_dir = intel_proc_dir->next) { - if((intel_proc_dir->namelen == strlen(ADAPTERS_PROC_DIR)) && - !memcmp(intel_proc_dir->name, ADAPTERS_PROC_DIR, strlen(ADAPTERS_PROC_DIR))) - break; - } - - if(!intel_proc_dir) - return; - - for(proc_dir = intel_proc_dir->subdir; proc_dir; - proc_dir = proc_dir->next) { - if ((proc_dir->namelen == strlen(name)) && - !memcmp(proc_dir->name, name, strlen(name))) - break; - } - - if(proc_dir) { - struct list_head *curr; - struct proc_list *elem; - - list_for_each(curr, proc_list_head) { - elem = list_entry(curr, struct proc_list, list); - remove_proc_entry(elem->tag, proc_dir); - } - - strcpy(info_name, name); - strcat(info_name, ".info"); - - remove_proc_entry(info_name, intel_proc_dir); - remove_proc_entry(name, intel_proc_dir); - } - - /* If the intel dir is empty, remove it */ - - for(proc_dir = intel_proc_dir->subdir; proc_dir; - proc_dir = proc_dir->next) { - - /* ignore . and .. */ - - if(*(proc_dir->name) == '.') - continue; - break; - } - - if(!proc_dir) - remove_proc_entry(ADAPTERS_PROC_DIR, proc_net); -} - - -static int -e1000_proc_singles_create(struct proc_dir_entry *parent, - struct list_head *proc_list_head) -{ - struct list_head *curr; - struct proc_list *elem; - - list_for_each(curr, proc_list_head) { - struct proc_dir_entry *proc_entry; - - elem = list_entry(curr, struct proc_list, list); - - if(!strlen(elem->tag)) - continue; - - if(!(proc_entry = - create_proc_entry(elem->tag, S_IFREG, parent))) - return 0; - - proc_entry->read_proc = e1000_proc_single_read; - proc_entry->data = elem; - SET_MODULE_OWNER(proc_entry); - } - - return 1; -} - -static void -e1000_proc_dirs_create(void *data, char *name, - struct list_head *proc_list_head) -{ - struct proc_dir_entry *intel_proc_dir, *proc_dir, *info_entry; - char info_name[strlen(name) + strlen(".info")]; - - for(intel_proc_dir = proc_net->subdir; intel_proc_dir; - intel_proc_dir = intel_proc_dir->next) { - if((intel_proc_dir->namelen == strlen(ADAPTERS_PROC_DIR)) && - !memcmp(intel_proc_dir->name, ADAPTERS_PROC_DIR, strlen(ADAPTERS_PROC_DIR))) - break; - } - - if(!intel_proc_dir) - if(!(intel_proc_dir = - create_proc_entry(ADAPTERS_PROC_DIR, - S_IFDIR, proc_net))) - return; - - if(!(proc_dir = - create_proc_entry(name, S_IFDIR, intel_proc_dir))) - return; - SET_MODULE_OWNER(proc_dir); - - if(!e1000_proc_singles_create(proc_dir, proc_list_head)) - return; - - strcpy(info_name, name); - strcat(info_name, ".info"); - - if(!(info_entry = - create_proc_entry(info_name, S_IFREG, intel_proc_dir))) - return; - SET_MODULE_OWNER(info_entry); - - info_entry->read_proc = e1000_proc_info_read; - info_entry->data = proc_list_head; -} - -static void -e1000_proc_list_add(struct list_head *proc_list_head, char *tag, - void *data, size_t len, - char *(*func)(void *, size_t, char *)) -{ - struct proc_list *new = (struct proc_list *) - kmalloc(sizeof(struct proc_list), GFP_KERNEL); - - if(!new) - return; - - strncpy(new->tag, tag, TAG_MAX_LENGTH); - new->data = data; - new->len = len; - new->func = func; - - list_add_tail(&new->list, proc_list_head); -} - -static void -e1000_proc_list_free(struct list_head *proc_list_head) -{ - struct proc_list *elem; - - while(!list_empty(proc_list_head)) { - elem = list_entry(proc_list_head->next, struct proc_list, list); - list_del(&elem->list); - kfree(elem); - } -} - -/* - * General purpose formating functions - */ - -static char * -e1000_proc_str(void *data, size_t len, char *buf) -{ - sprintf(buf, "%s", (char *)data); - return buf; -} - -static char * -e1000_proc_hex(void *data, size_t len, char *buf) -{ - switch(len) { - case sizeof(uint8_t): - sprintf(buf, "0x%02x", *(uint8_t *)data); - break; - case sizeof(uint16_t): - sprintf(buf, "0x%04x", *(uint16_t *)data); - break; - case sizeof(uint32_t): - sprintf(buf, "0x%08x", *(uint32_t *)data); - break; - case sizeof(uint64_t): - sprintf(buf, "0x%08Lx", (unsigned long long)*(uint64_t *)data); - break; - } - return buf; -} - -static char * -e1000_proc_unsigned(void *data, size_t len, char *buf) -{ - switch(len) { - case sizeof(uint8_t): - sprintf(buf, "%u", *(uint8_t *)data); - break; - case sizeof(uint16_t): - sprintf(buf, "%u", *(uint16_t *)data); - break; - case sizeof(uint32_t): - sprintf(buf, "%u", *(uint32_t *)data); - break; - case sizeof(uint64_t): - sprintf(buf, "%Lu", (unsigned long long)*(uint64_t *)data); - break; - } - return buf; -} - -/* - * Specific formating functions - */ - -static char * -e1000_proc_part_number(void *data, size_t len, char *buf) -{ - sprintf(buf, "%06x-%03x", *(uint32_t *)data >> 8, - *(uint32_t *)data & 0x000000FF); - return buf; -} - -static char * -e1000_proc_slot(void *data, size_t len, char *buf) -{ - struct e1000_adapter *adapter = data; - sprintf(buf, "%u", PCI_SLOT(adapter->pdev->devfn)); - return buf; -} - -static char * -e1000_proc_bus_type(void *data, size_t len, char *buf) -{ - e1000_bus_type bus_type = *(e1000_bus_type *)data; - sprintf(buf, - bus_type == e1000_bus_type_pci ? "PCI" : - bus_type == e1000_bus_type_pcix ? "PCI-X" : - "UNKNOWN"); - return buf; -} - -static char * -e1000_proc_bus_speed(void *data, size_t len, char *buf) -{ - e1000_bus_speed bus_speed = *(e1000_bus_speed *)data; - sprintf(buf, - bus_speed == e1000_bus_speed_33 ? "33MHz" : - bus_speed == e1000_bus_speed_66 ? "66MHz" : - bus_speed == e1000_bus_speed_100 ? "100MHz" : - bus_speed == e1000_bus_speed_133 ? "133MHz" : - "UNKNOWN"); - return buf; -} - -static char * -e1000_proc_bus_width(void *data, size_t len, char *buf) -{ - e1000_bus_width bus_width = *(e1000_bus_width *)data; - sprintf(buf, - bus_width == e1000_bus_width_32 ? "32-bit" : - bus_width == e1000_bus_width_64 ? "64-bit" : - "UNKNOWN"); - return buf; -} - -static char * -e1000_proc_hwaddr(void *data, size_t len, char *buf) -{ - unsigned char *hwaddr = data; - sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", - hwaddr[0], hwaddr[1], hwaddr[2], - hwaddr[3], hwaddr[4], hwaddr[5]); - return buf; -} - -static char * -e1000_proc_link(void *data, size_t len, char *buf) -{ - struct e1000_adapter *adapter = data; - sprintf(buf, netif_running(adapter->netdev) ? - netif_carrier_ok(adapter->netdev) ? - "up" : "down" : "N/A"); - return buf; -} - -static char * -e1000_proc_link_speed(void *data, size_t len, char *buf) -{ - uint16_t link_speed = *(uint16_t *)data; - sprintf(buf, link_speed ? "%u" : "N/A", link_speed); - return buf; -} - -static char * -e1000_proc_link_duplex(void *data, size_t len, char *buf) -{ - uint16_t link_duplex = *(uint16_t *)data; - sprintf(buf, - link_duplex == FULL_DUPLEX ? "Full" : - link_duplex == HALF_DUPLEX ? "Half" : - "N/A"); - return buf; -} - -static char * -e1000_proc_state(void *data, size_t len, char *buf) -{ - struct e1000_adapter *adapter = data; - sprintf(buf, adapter->netdev->flags & IFF_UP ? "up" : "down"); - return buf; -} - -static char * -e1000_proc_media_type(void *data, size_t len, char *buf) -{ - struct e1000_adapter *adapter = data; - sprintf(buf, - adapter->hw.media_type == e1000_media_type_copper ? - "Copper" : "Fiber"); - return buf; -} - -static char * -e1000_proc_cable_length(void *data, size_t len, char *buf) -{ - struct e1000_adapter *adapter = data; - e1000_cable_length cable_length = adapter->phy_info.cable_length; - sprintf(buf, "%s%s", - cable_length == e1000_cable_length_50 ? "0-50" : - cable_length == e1000_cable_length_50_80 ? "50-80" : - cable_length == e1000_cable_length_80_110 ? "80-110" : - cable_length == e1000_cable_length_110_140 ? "110-140" : - cable_length == e1000_cable_length_140 ? "> 140" : - "Unknown", - cable_length != e1000_cable_length_undefined ? - " Meters (+/- 20 Meters)" : ""); - return buf; -} - -static char * -e1000_proc_extended(void *data, size_t len, char *buf) -{ - struct e1000_adapter *adapter = data; - e1000_10bt_ext_dist_enable dist_enable = - adapter->phy_info.extended_10bt_distance; - sprintf(buf, - dist_enable == e1000_10bt_ext_dist_enable_normal ? "Disabled" : - dist_enable == e1000_10bt_ext_dist_enable_lower ? "Enabled" : - "Unknown"); - return buf; -} - -static char * -e1000_proc_cable_polarity(void *data, size_t len, char *buf) -{ - struct e1000_adapter *adapter = data; - e1000_rev_polarity polarity = adapter->phy_info.cable_polarity; - sprintf(buf, - polarity == e1000_rev_polarity_normal ? "Normal" : - polarity == e1000_rev_polarity_reversed ? "Reversed" : - "Unknown"); - return buf; -} - -static char * -e1000_proc_polarity_correction(void *data, size_t len, char *buf) -{ - struct e1000_adapter *adapter = data; - e1000_polarity_reversal correction = - adapter->phy_info.polarity_correction; - sprintf(buf, - correction == e1000_polarity_reversal_enabled ? "Disabled" : - correction == e1000_polarity_reversal_disabled ? "Enabled" : - "Unknown"); - return buf; -} - -static char * -e1000_proc_mdi_x_enabled(void *data, size_t len, char *buf) -{ - struct e1000_adapter *adapter = data; - e1000_auto_x_mode mdix_mode = adapter->phy_info.mdix_mode; - sprintf(buf, - mdix_mode == e1000_auto_x_mode_manual_mdi ? "MDI" : - mdix_mode == e1000_auto_x_mode_manual_mdix ? "MDI-X" : - "Unknown"); - return buf; -} - -static char * -e1000_proc_rx_status(void *data, size_t len, char *buf) -{ - e1000_1000t_rx_status rx_status = *(e1000_1000t_rx_status *)data; - sprintf(buf, - rx_status == e1000_1000t_rx_status_not_ok ? "NOT_OK" : - rx_status == e1000_1000t_rx_status_ok ? "OK" : - "Unknown"); - return buf; -} - -/* - * e1000_proc_list_setup - build link list of proc praramters - * @adapter: board private structure - * - * Order matters - ethx.info entries are ordered in the order links - * are added to list. - */ - -#define LIST_ADD_F(T,D,F) \ - e1000_proc_list_add(proc_list_head, (T), (D), sizeof(*(D)), (F)) -#define LIST_ADD_BLANK() LIST_ADD_F("", NULL, NULL) -#define LIST_ADD_S(T,D) LIST_ADD_F((T), (D), e1000_proc_str) -#define LIST_ADD_H(T,D) LIST_ADD_F((T), (D), e1000_proc_hex) -#define LIST_ADD_U(T,D) LIST_ADD_F((T), (D), e1000_proc_unsigned) - -static void -e1000_proc_list_setup(struct e1000_adapter *adapter) -{ - struct e1000_hw *hw = &adapter->hw; - struct list_head *proc_list_head = &adapter->proc_list_head; - - INIT_LIST_HEAD(proc_list_head); - - LIST_ADD_S("Description", adapter->id_string); - LIST_ADD_F("Part_Number", &adapter->part_num, e1000_proc_part_number); - LIST_ADD_S("Driver_Name", e1000_driver_name); - LIST_ADD_S("Driver_Version", e1000_driver_version); - LIST_ADD_H("PCI_Vendor", &hw->vendor_id); - LIST_ADD_H("PCI_Device_ID", &hw->device_id); - LIST_ADD_H("PCI_Subsystem_Vendor", &hw->subsystem_vendor_id); - LIST_ADD_H("PCI_Subsystem_ID", &hw->subsystem_id); - LIST_ADD_H("PCI_Revision_ID", &hw->revision_id); - LIST_ADD_U("PCI_Bus", &adapter->pdev->bus->number); - LIST_ADD_F("PCI_Slot", adapter, e1000_proc_slot); - - if(adapter->hw.mac_type >= e1000_82543) { - LIST_ADD_F("PCI_Bus_Type", - &hw->bus_type, e1000_proc_bus_type); - LIST_ADD_F("PCI_Bus_Speed", - &hw->bus_speed, e1000_proc_bus_speed); - LIST_ADD_F("PCI_Bus_Width", - &hw->bus_width, e1000_proc_bus_width); - } - - LIST_ADD_U("IRQ", &adapter->pdev->irq); - LIST_ADD_S("System_Device_Name", adapter->ifname); - LIST_ADD_F("Current_HWaddr", - adapter->netdev->dev_addr, e1000_proc_hwaddr); - LIST_ADD_F("Permanent_HWaddr", - adapter->hw.perm_mac_addr, e1000_proc_hwaddr); - - LIST_ADD_BLANK(); - - LIST_ADD_F("Link", adapter, e1000_proc_link); - LIST_ADD_F("Speed", &adapter->link_speed, e1000_proc_link_speed); - LIST_ADD_F("Duplex", &adapter->link_duplex, e1000_proc_link_duplex); - LIST_ADD_F("State", adapter, e1000_proc_state); - - LIST_ADD_BLANK(); - - /* Standard net device stats */ - LIST_ADD_U("Rx_Packets", &adapter->net_stats.rx_packets); - LIST_ADD_U("Tx_Packets", &adapter->net_stats.tx_packets); - LIST_ADD_U("Rx_Bytes", &adapter->net_stats.rx_bytes); - LIST_ADD_U("Tx_Bytes", &adapter->net_stats.tx_bytes); - LIST_ADD_U("Rx_Errors", &adapter->net_stats.rx_errors); - LIST_ADD_U("Tx_Errors", &adapter->net_stats.tx_errors); - LIST_ADD_U("Rx_Dropped", &adapter->net_stats.rx_dropped); - LIST_ADD_U("Tx_Dropped", &adapter->net_stats.tx_dropped); - - LIST_ADD_U("Multicast", &adapter->net_stats.multicast); - LIST_ADD_U("Collisions", &adapter->net_stats.collisions); - - LIST_ADD_U("Rx_Length_Errors", &adapter->net_stats.rx_length_errors); - LIST_ADD_U("Rx_Over_Errors", &adapter->net_stats.rx_over_errors); - LIST_ADD_U("Rx_CRC_Errors", &adapter->net_stats.rx_crc_errors); - LIST_ADD_U("Rx_Frame_Errors", &adapter->net_stats.rx_frame_errors); - LIST_ADD_U("Rx_FIFO_Errors", &adapter->net_stats.rx_fifo_errors); - LIST_ADD_U("Rx_Missed_Errors", &adapter->net_stats.rx_missed_errors); - - LIST_ADD_U("Tx_Aborted_Errors", &adapter->net_stats.tx_aborted_errors); - LIST_ADD_U("Tx_Carrier_Errors", &adapter->net_stats.tx_carrier_errors); - LIST_ADD_U("Tx_FIFO_Errors", &adapter->net_stats.tx_fifo_errors); - LIST_ADD_U("Tx_Heartbeat_Errors", - &adapter->net_stats.tx_heartbeat_errors); - LIST_ADD_U("Tx_Window_Errors", &adapter->net_stats.tx_window_errors); - - /* 8254x-specific stats */ - LIST_ADD_U("Tx_Abort_Late_Coll", &adapter->stats.latecol); - LIST_ADD_U("Tx_Deferred_Ok", &adapter->stats.dc); - LIST_ADD_U("Tx_Single_Coll_Ok", &adapter->stats.scc); - LIST_ADD_U("Tx_Multi_Coll_Ok", &adapter->stats.mcc); - LIST_ADD_U("Rx_Long_Length_Errors", &adapter->stats.roc); - LIST_ADD_U("Rx_Short_Length_Errors", &adapter->stats.ruc); - - /* The 82542 does not have some of these stats */ - if(adapter->hw.mac_type >= e1000_82543) { - LIST_ADD_U("Rx_Align_Errors", &adapter->stats.algnerrc); - LIST_ADD_U("Tx_TCP_Seg_Good", &adapter->stats.tsctc); - LIST_ADD_U("Tx_TCP_Seg_Failed", &adapter->stats.tsctfc); - } - - LIST_ADD_U("Rx_Flow_Control_XON", &adapter->stats.xonrxc); - LIST_ADD_U("Rx_Flow_Control_XOFF", &adapter->stats.xoffrxc); - LIST_ADD_U("Tx_Flow_Control_XON", &adapter->stats.xontxc); - LIST_ADD_U("Tx_Flow_Control_XOFF", &adapter->stats.xofftxc); - LIST_ADD_U("Rx_CSum_Offload_Good", &adapter->hw_csum_good); - LIST_ADD_U("Rx_CSum_Offload_Errors", &adapter->hw_csum_err); - - LIST_ADD_BLANK(); - - /* Cable diags */ - LIST_ADD_F("PHY_Media_Type", adapter, e1000_proc_media_type); - if(adapter->hw.media_type == e1000_media_type_copper) { - LIST_ADD_F("PHY_Cable_Length", - adapter, e1000_proc_cable_length); - LIST_ADD_F("PHY_Extended_10Base_T_Distance", - adapter, e1000_proc_extended); - LIST_ADD_F("PHY_Cable_Polarity", - adapter, e1000_proc_cable_polarity); - LIST_ADD_F("PHY_Disable_Polarity_Correction", - adapter, e1000_proc_polarity_correction); - LIST_ADD_U("PHY_Idle_Errors", - &adapter->phy_stats.idle_errors); - LIST_ADD_U("PHY_Receive_Errors", - &adapter->phy_stats.receive_errors); - LIST_ADD_F("PHY_MDI_X_Enabled", - adapter, e1000_proc_mdi_x_enabled); - LIST_ADD_F("PHY_Local_Receiver_Status", - &adapter->phy_info.local_rx, - e1000_proc_rx_status); - LIST_ADD_F("PHY_Remote_Receiver_Status", - &adapter->phy_info.remote_rx, - e1000_proc_rx_status); - } - -} - -/* - * e1000_proc_dev_setup - create proc fs nodes and link list - * @adapter: board private structure - */ - -void -e1000_proc_dev_setup(struct e1000_adapter *adapter) -{ - e1000_proc_list_setup(adapter); - - e1000_proc_dirs_create(adapter, - adapter->ifname, - &adapter->proc_list_head); -} - -/* - * e1000_proc_dev_free - free proc fs nodes and link list - * @adapter: board private structure - */ - -void -e1000_proc_dev_free(struct e1000_adapter *adapter) -{ - e1000_proc_dirs_free(adapter->ifname, &adapter->proc_list_head); - - e1000_proc_list_free(&adapter->proc_list_head); -} - -#else /* CONFIG_PROC_FS */ - -void e1000_proc_dev_setup(struct e1000_adapter *adapter) {} -void e1000_proc_dev_free(struct e1000_adapter *adapter) {} - -#endif /* CONFIG_PROC_FS */ - diff -Nru a/drivers/net/fealnx.c b/drivers/net/fealnx.c --- a/drivers/net/fealnx.c Sun Feb 9 21:13:34 2003 +++ b/drivers/net/fealnx.c Sun Feb 9 21:13:34 2003 @@ -1563,7 +1563,7 @@ } -/* This routine is logically part of the interrupt handler, but seperated +/* 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) { diff -Nru a/drivers/net/hamachi.c b/drivers/net/hamachi.c --- a/drivers/net/hamachi.c Sun Feb 9 21:13:37 2003 +++ b/drivers/net/hamachi.c Sun Feb 9 21:13:37 2003 @@ -1468,7 +1468,7 @@ spin_unlock(&hmp->lock); } -/* This routine is logically part of the interrupt handler, but seperated +/* This routine is logically part of the interrupt handler, but separated for clarity and better register allocation. */ static int hamachi_rx(struct net_device *dev) { diff -Nru a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c --- a/drivers/net/hamradio/6pack.c Sun Feb 9 21:13:29 2003 +++ b/drivers/net/hamradio/6pack.c Sun Feb 9 21:13:29 2003 @@ -113,7 +113,7 @@ /* 6pack stuff */ unsigned char tx_delay; - unsigned char persistance; + unsigned char persistence; unsigned char slottime; unsigned char duplex; unsigned char led_state; @@ -302,7 +302,7 @@ switch (p[0]) { case 1: sp->tx_delay = p[1]; return; - case 2: sp->persistance = p[1]; return; + case 2: sp->persistence = p[1]; return; case 3: sp->slottime = p[1]; return; case 4: /* ignored */ return; case 5: sp->duplex = p[1]; return; @@ -392,7 +392,7 @@ random = random * 17 + 41; - if (((sp->status1 & SIXP_DCD_MASK) == 0) && (random < sp->persistance)) { + if (((sp->status1 & SIXP_DCD_MASK) == 0) && (random < sp->persistence)) { sp->led_state = 0x70; sp->tty->driver.write(sp->tty, 0, &sp->led_state, 1); sp->tx_enable = 1; @@ -469,7 +469,7 @@ sp->duplex = 0; sp->tx_delay = SIXP_TXDELAY; - sp->persistance = SIXP_PERSIST; + sp->persistence = SIXP_PERSIST; sp->slottime = SIXP_SLOTTIME; sp->led_state = 0x60; sp->status = 1; diff -Nru a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig --- a/drivers/net/hamradio/Kconfig Sun Feb 9 21:13:28 2003 +++ b/drivers/net/hamradio/Kconfig Sun Feb 9 21:13:28 2003 @@ -15,7 +15,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called mkiss.o. + will be called mkiss. config 6PACK tristate "Serial port 6PACK driver" @@ -35,7 +35,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called 6pack.o. + will be called 6pack. config BPQETHER tristate "BPQ Ethernet driver" @@ -64,7 +64,7 @@ This driver can operate multiple boards simultaneously. If you compile it as a module (by saying M instead of Y), it will be called - dmascc.o. If you don't pass any parameter to the driver, all + dmascc. If you don't pass any parameter to the driver, all possible I/O addresses are probed. This could irritate other devices that are currently not in use. You may specify the list of addresses to be probed by "dmascc=addr1,addr2,..." (when compiled into the @@ -94,7 +94,7 @@ 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 scc.o. + will be called scc. config SCC_DELAY bool "additional delay for PA0HZP OptoSCC compatible boards" @@ -132,7 +132,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called baycom_ser_fdx.o. + recommended. The module will be called baycom_ser_fdx. config BAYCOM_SER_HDX tristate "BAYCOM ser12 halfduplex driver for AX.25" @@ -151,7 +151,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called baycom_ser_hdx.o. + recommended. The module will be called baycom_ser_hdx. config BAYCOM_PAR tristate "BAYCOM picpar and par96 driver for AX.25" @@ -167,7 +167,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called baycom_par.o. + recommended. The module will be called baycom_par. config BAYCOM_EPP tristate "BAYCOM epp driver for AX.25" @@ -183,7 +183,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is - recommended. The module will be called baycom_par.o. + recommended. The module will be called baycom_par. config YAM tristate "YAM driver for AX.25" diff -Nru a/drivers/net/hamradio/Makefile b/drivers/net/hamradio/Makefile --- a/drivers/net/hamradio/Makefile Sun Feb 9 21:13:29 2003 +++ b/drivers/net/hamradio/Makefile Sun Feb 9 21:13:29 2003 @@ -10,8 +10,6 @@ # Christoph Hellwig # -export-objs = hdlcdrv.o - obj-$(CONFIG_DMASCC) += dmascc.o obj-$(CONFIG_SCC) += scc.o obj-$(CONFIG_MKISS) += mkiss.o diff -Nru a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c --- a/drivers/net/hamradio/scc.c Sun Feb 9 21:13:35 2003 +++ b/drivers/net/hamradio/scc.c Sun Feb 9 21:13:35 2003 @@ -1703,7 +1703,7 @@ /* * Start transmission if the trx state is idle or - * t_idle hasn't expired yet. Use dwait/persistance/slottime + * t_idle hasn't expired yet. Use dwait/persistence/slottime * algorithm for normal halfduplex operation. */ diff -Nru a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c --- a/drivers/net/hamradio/yam.c Sun Feb 9 21:13:34 2003 +++ b/drivers/net/hamradio/yam.c Sun Feb 9 21:13:34 2003 @@ -34,7 +34,7 @@ * 0.5 F6FBB 01.08.98 Shared IRQs, /proc/net and network statistics * 0.6 F6FBB 25.08.98 Added 1200Bds format * 0.7 F6FBB 12.09.98 Added to the kernel configuration - * 0.8 F6FBB 14.10.98 Fixed slottime/persistance timing bug + * 0.8 F6FBB 14.10.98 Fixed slottime/persistence timing bug * OK1ZIA 2.09.01 Fixed "kfree_skb on hard IRQ" * using dev_kfree_skb_any(). (important in 2.4 kernel) * diff -Nru a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig --- a/drivers/net/irda/Kconfig Sun Feb 9 21:13:34 2003 +++ b/drivers/net/irda/Kconfig Sun Feb 9 21:13:34 2003 @@ -9,7 +9,7 @@ depends on IRDA help Say Y here if you want to build support for the IrTTY line - discipline. If you want to compile it as a module (irtty-sir.o), say M + discipline. If you want to compile it as a module (irtty-sir), say M here and read . IrTTY makes it possible to use Linux's own serial driver for all IrDA ports that are 16550 compatible. Most IrDA chips are 16550 compatible so you @@ -72,7 +72,7 @@ depends on IRDA help Say Y here if you want to build support for the IrTTY line - discipline. If you want to compile it as a module (irtty.o), say M + discipline. If you want to compile it as a module (irtty), say M here and read . IrTTY makes it possible to use Linux's own serial driver for all IrDA ports that are 16550 compatible. Most IrDA chips are 16550 compatible so you @@ -86,7 +86,7 @@ depends on IRDA ---help--- Say Y here if you want to build support for the IrPORT IrDA device - driver. If you want to compile it as a module (irport.o), say M here + driver. If you want to compile it as a module (irport), say M here and read . IrPORT can be used instead of IrTTY and sometimes this can be better. One example is if your IrDA port does not have echo-canceling, which will work OK @@ -188,7 +188,7 @@ Say Y here if you want to build support for the Adaptec Airport 1000 and 2000 dongles. If you want to compile it as a module, say M here and read . The module will be - called old_belkin.o. Some information is contained in the comments + called old_belkin. Some information is contained in the comments at the top of . config EP7211_IR @@ -230,7 +230,7 @@ depends on IRDA && USB && EXPERIMENTAL ---help--- Say Y here if you want to build support for the USB IrDA FIR Dongle - device driver. If you want to compile it as a module (irda-usb.o), + device driver. If you want to compile it as a module (irda-usb), say M here and read . IrDA-USB support the various IrDA USB dongles available and most of their pecularities. Those dongles plug in the USB port of your computer, @@ -251,7 +251,7 @@ If you want to compile it as a module, say M here and read . The module will be called - nsc-ircc.o. + nsc-ircc. config WINBOND_FIR tristate "Winbond W83977AF (IR)" @@ -264,7 +264,7 @@ If you want to compile it as a module, say M here and read . The module will be called - w83977af_ir.o. + w83977af_ir. config TOSHIBA_OLD tristate "Toshiba Type-O IR Port (old driver)" @@ -276,7 +276,7 @@ maintained and will be removed in favor of the new driver. If you want to compile it as a module, say M here and read . - The module will be called toshoboe.o. + The module will be called toshoboe. config TOSHIBA_FIR tristate "Toshiba Type-O IR Port" @@ -287,7 +287,7 @@ Libretto 100/110CT, Tecra 8100, Portege 7020 and many more laptops. If you want to compile it as a module, say M here and read . - The module will be called donauboe.o. + The module will be called donauboe. config SMC_IRCC_FIR tristate "SMC IrCC (EXPERIMENTAL)" @@ -297,7 +297,7 @@ Communications Controller. It is used in the Fujitsu Lifebook 635t and Sony PCG-505TX. If you want to compile it as a module, say M here and read . The module will be - called smc-ircc.o. + called smc-ircc. config ALI_FIR tristate "ALi M5123 FIR (EXPERIMENTAL)" @@ -310,7 +310,7 @@ If you want to compile it as a module, say M here and read . The module will be called - ali-ircc.o. + ali-ircc. config VLSI_FIR tristate "VLSI 82C147 SIR/MIR/FIR (EXPERIMENTAL)" @@ -322,7 +322,8 @@ FIR (4Mbps) speeds. If you want to compile it as a module, say M here and read - . The module will be called vlsi_ir.o. + . The module will be called + vlsi_ir. config SA1100_FIR tristate "SA1100 Internal IR" diff -Nru a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile --- a/drivers/net/irda/Makefile Sun Feb 9 21:13:31 2003 +++ b/drivers/net/irda/Makefile Sun Feb 9 21:13:31 2003 @@ -5,8 +5,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs = irport.o sir_core.o - # Old SIR drivers (irtty is broken) obj-$(CONFIG_IRTTY_OLD) += irtty.o obj-$(CONFIG_IRPORT_SIR) += irport.o diff -Nru a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c --- a/drivers/net/irda/irport.c Sun Feb 9 21:13:34 2003 +++ b/drivers/net/irda/irport.c Sun Feb 9 21:13:34 2003 @@ -102,9 +102,6 @@ int i; for (i=0; (io[i] < 2000) && (i < 4); i++) { - int ioaddr = io[i]; - if (check_region(ioaddr, IO_EXTENT)) - continue; if (irport_open(i, io[i], irq[i]) != NULL) return 0; } @@ -142,6 +139,14 @@ IRDA_DEBUG(1, "%s()\n", __FUNCTION__); + /* Lock the port that we need */ + ret = request_region(iobase, IO_EXTENT, driver_name); + if (!ret) { + IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n", + __FUNCTION__, iobase); + return NULL; + } + /* * Allocate new instance of the driver */ @@ -149,6 +154,7 @@ if (!self) { ERROR("%s(), can't allocate memory for " "control block!\n", __FUNCTION__); + release_region(iobase, IO_EXTENT); return NULL; } memset(self, 0, sizeof(struct irport_cb)); @@ -164,14 +170,6 @@ self->io.sir_ext = IO_EXTENT; self->io.irq = irq; self->io.fifo_size = 16; - - /* Lock the port that we need */ - ret = request_region(self->io.sir_base, self->io.sir_ext, driver_name); - if (!ret) { - IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n", - __FUNCTION__, self->io.sir_base); - return NULL; - } /* Initialize QoS for this device */ irda_init_max_qos_capabilies(&self->qos); diff -Nru a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c --- a/drivers/net/irda/sir_kthread.c Sun Feb 9 21:13:35 2003 +++ b/drivers/net/irda/sir_kthread.c Sun Feb 9 21:13:35 2003 @@ -116,10 +116,10 @@ daemonize(); strcpy(current->comm, "kIrDAd"); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigfillset(¤t->blocked); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); set_fs(KERNEL_DS); diff -Nru a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c --- a/drivers/net/lasi_82596.c Sun Feb 9 21:13:29 2003 +++ b/drivers/net/lasi_82596.c Sun Feb 9 21:13:29 2003 @@ -91,6 +91,7 @@ #include #include #include +#include static char version[] __devinitdata = "82596.c $Revision: 1.29 $\n"; @@ -121,13 +122,13 @@ #define CHECK_WBACK(addr,len) \ - do { if (!dma_consistent) dma_cache_wback((unsigned long)addr,len); } while (0) + do { dma_cache_sync((void *)addr, len, DMA_TO_DEVICE); } while (0) #define CHECK_INV(addr,len) \ - do { if (!dma_consistent) dma_cache_inv((unsigned long)addr,len); } while(0) + do { dma_cache_sync((void *)addr,len, DMA_FROM_DEVICE); } while(0) #define CHECK_WBACK_INV(addr,len) \ - do { if (!dma_consistent) dma_cache_wback_inv((unsigned long)addr,len); } while (0) + do { dma_cache_sync((void *)addr,len, DMA_BIDIRECTIONAL); } while (0) #define PA_I82596_RESET 0 /* Offsets relative to LASI-LAN-Addr.*/ @@ -383,6 +384,7 @@ int options; spinlock_t lock; dma_addr_t dma_addr; + struct device *dev; }; static char init_setup[] = @@ -402,10 +404,6 @@ 0x00, 0x7f /* *multi IA */ }; -static struct pci_dev *fake_pci_dev; /* The fake pci_dev needed for - pci_* functions under ccio. */ -static int dma_consistent = 1; /* Zero if pci_alloc_consistent() fails */ - static int i596_open(struct net_device *dev); static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -558,8 +556,8 @@ if (skb == NULL) panic("82596: alloc_skb() failed"); skb_reserve(skb, 2); - dma_addr = pci_map_single(fake_pci_dev, skb->tail,PKT_BUF_SZ, - PCI_DMA_FROMDEVICE); + dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ, + DMA_FROM_DEVICE); skb->dev = dev; rbd->v_next = rbd+1; rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1)); @@ -605,9 +603,9 @@ for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { if (rbd->skb == NULL) break; - pci_unmap_single(fake_pci_dev, + dma_unmap_single(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), - PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + PKT_BUF_SZ, DMA_FROM_DEVICE); dev_kfree_skb(rbd->skb); } } @@ -774,7 +772,7 @@ struct sk_buff *newskb; dma_addr_t dma_addr; - pci_unmap_single(fake_pci_dev,(dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + dma_unmap_single(lp->dev,(dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE); /* Get fresh skbuff to replace filled one. */ newskb = dev_alloc_skb(PKT_BUF_SZ + 4); if (newskb == NULL) { @@ -788,7 +786,7 @@ rx_in_place = 1; rbd->skb = newskb; newskb->dev = dev; - dma_addr = pci_map_single(fake_pci_dev, newskb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE); rbd->v_data = newskb->tail; rbd->b_data = WSWAPchar(dma_addr); CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd)); @@ -805,7 +803,7 @@ skb->dev = dev; if (!rx_in_place) { /* 16 byte align the data fields */ - pci_dma_sync_single(fake_pci_dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + dma_sync_single(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE); skb_reserve(skb, 2); memcpy(skb_put(skb,pkt_len), rbd->v_data, pkt_len); } @@ -886,7 +884,7 @@ { struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr; struct sk_buff *skb = tx_cmd->skb; - pci_unmap_single(fake_pci_dev, tx_cmd->dma_addr, skb->len, PCI_DMA_TODEVICE); + dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb(skb); @@ -1118,8 +1116,8 @@ tbd->pad = 0; tbd->size = EOF | length; - tx_cmd->dma_addr = pci_map_single(fake_pci_dev, skb->data, skb->len, - PCI_DMA_TODEVICE); + tx_cmd->dma_addr = dma_map_single(lp->dev, skb->data, skb->len, + DMA_TO_DEVICE); tbd->data = WSWAPchar(tx_cmd->dma_addr); DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued")); @@ -1156,6 +1154,8 @@ { int i; struct i596_private *lp; + /* we're going to overwrite dev->priv, so pull the device out */ + struct device *gen_dev = dev->priv; char eth_addr[6]; dma_addr_t dma_addr; @@ -1198,17 +1198,11 @@ printk("82596.c: MAC of HP700 LAN read from EEPROM\n"); } - dev->mem_start = (unsigned long) pci_alloc_consistent(fake_pci_dev, - sizeof(struct i596_private), &dma_addr); + dev->mem_start = (unsigned long) dma_alloc_noncoherent(gen_dev, + sizeof(struct i596_private), &dma_addr, GFP_KERNEL); if (!dev->mem_start) { - printk("%s: Couldn't get consistent shared memory\n", dev->name); - dma_consistent = 0; - dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0); - if (!dev->mem_start) { - printk("%s: Couldn't get shared memory\n", dev->name); - return -ENOMEM; - } - dma_addr = virt_to_bus(dev->mem_start); + printk("%s: Couldn't get shared memory\n", dev->name); + return -ENOMEM; } ether_setup(dev); @@ -1243,6 +1237,7 @@ lp->scb.rfd = I596_NULL; lp->lock = SPIN_LOCK_UNLOCKED; lp->dma_addr = dma_addr; + lp->dev = gen_dev; CHECK_WBACK_INV(dev->mem_start, sizeof(struct i596_private)); @@ -1320,7 +1315,7 @@ if ((ptr->status) & 0x1000) lp->stats.tx_aborted_errors++; } - pci_unmap_single(fake_pci_dev, tx_cmd->dma_addr, skb->len, PCI_DMA_TODEVICE); + dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb_irq(skb); tx_cmd->cmd.command = 0; /* Mark free */ @@ -1530,8 +1525,6 @@ return -ENODEV; } - fake_pci_dev = ccio_get_fake(dev); - if (!dev->irq) { printk(KERN_ERR __FILE__ ": IRQ not found for i82596 at 0x%lx\n", dev->hpa); return -ENODEV; @@ -1546,6 +1539,7 @@ netdevice->base_addr = dev->hpa; netdevice->irq = dev->irq; netdevice->init = i82596_probe; + netdevice->priv = &dev->dev; retval = register_netdev(netdevice); if (retval) { @@ -1601,13 +1595,8 @@ unregister_netdev(netdevice); lp = (struct i596_private *) netdevice->priv; - if (dma_consistent) - pci_free_consistent(fake_pci_dev, - sizeof(struct i596_private), - (void *)netdevice->mem_start, lp->dma_addr); - else - free_page(netdevice->mem_start); - + dma_free_noncoherent(lp->dev, sizeof(struct i596_private), + (void *)netdevice->mem_start, lp->dma_addr); netdevice->priv = NULL; } diff -Nru a/drivers/net/mac8390.c b/drivers/net/mac8390.c --- a/drivers/net/mac8390.c Sun Feb 9 21:13:32 2003 +++ b/drivers/net/mac8390.c Sun Feb 9 21:13:32 2003 @@ -121,7 +121,7 @@ 1, /* dayna-lc */ }; -static const char __initdata * version = +static char version[] __initdata = "mac8390.c: v0.4 2001-05-15 David Huggins-Daines and others\n"; extern int mac8390_probe(struct net_device * dev); diff -Nru a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c --- a/drivers/net/pcmcia/3c574_cs.c Sun Feb 9 21:13:29 2003 +++ b/drivers/net/pcmcia/3c574_cs.c Sun Feb 9 21:13:29 2003 @@ -305,6 +305,7 @@ link = &lp->link; dev = &lp->dev; link->priv = dev->priv = link->irq.Instance = lp; + init_timer(&link->release); link->release.function = &tc574_release; link->release.data = (u_long)link; link->io.NumPorts1 = 32; diff -Nru a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c --- a/drivers/net/pcmcia/3c589_cs.c Sun Feb 9 21:13:36 2003 +++ b/drivers/net/pcmcia/3c589_cs.c Sun Feb 9 21:13:36 2003 @@ -229,6 +229,7 @@ link = &lp->link; dev = &lp->dev; link->priv = dev->priv = link->irq.Instance = lp; + init_timer(&link->release); link->release.function = &tc589_release; link->release.data = (unsigned long)link; link->io.NumPorts1 = 16; diff -Nru a/drivers/net/pcmcia/Kconfig b/drivers/net/pcmcia/Kconfig --- a/drivers/net/pcmcia/Kconfig Sun Feb 9 21:13:34 2003 +++ b/drivers/net/pcmcia/Kconfig Sun Feb 9 21:13:34 2003 @@ -30,7 +30,7 @@ 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 will be called 3c589_cs.o. If you want to compile it as + The module will be called 3c589_cs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -43,7 +43,7 @@ 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 will be called 3c574_cs.o. If you want to compile it as + The module will be called 3c574_cs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -56,7 +56,7 @@ 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 will be called fmvj18x_cs.o. If you want to compile it + The module will be called fmvj18x_cs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -69,7 +69,7 @@ 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 will be called pcnet_cs.o. If you want to compile it as + The module will be called pcnet_cs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -82,7 +82,7 @@ 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 will be called nmclan_cs.o. If you want to compile it as + The module will be called nmclan_cs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -95,7 +95,7 @@ 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 will be called smc91c92_cs.o. If you want to compile it + The module will be called smc91c92_cs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -108,7 +108,7 @@ 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 will be called xirc2ps_cs.o. If you want to compile it + The module will be called xirc2ps_cs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -123,7 +123,7 @@ 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 will be called axnet_cs.o. If you want to compile it as + The module will be called axnet_cs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -136,7 +136,7 @@ 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 will be called com20020_cs.o. If you want to compile it + The module will be called com20020_cs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -150,7 +150,7 @@ 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 will be called ibmtr_cs.o. If you want to compile it as + The module will be called ibmtr_cs. If you want to compile it as a module, say M here and read . config NET_PCMCIA_RADIO @@ -177,7 +177,7 @@ 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 will be called ray_cs.o. If you want to compile it as a + The module will be called ray_cs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -191,7 +191,7 @@ 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 will be called aironet4500_cs.o. If you want to + The module will be called aironet4500_cs. If you want to compile it as a module, say M here and read . diff -Nru a/drivers/net/pcmcia/Makefile b/drivers/net/pcmcia/Makefile --- a/drivers/net/pcmcia/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/net/pcmcia/Makefile Sun Feb 9 21:13:28 2003 @@ -2,9 +2,6 @@ # Makefile for the Linux PCMCIA network device drivers. # -# Things that need to export symbols -export-objs := ray_cs.o - # 16-bit client drivers obj-$(CONFIG_PCMCIA_3C589) += 3c589_cs.o obj-$(CONFIG_PCMCIA_3C574) += 3c574_cs.o diff -Nru a/drivers/net/pcmcia/aironet4500_cs.c b/drivers/net/pcmcia/aironet4500_cs.c --- a/drivers/net/pcmcia/aironet4500_cs.c Sun Feb 9 21:13:28 2003 +++ b/drivers/net/pcmcia/aironet4500_cs.c Sun Feb 9 21:13:28 2003 @@ -246,6 +246,7 @@ memset(link->dev, 0, sizeof(struct dev_node_t)); + init_timer(&link->release); link->release.function = &awc_release; link->release.data = (u_long)link; // link->io.NumPorts1 = 32; diff -Nru a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c --- a/drivers/net/pcmcia/axnet_cs.c Sun Feb 9 21:13:32 2003 +++ b/drivers/net/pcmcia/axnet_cs.c Sun Feb 9 21:13:32 2003 @@ -203,6 +203,7 @@ link = &info->link; dev = &info->dev; link->priv = info; + init_timer(&link->release); link->release.function = &axnet_release; link->release.data = (u_long)link; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; diff -Nru a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c --- a/drivers/net/pcmcia/com20020_cs.c Sun Feb 9 21:13:32 2003 +++ b/drivers/net/pcmcia/com20020_cs.c Sun Feb 9 21:13:32 2003 @@ -221,6 +221,7 @@ memset(link, 0, sizeof(struct dev_link_t)); dev->priv = lp; + init_timer(&link->release); link->release.function = &com20020_release; link->release.data = (u_long)link; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; diff -Nru a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c --- a/drivers/net/pcmcia/ibmtr_cs.c Sun Feb 9 21:13:32 2003 +++ b/drivers/net/pcmcia/ibmtr_cs.c Sun Feb 9 21:13:32 2003 @@ -221,6 +221,7 @@ memset(info, 0, sizeof(*info)); link = &info->link; link->priv = info; + init_timer(&link->release); link->release.function = &ibmtr_release; link->release.data = (u_long)link; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; diff -Nru a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c --- a/drivers/net/pcmcia/nmclan_cs.c Sun Feb 9 21:13:29 2003 +++ b/drivers/net/pcmcia/nmclan_cs.c Sun Feb 9 21:13:29 2003 @@ -493,6 +493,7 @@ link = &lp->link; dev = &lp->dev; link->priv = dev->priv = link->irq.Instance = lp; + init_timer(&link->release); link->release.function = &nmclan_release; link->release.data = (u_long)link; link->io.NumPorts1 = 32; diff -Nru a/drivers/net/pcmcia/ray_cs.c b/drivers/net/pcmcia/ray_cs.c --- a/drivers/net/pcmcia/ray_cs.c Sun Feb 9 21:13:31 2003 +++ b/drivers/net/pcmcia/ray_cs.c Sun Feb 9 21:13:31 2003 @@ -378,6 +378,7 @@ memset(dev, 0, sizeof(struct net_device)); memset(local, 0, sizeof(ray_dev_t)); + init_timer(&link->release); link->release.function = &ray_release; link->release.data = (u_long)link; diff -Nru a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c --- a/drivers/net/pcmcia/xirc2ps_cs.c Sun Feb 9 21:13:31 2003 +++ b/drivers/net/pcmcia/xirc2ps_cs.c Sun Feb 9 21:13:31 2003 @@ -632,6 +632,7 @@ link = &local->link; dev = &local->dev; link->priv = dev->priv = local; + init_timer(&link->release); link->release.function = &xirc2ps_release; link->release.data = (u_long) link; diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c --- a/drivers/net/ppp_generic.c Sun Feb 9 21:13:36 2003 +++ b/drivers/net/ppp_generic.c Sun Feb 9 21:13:36 2003 @@ -962,11 +962,10 @@ if (ppp->pass_filter.filter && sk_run_filter(skb, ppp->pass_filter.filter, ppp->pass_filter.len) == 0) { - if (ppp->debug & 1) { + if (ppp->debug & 1) printk(KERN_DEBUG "PPP: outbound frame not passed\n"); - kfree_skb(skb); - return; - } + kfree_skb(skb); + return; } /* if this packet passes the active filter, record the time */ if (!(ppp->active_filter.filter diff -Nru a/drivers/net/rrunner.c b/drivers/net/rrunner.c --- a/drivers/net/rrunner.c Sun Feb 9 21:13:29 2003 +++ b/drivers/net/rrunner.c Sun Feb 9 21:13:29 2003 @@ -386,7 +386,7 @@ writel(0, ®s->CmdRing[i]); /* - * Why 32 ? is this not cache line size dependant? + * Why 32 ? is this not cache line size dependent? */ writel(RBURST_64|WBURST_64, ®s->PciState); wmb(); diff -Nru a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c --- a/drivers/net/sgiseeq.c Sun Feb 9 21:13:36 2003 +++ b/drivers/net/sgiseeq.c Sun Feb 9 21:13:36 2003 @@ -524,7 +524,7 @@ * 2) Do no allow the HPC to look at a new descriptor until * we have completely set up it's state. This means, do * not clear HPCDMA_EOX in the current last descritptor - * until the one we are adding looks consistant and could + * until the one we are adding looks consistent and could * be processes right now. * 3) The tx interrupt code must notice when we've added a new * entry and the HPC got to the end of the chain before we diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c --- a/drivers/net/sis900.c Sun Feb 9 21:13:31 2003 +++ b/drivers/net/sis900.c Sun Feb 9 21:13:31 2003 @@ -750,7 +750,7 @@ /* Read and write the MII management registers using software-generated serial MDIO protocol. Note that the command bits and data bits are - send out seperately */ + send out separately */ #define mdio_delay() inl(mdio_addr) static void mdio_idle(long mdio_addr) diff -Nru a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c --- a/drivers/net/sk98lin/skgeinit.c Sun Feb 9 21:13:32 2003 +++ b/drivers/net/sk98lin/skgeinit.c Sun Feb 9 21:13:32 2003 @@ -1134,7 +1134,7 @@ * After calling this function the descriptor rings and rx and tx * queues of this port may be reconfigured. * - * It is possible to stop the receive and transmit path seperate or + * It is possible to stop the receive and transmit path separate or * both together. * * Dir = SK_STOP_TX Stops the transmit path only and resets diff -Nru a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c --- a/drivers/net/sk98lin/skvpd.c Sun Feb 9 21:13:33 2003 +++ b/drivers/net/sk98lin/skvpd.c Sun Feb 9 21:13:33 2003 @@ -88,7 +88,7 @@ * Revision 1.9 1998/09/16 07:33:52 malthoff * remove memcmp() by SK_MEMCMP and * memcpy() by SK_MEMCPY() to be - * independant from the 'C' Standard Library. + * independent from the 'C' Standard Library. * * Revision 1.8 1998/08/19 12:52:35 malthoff * compiler fix: use SK_VPD_KEY instead of S_VPD. diff -Nru a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c --- a/drivers/net/sk98lin/skxmac2.c Sun Feb 9 21:13:36 2003 +++ b/drivers/net/sk98lin/skxmac2.c Sun Feb 9 21:13:36 2003 @@ -194,7 +194,7 @@ * * Revision 1.12 1998/10/14 14:45:04 malthoff * Remove SKERR_SIRQ_E0xx and SKERR_SIRQ_E0xxMSG by - * SKERR_HWI_Exx and SKERR_HWI_E0xxMSG to be independant + * SKERR_HWI_Exx and SKERR_HWI_E0xxMSG to be independent * from the Sirq module. * * Revision 1.11 1998/10/14 13:59:01 gklug @@ -826,7 +826,7 @@ for (i = 0; i < 3; i++) { /* * The following 2 statements are together endianess - * independant. Remember this when changing. + * independent. Remember this when changing. */ SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord); XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord); diff -Nru a/drivers/net/skfp/cfm.c b/drivers/net/skfp/cfm.c --- a/drivers/net/skfp/cfm.c Sun Feb 9 21:13:32 2003 +++ b/drivers/net/skfp/cfm.c Sun Feb 9 21:13:32 2003 @@ -21,15 +21,15 @@ */ /* - * Hardware independant state machine implemantation + * Hardware independent state machine implemantation * The following external SMT functions are referenced : * * queue_event() * - * The following external HW dependant functions are referenced : + * The following external HW dependent functions are referenced : * config_mux() * - * The following HW dependant events are required : + * The following HW dependent events are required : * NONE */ diff -Nru a/drivers/net/skfp/ecm.c b/drivers/net/skfp/ecm.c --- a/drivers/net/skfp/ecm.c Sun Feb 9 21:13:30 2003 +++ b/drivers/net/skfp/ecm.c Sun Feb 9 21:13:30 2003 @@ -17,23 +17,23 @@ /* SMT ECM Entity Coordination Management - Hardware independant state machine + Hardware independent state machine */ /* - * Hardware independant state machine implemantation + * Hardware independent state machine implemantation * The following external SMT functions are referenced : * * queue_event() * smt_timer_start() * smt_timer_stop() * - * The following external HW dependant functions are referenced : + * The following external HW dependent functions are referenced : * sm_pm_bypass_req() * sm_pm_ls_latch() * sm_pm_get_ls() * - * The following HW dependant events are required : + * The following HW dependent events are required : * NONE * */ diff -Nru a/drivers/net/skfp/h/osdef1st.h b/drivers/net/skfp/h/osdef1st.h --- a/drivers/net/skfp/h/osdef1st.h Sun Feb 9 21:13:35 2003 +++ b/drivers/net/skfp/h/osdef1st.h Sun Feb 9 21:13:35 2003 @@ -13,7 +13,7 @@ ******************************************************************************/ /* - * Operating system-dependant definitions that have to be defined + * Operating system-dependent definitions that have to be defined * before any other header files are included. */ diff -Nru a/drivers/net/skfp/h/supern_2.h b/drivers/net/skfp/h/supern_2.h --- a/drivers/net/skfp/h/supern_2.h Sun Feb 9 21:13:34 2003 +++ b/drivers/net/skfp/h/supern_2.h Sun Feb 9 21:13:34 2003 @@ -926,7 +926,7 @@ #define PL_PC1 (1<<7) /* BREAK - entry point in start PCM*/ #define PL_PC2 (2<<7) /* TRACE - to localize stuck Beacon*/ #define PL_PC3 (3<<7) /* CONNECT - synchronize ends of conn*/ -#define PL_PC4 (4<<7) /* NEXT - to seperate the signalng*/ +#define PL_PC4 (4<<7) /* NEXT - to separate the signalng*/ #define PL_PC5 (5<<7) /* SIGNAL - PCM trans/rec. bit infos*/ #define PL_PC6 (6<<7) /* JOIN - 1. state to activ conn. */ #define PL_PC7 (7<<7) /* VERIFY - 2. - " - (3. ACTIVE) */ diff -Nru a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c --- a/drivers/net/skfp/pcmplc.c Sun Feb 9 21:13:28 2003 +++ b/drivers/net/skfp/pcmplc.c Sun Feb 9 21:13:28 2003 @@ -20,19 +20,19 @@ */ /* - * Hardware independant state machine implemantation + * Hardware independent state machine implemantation * The following external SMT functions are referenced : * * queue_event() * smt_timer_start() * smt_timer_stop() * - * The following external HW dependant functions are referenced : + * The following external HW dependent functions are referenced : * sm_pm_control() * sm_ph_linestate() * sm_pm_ls_latch() * - * The following HW dependant events are required : + * The following HW dependent events are required : * PC_QLS * PC_ILS * PC_HLS @@ -714,7 +714,7 @@ mib = phy->mib ; /* - * general transitions independant of state + * general transitions independent of state */ switch (cmd) { case PC_STOP : diff -Nru a/drivers/net/skfp/rmt.c b/drivers/net/skfp/rmt.c --- a/drivers/net/skfp/rmt.c Sun Feb 9 21:13:36 2003 +++ b/drivers/net/skfp/rmt.c Sun Feb 9 21:13:36 2003 @@ -20,18 +20,18 @@ */ /* - * Hardware independant state machine implemantation + * Hardware independent state machine implemantation * The following external SMT functions are referenced : * * queue_event() * smt_timer_start() * smt_timer_stop() * - * The following external HW dependant functions are referenced : + * The following external HW dependent functions are referenced : * sm_ma_control() * sm_mac_check_beacon_claim() * - * The following HW dependant events are required : + * The following HW dependent events are required : * RM_RING_OP * RM_RING_NON_OP * RM_MY_BEACON diff -Nru a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c --- a/drivers/net/skfp/skfddi.c Sun Feb 9 21:13:28 2003 +++ b/drivers/net/skfp/skfddi.c Sun Feb 9 21:13:28 2003 @@ -33,7 +33,7 @@ * The driver architecture is based on the DEC FDDI driver by * Lawrence V. Stefani and several ethernet drivers. * I also used an existing Windows NT miniport driver. - * All hardware dependant fuctions are handled by the SysKonnect + * All hardware dependent fuctions are handled by the SysKonnect * Hardware Module. * The only headerfiles that are directly related to this source * are skfddi.c, h/types.h, h/osdef1st.h, h/targetos.h. @@ -1729,7 +1729,7 @@ * dma_complete * * The hardware module calls this routine when it has completed a DMA - * transfer. If the operating system dependant module has set up the DMA + * transfer. If the operating system dependent module has set up the DMA * channel via dma_master() (e.g. Windows NT or AIX) it should clean up * the DMA channel. * Args diff -Nru a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c --- a/drivers/net/skfp/smt.c Sun Feb 9 21:13:35 2003 +++ b/drivers/net/skfp/smt.c Sun Feb 9 21:13:35 2003 @@ -417,7 +417,7 @@ /* * Make sure the fddiMACUNDA_Flag = FALSE is * included in the SRF so we don't generate - * a seperate SRF for the deassertion of this + * a separate SRF for the deassertion of this * condition */ update_dac(smc,0) ; diff -Nru a/drivers/net/skfp/smtdef.c b/drivers/net/skfp/smtdef.c --- a/drivers/net/skfp/smtdef.c Sun Feb 9 21:13:28 2003 +++ b/drivers/net/skfp/smtdef.c Sun Feb 9 21:13:28 2003 @@ -217,7 +217,7 @@ mib->fddiSMTStatRptPolicy = TRUE ; mib->fddiSMTTrace_MaxExpiration = SEC2MIB(7) ; mib->fddiSMTMACIndexes = INDEX_MAC ; - mib->fddiSMTStationStatus = MIB_SMT_STASTA_SEPA ; /* seperated */ + mib->fddiSMTStationStatus = MIB_SMT_STASTA_SEPA ; /* separated */ mib->m[MAC0].fddiMACIndex = INDEX_MAC ; mib->m[MAC0].fddiMACFrameStatusFunctions = FSC_TYPE0 ; diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c --- a/drivers/net/tg3.c Sun Feb 9 21:13:32 2003 +++ b/drivers/net/tg3.c Sun Feb 9 21:13:32 2003 @@ -1,4 +1,4 @@ -/* $Id: tg3.c,v 1.43.2.80 2002/03/14 00:10:04 davem Exp $ +/* * tg3.c: Broadcom Tigon3 ethernet driver. * * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com) @@ -54,8 +54,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.2a" -#define DRV_MODULE_RELDATE "Dec 9, 2002" +#define DRV_MODULE_VERSION "1.4" +#define DRV_MODULE_RELDATE "Feb 1, 2003" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -141,6 +141,12 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703X, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704S, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702A3, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703A3, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_SYSKONNECT, 0x4400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000, @@ -163,6 +169,8 @@ spin_unlock_irqrestore(&tp->indirect_lock, flags); } else { writel(val, tp->regs + off); + if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0) + readl(tp->regs + off); } } @@ -213,28 +221,11 @@ tw32(TG3PCI_MISC_HOST_CTRL, (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); - - if (tp->hw_status->status & SD_STATUS_UPDATED) { - tw32(GRC_LOCAL_CTRL, - tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); - } tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); -} - -static inline void tg3_mask_ints(struct tg3 *tp) -{ - tw32(TG3PCI_MISC_HOST_CTRL, - (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT)); -} -static inline void tg3_unmask_ints(struct tg3 *tp) -{ - tw32(TG3PCI_MISC_HOST_CTRL, - (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); - if (tp->hw_status->status & SD_STATUS_UPDATED) { + if (tp->hw_status->status & SD_STATUS_UPDATED) tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); - } } static void tg3_switch_clocks(struct tg3 *tp) @@ -900,6 +891,20 @@ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02); + /* Some third-party PHYs need to be reset on link going + * down. + * + * XXX 5705 note: This workaround also applies to 5705_a0 + */ + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) && + netif_carrier_ok(tp->dev)) { + tg3_readphy(tp, MII_BMSR, &bmsr); + tg3_readphy(tp, MII_BMSR, &bmsr); + if (!(bmsr & BMSR_LSTATUS)) + tg3_phy_reset(tp, 1); + } + if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { tg3_readphy(tp, MII_BMSR, &bmsr); tg3_readphy(tp, MII_BMSR, &bmsr); @@ -1867,7 +1872,7 @@ * Each TG3_BDINFO specifies a MAXLEN field and the first TG3_BDINFO * which is within the range of the new packet's length is chosen. * - * The "seperate ring for rx status" scheme may sound queer, but it makes + * The "separate ring for rx status" scheme may sound queer, but it makes * sense from a cache coherency perspective. If only the host writes * to the buffer post rings, and only the chip writes to the rx status * rings, then cache lines never move beyond shared-modified state. @@ -1958,13 +1963,12 @@ } if ((tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) && - (desc->type_flags & RXD_FLAG_TCPUDP_CSUM)) { - skb->csum = htons((desc->ip_tcp_csum & RXD_TCPCSUM_MASK) - >> RXD_TCPCSUM_SHIFT); - skb->ip_summed = CHECKSUM_HW; - } else { + (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) && + (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK) + >> RXD_TCPCSUM_SHIFT) == 0xffff)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else skb->ip_summed = CHECKSUM_NONE; - } skb->protocol = eth_type_trans(skb, tp->dev); #if TG3_VLAN_TAG_USED @@ -2017,10 +2021,12 @@ { struct tg3 *tp = netdev->priv; struct tg3_hw_status *sblk = tp->hw_status; + unsigned long flags; int done; - spin_lock_irq(&tp->lock); + spin_lock_irqsave(&tp->lock, flags); + /* handle link change and other phy events */ if (!(tp->tg3_flags & (TG3_FLAG_USE_LINKCHG_REG | TG3_FLAG_POLL_SERDES))) { @@ -2031,12 +2037,14 @@ } } + /* run TX completion thread */ if (sblk->idx[0].tx_consumer != tp->tx_cons) { spin_lock(&tp->tx_lock); tg3_tx(tp); spin_unlock(&tp->tx_lock); } + /* run RX thread, within the bounds set by NAPI */ done = 1; if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) { int orig_budget = *budget; @@ -2054,44 +2062,35 @@ done = 0; } + /* if no more work, tell net stack and NIC we're done */ if (done) { netif_rx_complete(netdev); - tg3_unmask_ints(tp); + tg3_enable_ints(tp); } - spin_unlock_irq(&tp->lock); + spin_unlock_irqrestore(&tp->lock, flags); return (done ? 0 : 1); } -static __inline__ void tg3_interrupt_main_work(struct net_device *dev, struct tg3 *tp) +static inline unsigned int tg3_has_work(struct net_device *dev, struct tg3 *tp) { struct tg3_hw_status *sblk = tp->hw_status; - int work_exists = 0; + unsigned int work_exists = 0; + /* check for phy events */ if (!(tp->tg3_flags & (TG3_FLAG_USE_LINKCHG_REG | TG3_FLAG_POLL_SERDES))) { if (sblk->status & SD_STATUS_LINK_CHG) work_exists = 1; } + /* check for RX/TX work to do */ if (sblk->idx[0].tx_consumer != tp->tx_cons || sblk->idx[0].rx_producer != tp->rx_rcb_ptr) work_exists = 1; - if (!work_exists) - return; - - if (netif_rx_schedule_prep(dev)) { - /* NOTE: These writes are posted by the readback of - * the mailbox register done by our caller. - */ - tg3_mask_ints(tp); - __netif_rx_schedule(dev); - } else { - printk(KERN_ERR PFX "%s: Error, poll already scheduled\n", - dev->name); - } + return work_exists; } static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -2104,15 +2103,32 @@ spin_lock_irqsave(&tp->lock, flags); if (sblk->status & SD_STATUS_UPDATED) { + /* + * writing any value to intr-mbox-0 clears PCI INTA# and + * chip-internal interrupt pending events. + * writing non-zero to intr-mbox-0 additional tells the + * NIC to stop sending us irqs, engaging "in-intr-handler" + * event coalescing. + */ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + /* + * Flush PCI write. This also guarantees that our + * status block has been flushed to host memory. + */ + tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); sblk->status &= ~SD_STATUS_UPDATED; - tg3_interrupt_main_work(dev, tp); - - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000000); - tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); + if (likely(tg3_has_work(dev, tp))) + netif_rx_schedule(dev); /* schedule NAPI poll */ + else { + /* no work, shared interrupt perhaps? re-enable + * interrupts, and flush that PCI write + */ + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, + 0x00000000); + tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); + } } spin_unlock_irqrestore(&tp->lock, flags); @@ -2213,11 +2229,6 @@ return -1; } - /* NOTE: Broadcom's driver botches this case up really bad. - * This is especially true if any of the frag pages - * are in highmem. It will instantly oops in that case. - */ - /* New SKB is guarenteed to be linear. */ entry = *start; new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len, @@ -2649,6 +2660,17 @@ return 0; } +static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp, + int new_mtu) +{ + dev->mtu = new_mtu; + + if (new_mtu > ETH_DATA_LEN) + tp->tg3_flags |= TG3_FLAG_JUMBO_ENABLE; + else + tp->tg3_flags &= ~TG3_FLAG_JUMBO_ENABLE; +} + static int tg3_change_mtu(struct net_device *dev, int new_mtu) { struct tg3 *tp = dev->priv; @@ -2660,7 +2682,7 @@ /* We'll just catch it later when the * device is up'd. */ - dev->mtu = new_mtu; + tg3_set_mtu(dev, tp, new_mtu); return 0; } @@ -2669,12 +2691,7 @@ tg3_halt(tp); - dev->mtu = new_mtu; - - if (new_mtu > ETH_DATA_LEN) - tp->tg3_flags |= TG3_FLAG_JUMBO_ENABLE; - else - tp->tg3_flags &= ~TG3_FLAG_JUMBO_ENABLE; + tg3_set_mtu(dev, tp, new_mtu); tg3_init_rings(tp); tg3_init_hw(tp); @@ -4285,6 +4302,12 @@ if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) tw32(MAC_SERDES_CFG, 0x616000); + /* Prevent chip from dropping frames when flow control + * is enabled. + */ + tw32(MAC_LOW_WMARK_MAX_RX_FRAME, 2); + tr32(MAC_LOW_WMARK_MAX_RX_FRAME); + err = tg3_setup_phy(tp); if (err) return err; @@ -4353,8 +4376,9 @@ static void tg3_timer(unsigned long __opaque) { struct tg3 *tp = (struct tg3 *) __opaque; + unsigned long flags; - spin_lock_irq(&tp->lock); + spin_lock_irqsave(&tp->lock, flags); spin_lock(&tp->tx_lock); /* All of this garbage is because when using non-tagged @@ -4436,7 +4460,7 @@ } spin_unlock(&tp->tx_lock); - spin_unlock_irq(&tp->lock); + spin_unlock_irqrestore(&tp->lock, flags); tp->timer.expires = jiffies + tp->timer_offset; add_timer(&tp->timer); @@ -5793,7 +5817,8 @@ tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa); } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) && + (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)) { tg3_writephy(tp, 0x1c, 0x8d68); tg3_writephy(tp, 0x1c, 0x8d68); } @@ -5999,6 +6024,14 @@ pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); } } + + /* Back to back register writes can cause problems on this chip, + * the workaround is to read back all reg writes except those to + * mailbox regs. See tg3_write_indirect_reg32(). + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) + tp->tg3_flags |= TG3_FLAG_5701_REG_WRITE_BUG; + if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0) tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED; if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0) @@ -6013,8 +6046,11 @@ /* Force the chip into D0. */ err = tg3_set_power_state(tp, 0); - if (err) + if (err) { + printk(KERN_ERR PFX "(%s) transition to D0 failed\n", + tp->pdev->slot_name); return err; + } /* 5700 B0 chips do not support checksumming correctly due * to hardware bugs. @@ -6022,18 +6058,14 @@ if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS; - /* Regardless of whether checksums work or not, we configure - * the StrongARM chips to not compute the pseudo header checksums - * in either direction. Because of the way Linux checksum support - * works we do not need the chips to do this, and taking the load - * off of the TX/RX onboard StrongARM cpus means that they will not be - * the bottleneck. Whoever wrote Broadcom's driver did not - * understand the situation at all. He could have bothered - * to read Jes's Acenic driver because the logic (and this part of - * the Tigon2 hardware/firmware) is pretty much identical. + /* Pseudo-header checksum is done by hardware logic and not + * the offload processers, so make the chip do the pseudo- + * header checksums on receive. For transmit it is more + * convenient to do the pseudo-header checksum in software + * as Linux does that on transmit for us in all cases. */ tp->tg3_flags |= TG3_FLAG_NO_TX_PSEUDO_CSUM; - tp->tg3_flags |= TG3_FLAG_NO_RX_PSEUDO_CSUM; + tp->tg3_flags &= ~TG3_FLAG_NO_RX_PSEUDO_CSUM; /* Derive initial jumbo mode from MTU assigned in * ether_setup() via the alloc_etherdev() call @@ -6111,19 +6143,8 @@ if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) tp->tg3_flags |= TG3_FLAG_HOST_TXDS; - /* Quick sanity check. Make sure we see an expected - * value here. - */ grc_misc_cfg = tr32(GRC_MISC_CFG); grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK; - if (grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5700 && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5701 && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5702FE && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703 && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703S && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5704 && - grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_AC91002A1) - return -ENODEV; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) { @@ -6131,14 +6152,16 @@ tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ; } - /* ROFL, you should see Broadcom's driver code implementing - * this, stuff like "if (a || b)" where a and b are always - * mutually exclusive. DaveM finds like 6 bugs today, hello! - */ + /* this one is limited to 10/100 only */ if (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5702FE) tp->tg3_flags |= TG3_FLAG_10_100_ONLY; err = tg3_phy_probe(tp); + if (err) { + printk(KERN_ERR PFX "(%s) phy probe failed, err %d\n", + tp->pdev->slot_name, err); + /* ... but do not return immediately ... */ + } tg3_read_partno(tp); @@ -6192,17 +6215,10 @@ /* 5700 chips can get confused if TX buffers straddle the * 4GB address boundary in some cases. */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) { - /* ROFL! Latest Broadcom driver disables NETIF_F_HIGHDMA - * in this case instead of fixing their workaround code. - * - * Like, hey, there is this skb_copy() thing guys, - * use it. Oh I can't stop laughing... - */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) tp->dev->hard_start_xmit = tg3_start_xmit_4gbug; - } else { + else tp->dev->hard_start_xmit = tg3_start_xmit; - } tp->rx_offset = 2; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && @@ -6368,6 +6384,7 @@ (0x7 << DMA_RWCTRL_WRITE_WATER_SHIFT) | (0x7 << DMA_RWCTRL_READ_WATER_SHIFT) | (0x0f << DMA_RWCTRL_MIN_DMA_SHIFT); + /* XXX 5705 note: set MIN_DMA to zero here */ } else { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) tp->dma_rwctrl = @@ -6385,12 +6402,19 @@ (0x0f << DMA_RWCTRL_MIN_DMA_SHIFT); /* Wheee, some more chip bugs... */ - if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1 || - tp->pci_chip_rev_id == CHIPREV_ID_5703_A2 || - tp->pci_chip_rev_id == CHIPREV_ID_5703_A3 || - tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) - tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { + u32 ccval = (tr32(TG3PCI_CLOCK_CTRL) & 0x1f); + + if (ccval == 0x6 || ccval == 0x7) + tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; + } } + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) + tp->dma_rwctrl &= ~(DMA_RWCTRL_MIN_DMA + << DMA_RWCTRL_MIN_DMA_SHIFT); /* We don't do this on x86 because it seems to hurt performace. * It does help things on other platforms though. diff -Nru a/drivers/net/tg3.h b/drivers/net/tg3.h --- a/drivers/net/tg3.h Sun Feb 9 21:13:29 2003 +++ b/drivers/net/tg3.h Sun Feb 9 21:13:29 2003 @@ -113,6 +113,8 @@ #define CHIPREV_ID_5703_A2 0x1002 #define CHIPREV_ID_5703_A3 0x1003 #define CHIPREV_ID_5704_A0 0x2000 +#define CHIPREV_ID_5704_A1 0x2001 +#define CHIPREV_ID_5704_A2 0x2002 #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) #define ASIC_REV_5700 0x07 #define ASIC_REV_5701 0x00 @@ -454,6 +456,7 @@ #define RCV_RULE_DISABLE_MASK 0x7fffffff #define MAC_RCV_RULE_CFG 0x00000500 #define RCV_RULE_CFG_DEFAULT_CLASS 0x00000008 +#define MAC_LOW_WMARK_MAX_RX_FRAME 0x00000504 /* 0x504 --> 0x590 unused */ #define MAC_SERDES_CFG 0x00000590 #define MAC_SERDES_STAT 0x00000594 @@ -1136,6 +1139,7 @@ #define GRC_MISC_CFG_BOARD_ID_5703S 0x00002000 #define GRC_MISC_CFG_BOARD_ID_5704 0x00000000 #define GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00004000 +#define GRC_MISC_CFG_BOARD_ID_5704_A2 0x00008000 #define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000 #define GRC_LOCAL_CTRL 0x00006808 #define GRC_LCLCTRL_INT_ACTIVE 0x00000001 @@ -1791,6 +1795,7 @@ #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 #define TG3_FLAG_USE_MI_INTERRUPT 0x00000010 #define TG3_FLAG_ENABLE_ASF 0x00000020 +#define TG3_FLAG_5701_REG_WRITE_BUG 0x00000040 #define TG3_FLAG_POLL_SERDES 0x00000080 #define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100 #define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200 diff -Nru a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig --- a/drivers/net/tokenring/Kconfig Sun Feb 9 21:13:30 2003 +++ b/drivers/net/tokenring/Kconfig Sun Feb 9 21:13:30 2003 @@ -32,7 +32,7 @@ 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 will be called ibmtr.o. If you want to compile it as a + The module will be called ibmtr. If you want to compile it as a module, say M here and read . config IBMOL @@ -48,7 +48,7 @@ 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 will be called olympic.o. If you want to compile it + The module will be called olympic. If you want to compile it as a module, say M here and read . Also read or check the @@ -66,7 +66,7 @@ This driver is also available as a modules ( = code which can be inserted in and removed from the running kernel whenever you want). - The modules will be called lanstreamer.o. If you want to compile it + The modules will be called lanstreamer. If you want to compile it as a module, say M here and read . config 3C359 @@ -82,7 +82,7 @@ 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 will will be called 3c359.o. If you want to compile it + The module will will be called 3c359. If you want to compile it as a module, say M here and read Documentation/modules.txt. Also read the file or check the @@ -111,7 +111,7 @@ 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 will be called tms380tr.o. If you want to compile it + The module will be called tms380tr. If you want to compile it as a module, say M here and read . config TMSPCI @@ -128,7 +128,7 @@ This driver is available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called tmspci.o. If you want to compile it + The module will be called tmspci. If you want to compile it as a module, say M here and read . config TMSISA @@ -142,7 +142,7 @@ This driver is available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called tmsisa.o. If you want to compile it + The module will be called tmsisa. If you want to compile it as a module, say M here and read . config ABYSS @@ -154,7 +154,7 @@ This driver is available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called abyss.o. If you want to compile it + The module will be called abyss. If you want to compile it as a module, say M here and read . config MADGEMC @@ -166,7 +166,7 @@ This driver is available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called madgemc.o. If you want to compile it + The module will be called madgemc. If you want to compile it as a module, say M here and read . config SMCTR @@ -184,7 +184,7 @@ 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 will be called smctr.o. If you want to compile it + The module will be called smctr. If you want to compile it as a module, say M here and read . endmenu diff -Nru a/drivers/net/tokenring/Makefile b/drivers/net/tokenring/Makefile --- a/drivers/net/tokenring/Makefile Sun Feb 9 21:13:29 2003 +++ b/drivers/net/tokenring/Makefile Sun Feb 9 21:13:29 2003 @@ -2,8 +2,6 @@ # Makefile for drivers/net/tokenring # -export-objs := tms380tr.o - obj-$(CONFIG_IBMTR) += ibmtr.o obj-$(CONFIG_IBMOL) += olympic.o obj-$(CONFIG_IBMLS) += lanstreamer.o diff -Nru a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c --- a/drivers/net/tokenring/madgemc.c Sun Feb 9 21:13:36 2003 +++ b/drivers/net/tokenring/madgemc.c Sun Feb 9 21:13:36 2003 @@ -514,7 +514,7 @@ * * Register selection is normally done via three contiguous * bits. However, some boards (such as the MC16/32) use only - * two bits, plus a seperate bit in the glue chip. This + * two bits, plus a separate bit in the glue chip. This * sets the SRSX bit (the top bit). See page 4-17 in the * Yellow Book for which registers are affected. * @@ -629,7 +629,7 @@ /* * Read the card type (MC16 or MC32) from the card. * - * The configuration registers are stored in two seperate + * The configuration registers are stored in two separate * pages. Pages are flipped by clearing bit 3 of CONTROL_REG0 (PAGE) * for page zero, or setting bit 3 for page one. * diff -Nru a/drivers/net/tokenring/smctr_firmware.h b/drivers/net/tokenring/smctr_firmware.h --- a/drivers/net/tokenring/smctr_firmware.h Sun Feb 9 21:13:34 2003 +++ b/drivers/net/tokenring/smctr_firmware.h Sun Feb 9 21:13:34 2003 @@ -1,6 +1,6 @@ /* * The firmware this driver downloads into the tokenring card is a - * seperate program and is not GPL'd source code, even though the Linux + * separate program and is not GPL'd source code, even though the Linux * side driver and the routine that loads this data into the card are. * * This firmware is licensed to you strictly for use in conjunction diff -Nru a/drivers/net/tokenring/tmsisa.c b/drivers/net/tokenring/tmsisa.c --- a/drivers/net/tokenring/tmsisa.c Sun Feb 9 21:13:29 2003 +++ b/drivers/net/tokenring/tmsisa.c Sun Feb 9 21:13:29 2003 @@ -302,7 +302,7 @@ * Calling this on a board that does not support it can be a very * dangerous thing. The Madge board, for instance, will lock your * machine hard when this is called. Luckily, its supported in a - * seperate driver. --ASF + * separate driver. --ASF */ static void tms_isa_read_eeprom(struct net_device *dev) { diff -Nru a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c --- a/drivers/net/tokenring/tmspci.c Sun Feb 9 21:13:35 2003 +++ b/drivers/net/tokenring/tmspci.c Sun Feb 9 21:13:35 2003 @@ -190,7 +190,7 @@ * Calling this on a board that does not support it can be a very * dangerous thing. The Madge board, for instance, will lock your * machine hard when this is called. Luckily, its supported in a - * seperate driver. --ASF + * separate driver. --ASF */ static void tms_pci_read_eeprom(struct net_device *dev) { diff -Nru a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig --- a/drivers/net/tulip/Kconfig Sun Feb 9 21:13:34 2003 +++ b/drivers/net/tulip/Kconfig Sun Feb 9 21:13:34 2003 @@ -27,7 +27,7 @@ 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 will be called tulip.o. If you want to compile it as a + The module will be called tulip. If you want to compile it as a module, say M here and read as well as . @@ -48,7 +48,7 @@ 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 will be called tulip.o. If you want to compile it as a + The module will be called tulip. If you want to compile it as a module, say M here and read as well as . @@ -86,7 +86,7 @@ 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 will be called de4x5.o. If you want to compile it as a + The module will be called de4x5. If you want to compile it as a module, say M here and read as well as . @@ -110,7 +110,7 @@ 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 will be called dmfe.o. If you want to compile it as a + The module will be called dmfe. If you want to compile it as a module, say M here and read as well as . @@ -125,7 +125,7 @@ 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 will be called xircom_cb.o. If you want to compile + The module will be called xircom_cb. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -140,7 +140,7 @@ 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 will be called xircom_tulip_cb.o. If you want to compile + The module will be called xircom_tulip_cb. If you want to compile it as a module, say M here and read . If unsure, say N. diff -Nru a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c --- a/drivers/net/tulip/de4x5.c Sun Feb 9 21:13:28 2003 +++ b/drivers/net/tulip/de4x5.c Sun Feb 9 21:13:28 2003 @@ -440,7 +440,7 @@ ========================================================================= */ -static const char *version = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n"; +static char version[] __initdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n"; #include #include diff -Nru a/drivers/net/tulip/de4x5.h b/drivers/net/tulip/de4x5.h --- a/drivers/net/tulip/de4x5.h Sun Feb 9 21:13:33 2003 +++ b/drivers/net/tulip/de4x5.h Sun Feb 9 21:13:33 2003 @@ -1026,6 +1026,4 @@ #define DE4X5_SET_OMR 0x0d /* Set the OMR Register contents */ #define DE4X5_GET_REG 0x0e /* Get the DE4X5 Registers */ -#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) - #define MOTO_SROM_BUG ((lp->active == 8) && (((le32_to_cpu(get_unaligned(((s32 *)dev->dev_addr))))&0x00ffffff)==0x3e0008)) diff -Nru a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig --- a/drivers/net/wan/Kconfig Sun Feb 9 21:13:30 2003 +++ b/drivers/net/wan/Kconfig Sun Feb 9 21:13:30 2003 @@ -54,7 +54,7 @@ The driver will be compiled as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called cosa.o. For general information about + The module will be called cosa. For general information about modules read . # @@ -76,7 +76,7 @@ use this driver. If you want to compile this as a module, say M and read - . The module will be called comx.o. + . The module will be called comx. config COMX_HW_COMX tristate "Support for COMX/CMX/HiCOMX boards" @@ -90,7 +90,7 @@ If you want to compile this as a module, say M and read . The module will be called - comx-hw-comx.o. + comx-hw-comx. config COMX_HW_LOCOMX tristate "Support for LoCOMX board" @@ -101,7 +101,7 @@ If you want to compile this as a module, say M and read . The module will be called - comx-hw-locomx.o. + comx-hw-locomx. config COMX_HW_MIXCOM tristate "Support for MixCOM board" @@ -119,7 +119,7 @@ If you want to compile this as a module, say M and read . The module will be called - comx-hw-mixcom.o. + comx-hw-mixcom. config COMX_HW_MUNICH tristate "Support for MUNICH based boards: SliceCOM, PCICOM (WelCOM)" @@ -130,7 +130,7 @@ 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 will be called comx-hw-munich.o. If you want to compile it + The module will be called comx-hw-munich. If you want to compile it as a module, say M here and read Documentation/modules.txt. Read linux/Documentation/networking/slicecom.txt for help on @@ -147,7 +147,7 @@ If you want to compile this as a module, say M and read . The module will be called - comx-proto-ppp.o. + comx-proto-ppp. config COMX_PROTO_LAPB tristate "Support for LAPB protocol on MultiGate boards" @@ -158,7 +158,7 @@ If you want to compile this as a module, say M and read . The module will be called - comx-proto-lapb.o. + comx-proto-lapb. config COMX_PROTO_FR tristate "Support for Frame Relay on MultiGate boards" @@ -169,7 +169,7 @@ If you want to compile this as a module, say M and read . The module will be called - comx-proto-fr.o. + comx-proto-fr. # # The Etinc driver has not been tested as non-modular yet. @@ -185,7 +185,7 @@ The driver will be compiled as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called dscc4.o. For general information about + The module will be called dscc4. For general information about modules read . # @@ -214,7 +214,7 @@ To change setting such as syncPPP vs cisco HDLC or clock source you will need lmcctl. It is available at . - This code is also available as a module called lmc.o ( = code + This code is also available as a module called lmc ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -229,7 +229,7 @@ This driver can only be compiled as a module ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to do that, say M here. The module will be called - sealevel.o. + sealevel. config SYNCLINK_SYNCPPP tristate "SyncLink HDLC/SYNCPPP support" @@ -317,7 +317,7 @@ 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 Documentation/modules.txt. The module will be - called pc300.o. + called pc300. If you haven't heard about it, it's safe to say N. @@ -369,7 +369,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want) say M here and read . - The module will be called farsync.o and if you want the module to be + The module will be called farsync and if you want the module to be automatically loaded when the interface is referenced then you should add "alias hdlcX farsync" to /etc/modules.conf for each interface, where X is 0, 1, 2, ... @@ -408,7 +408,7 @@ 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 will be called dlci.o. If you want to compile it as a + The module will be called dlci. If you want to compile it as a module, say M here and read . config DLCI_COUNT @@ -441,7 +441,7 @@ 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 will be called sdla.o. If you want to compile it as a + The module will be called sdla. If you want to compile it as a module, say M here and read . # Wan router core. @@ -491,7 +491,7 @@ The driver will be compiled as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called wanpipe.o. For general information about + The module will be called wanpipe. For general information about modules read . config WANPIPE_CHDLC @@ -583,7 +583,7 @@ The driver will be compiled as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called cyclomx.o. For general information about + The module will be called cyclomx. For general information about modules read . config CYCLOMX_X25 @@ -610,7 +610,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called lapbether.o. If unsure, say N. + will be called lapbether. If unsure, say N. config X25_ASY tristate "X.25 async driver (EXPERIMENTAL)" @@ -625,7 +625,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called x25_asy.o. If unsure, say N. + will be called x25_asy. If unsure, say N. config SBNI tristate "Granch SBNI12 Leased Line adapter support" @@ -634,7 +634,7 @@ This is a driver for ISA SBNI12-xx cards which are low cost alternatives to leased line modems. Say Y if you want to insert the driver into the kernel or say M to compile it as a module (the - module will be called sbni.o). + module will be called sbni). You can find more information and last versions of drivers and utilities at . If you have any question you diff -Nru a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile --- a/drivers/net/wan/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/net/wan/Makefile Sun Feb 9 21:13:32 2003 @@ -5,9 +5,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs := z85230.o syncppp.o comx.o sdladrv.o cycx_drv.o hdlc_generic.o \ - dlci.o - wanpipe-y := sdlamain.o sdla_ft1.o wanpipe-$(CONFIG_WANPIPE_X25) += sdla_x25.o wanpipe-$(CONFIG_WANPIPE_FR) += sdla_fr.o diff -Nru a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c --- a/drivers/net/wan/dscc4.c Sun Feb 9 21:13:30 2003 +++ b/drivers/net/wan/dscc4.c Sun Feb 9 21:13:30 2003 @@ -1787,7 +1787,7 @@ return -ENOMEM; } -static void __exit dscc4_remove_one(struct pci_dev *pdev) +static void __devexit dscc4_remove_one(struct pci_dev *pdev) { struct dscc4_pci_priv *ppriv; struct dscc4_dev_priv *root; @@ -1867,7 +1867,7 @@ .name = DRV_NAME, .id_table = dscc4_pci_tbl, .probe = dscc4_init_one, - .remove = dscc4_remove_one, + .remove = __devexit_p(dscc4_remove_one), }; static int __init dscc4_init_module(void) diff -Nru a/drivers/net/wan/lmc/lmc_ioctl.h b/drivers/net/wan/lmc/lmc_ioctl.h --- a/drivers/net/wan/lmc/lmc_ioctl.h Sun Feb 9 21:13:29 2003 +++ b/drivers/net/wan/lmc/lmc_ioctl.h Sun Feb 9 21:13:29 2003 @@ -173,7 +173,7 @@ /* * Some of the MII16 bits are mirrored in the MII17 register as well, - * but let's keep thing seperate for now, and get only the cable from + * but let's keep thing separate for now, and get only the cable from * the MII17. */ #define LMC_MII17_SSI_CABLE_MASK 0x0038 /* mask to extract the cable type */ diff -Nru a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c --- a/drivers/net/wan/lmc/lmc_main.c Sun Feb 9 21:13:30 2003 +++ b/drivers/net/wan/lmc/lmc_main.c Sun Feb 9 21:13:30 2003 @@ -1074,7 +1074,7 @@ * This prevents taking someone else's device. * * Check either the subvendor or the subdevice, some systems reverse - * the setting in the bois, seems to be version and arch dependant? + * the setting in the bois, seems to be version and arch dependent? * Fix the two variables * */ diff -Nru a/drivers/net/wan/lmc/lmc_ver.h b/drivers/net/wan/lmc/lmc_ver.h --- a/drivers/net/wan/lmc/lmc_ver.h Sun Feb 9 21:13:29 2003 +++ b/drivers/net/wan/lmc/lmc_ver.h Sun Feb 9 21:13:29 2003 @@ -25,7 +25,7 @@ * made the souce code not only hard to read but version problems hard * to track down. If I'm overiding a function/etc with something in * this file it will be prefixed by "LMC_" which will mean look - * here for the version dependant change that's been done. + * here for the version dependent change that's been done. * */ diff -Nru a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig --- a/drivers/net/wireless/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/net/wireless/Kconfig Sun Feb 9 21:13:29 2003 @@ -31,7 +31,7 @@ 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 will be called wavelan.o. If you want to compile it as a + The module will be called wavelan. If you want to compile it as a module, say M here and read as well as . @@ -50,7 +50,7 @@ and Cisco proprietary API, so both the Linux Wireless Tools and the Cisco Linux utilities can be used to configure the card. - The driver can be compiled as a module and will be named "airo.o". + The driver can be compiled as a module and will be named "airo". config HERMES tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)" @@ -121,7 +121,7 @@ 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 will be called netwave_cs.o. If you want to compile it + The module will be called netwave_cs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -135,7 +135,7 @@ 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 will be called wavelan_cs.o. If you want to compile it + The module will be called wavelan_cs. If you want to compile it as a module, say M here and read . If unsure, say N. diff -Nru a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile --- a/drivers/net/wireless/Makefile Sun Feb 9 21:13:37 2003 +++ b/drivers/net/wireless/Makefile Sun Feb 9 21:13:37 2003 @@ -2,9 +2,6 @@ # Makefile for the Linux Wireless network device drivers. # -# Things that need to export symbols -export-objs := airo.o orinoco.o hermes.o - # Obsolete cards obj-$(CONFIG_WAVELAN) += wavelan.o obj-$(CONFIG_PCMCIA_NETWAVE) += netwave_cs.o diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c --- a/drivers/net/wireless/airo.c Sun Feb 9 21:13:29 2003 +++ b/drivers/net/wireless/airo.c Sun Feb 9 21:13:29 2003 @@ -5144,7 +5144,7 @@ /*------------------------------------------------------------------*/ /* - * Translate scan data returned from the card to a card independant + * Translate scan data returned from the card to a card independent * format that the Wireless Tools will understand - Jean II */ static inline char *airo_translate_scan(struct net_device *dev, diff -Nru a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c --- a/drivers/net/wireless/airo_cs.c Sun Feb 9 21:13:30 2003 +++ b/drivers/net/wireless/airo_cs.c Sun Feb 9 21:13:30 2003 @@ -216,6 +216,7 @@ return NULL; } memset(link, 0, sizeof(struct dev_link_t)); + init_timer(&link->release); link->release.function = &airo_release; link->release.data = (u_long)link; diff -Nru a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c --- a/drivers/net/wireless/netwave_cs.c Sun Feb 9 21:13:36 2003 +++ b/drivers/net/wireless/netwave_cs.c Sun Feb 9 21:13:36 2003 @@ -462,6 +462,7 @@ memset(priv, 0, sizeof(*priv)); link = &priv->link; dev = &priv->dev; link->priv = dev->priv = priv; + init_timer(&link->release); link->release.function = &netwave_release; link->release.data = (u_long)link; diff -Nru a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h --- a/drivers/net/wireless/orinoco.h Sun Feb 9 21:13:30 2003 +++ b/drivers/net/wireless/orinoco.h Sun Feb 9 21:13:30 2003 @@ -36,7 +36,7 @@ struct orinoco_private { - void *card; /* Pointer to card dependant structure */ + void *card; /* Pointer to card dependent structure */ int (*hard_reset)(struct orinoco_private *); /* Synchronisation stuff */ diff -Nru a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c --- a/drivers/net/wireless/orinoco_cs.c Sun Feb 9 21:13:36 2003 +++ b/drivers/net/wireless/orinoco_cs.c Sun Feb 9 21:13:36 2003 @@ -203,6 +203,7 @@ link->priv = dev; /* Initialize the dev_link_t structure */ + init_timer(&link->release); link->release.function = &orinoco_cs_release; link->release.data = (u_long) link; diff -Nru a/drivers/nubus/Makefile b/drivers/nubus/Makefile --- a/drivers/nubus/Makefile Sun Feb 9 21:13:36 2003 +++ b/drivers/nubus/Makefile Sun Feb 9 21:13:36 2003 @@ -2,8 +2,6 @@ # Makefile for the nubus specific drivers. # -export-objs := nubus_syms.o - obj-y := nubus.o obj-$(CONFIG_MODULES) += nubus_syms.o diff -Nru a/drivers/parisc/Makefile b/drivers/parisc/Makefile --- a/drivers/parisc/Makefile Sun Feb 9 21:13:29 2003 +++ b/drivers/parisc/Makefile Sun Feb 9 21:13:29 2003 @@ -2,8 +2,6 @@ # Makefile for most of the non-PCI devices in PA-RISC machines # -export-objs := gsc.o superio.o - obj-y := obj-m := obj-n := diff -Nru a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c --- a/drivers/parisc/ccio-dma.c Sun Feb 9 21:13:29 2003 +++ b/drivers/parisc/ccio-dma.c Sun Feb 9 21:13:29 2003 @@ -852,7 +852,7 @@ ** in the DMA stream. Allocates PDIR entries but does not fill them. ** Returns the number of DMA chunks. ** -** Doing the fill seperate from the coalescing/allocation keeps the +** Doing the fill separate from the coalescing/allocation keeps the ** code simpler. Future enhancement could make one pass through ** the sglist do both. */ @@ -1553,38 +1553,6 @@ ioc_count++; return 0; -} - -struct pci_dev * ccio_get_fake(const struct parisc_device *dev) -{ - struct ioc *ioc; - - dev = find_pa_parent_type(dev, HPHW_IOA); - if(!dev) - return NULL; - - ioc = ccio_find_ioc(dev->hw_path); - if(!ioc) - return NULL; - - if(ioc->fake_pci_dev) - return ioc->fake_pci_dev; - - ioc->fake_pci_dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); - if(ioc->fake_pci_dev == NULL) { - printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); - return NULL; - } - memset(ioc->fake_pci_dev, 0, sizeof(struct pci_dev)); - - ioc->fake_pci_dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL); - if(ioc->fake_pci_dev->dev.platform_data == NULL) { - printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); - return NULL; - } - - HBA_DATA(ioc->fake_pci_dev->dev.platform_data)->iommu = ioc; - return ioc->fake_pci_dev; } /* We *can't* support JAVA (T600). Venture there at your own risk. */ diff -Nru a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c --- a/drivers/parisc/ccio-rm-dma.c Sun Feb 9 21:13:29 2003 +++ b/drivers/parisc/ccio-rm-dma.c Sun Feb 9 21:13:29 2003 @@ -116,7 +116,7 @@ { int tmp = nents; - /* KISS: map each buffer seperately. */ + /* KISS: map each buffer separately. */ while (nents) { sg_dma_address(sglist) = ccio_map_single(dev, sglist->address, sglist->length, direction); sg_dma_len(sglist) = sglist->length; diff -Nru a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c --- a/drivers/parisc/sba_iommu.c Sun Feb 9 21:13:34 2003 +++ b/drivers/parisc/sba_iommu.c Sun Feb 9 21:13:34 2003 @@ -974,8 +974,8 @@ * * See Documentation/DMA-mapping.txt */ -static void * -sba_alloc_consistent(struct device *hwdev, size_t size, dma_addr_t *dma_handle) +static void *sba_alloc_consistent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, int gfp) { void *ret; @@ -985,7 +985,7 @@ return 0; } - ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size)); + ret = (void *) __get_free_pages(gfp, get_order(size)); if (ret) { memset(ret, 0, size); @@ -1132,7 +1132,7 @@ * in the DMA stream. Allocates PDIR entries but does not fill them. * Returns the number of DMA chunks. * - * Doing the fill seperate from the coalescing/allocation keeps the + * Doing the fill separate from the coalescing/allocation keeps the * code simpler. Future enhancement could make one pass through * the sglist do both. */ diff -Nru a/drivers/parport/Kconfig b/drivers/parport/Kconfig --- a/drivers/parport/Kconfig Sun Feb 9 21:13:36 2003 +++ b/drivers/parport/Kconfig Sun Feb 9 21:13:36 2003 @@ -28,7 +28,7 @@ ( = 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 - parport.o. If you have more than one parallel port and want to + parport. If you have more than one parallel port and want to specify which port and IRQ to be used by this driver at module load time, take a look at . @@ -47,7 +47,7 @@ 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 - parport_pc.o. + parport_pc. If unsure, say Y. @@ -63,7 +63,7 @@ help This adds support for multi-IO PCI cards that have parallel and serial ports. You should say Y or M here. If you say M, the module - will be called parport_serial.o. + will be called parport_serial. config PARPORT_PC_FIFO bool "Use FIFO/DMA if available (EXPERIMENTAL)" @@ -103,7 +103,7 @@ help Say Y here if you need support for the parallel port hardware on Amiga machines. This code is also available as a module (say M), - called parport_amiga.o. If in doubt, saying N is the safe plan. + called parport_amiga. If in doubt, saying N is the safe plan. config PARPORT_MFC3 tristate "Multiface III parallel port" @@ -111,7 +111,7 @@ help Say Y here if you need parallel port support for the MFC3 card. This code is also available as a module (say M), called - parport_mfc3.o. If in doubt, saying N is the safe plan. + parport_mfc3. If in doubt, saying N is the safe plan. config PARPORT_ATARI tristate "Atari hardware" @@ -119,7 +119,7 @@ help Say Y here if you need support for the parallel port hardware on Atari machines. This code is also available as a module (say M), - called parport_atari.o. If in doubt, saying N is the safe plan. + called parport_atari. If in doubt, saying N is the safe plan. config PARPORT_GSC tristate diff -Nru a/drivers/parport/Makefile b/drivers/parport/Makefile --- a/drivers/parport/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/parport/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for the kernel Parallel port device drivers. # -export-objs := init.o parport_pc.o - parport-objs := share.o ieee1284.o ieee1284_ops.o init.o procfs.o ifeq ($(CONFIG_PARPORT_1284),y) diff -Nru a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c --- a/drivers/parport/parport_cs.c Sun Feb 9 21:13:37 2003 +++ b/drivers/parport/parport_cs.c Sun Feb 9 21:13:37 2003 @@ -134,6 +134,7 @@ memset(info, 0, sizeof(*info)); link = &info->link; link->priv = info; + init_timer(&link->release); link->release.function = &parport_cs_release; link->release.data = (u_long)link; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; diff -Nru a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c --- a/drivers/parport/parport_gsc.c Sun Feb 9 21:13:35 2003 +++ b/drivers/parport/parport_gsc.c Sun Feb 9 21:13:35 2003 @@ -40,6 +40,7 @@ #include #include +#include #include #include diff -Nru a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c --- a/drivers/parport/parport_pc.c Sun Feb 9 21:13:36 2003 +++ b/drivers/parport/parport_pc.c Sun Feb 9 21:13:36 2003 @@ -2987,7 +2987,7 @@ .id_table = pnp_dev_table, }; #else -static const struct pnp_driver parport_pc_pnp_driver; +static struct pnp_driver parport_pc_pnp_driver; #endif /* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */ diff -Nru a/drivers/pci/Makefile b/drivers/pci/Makefile --- a/drivers/pci/Makefile Sun Feb 9 21:13:36 2003 +++ b/drivers/pci/Makefile Sun Feb 9 21:13:36 2003 @@ -2,11 +2,9 @@ # Makefile for the PCI bus specific drivers. # -export-objs := access.o hotplug.o pci-driver.o pci.o pool.o \ - probe.o proc.o search.o setup-bus.o - obj-y += access.o probe.o pci.o pool.o quirks.o \ - names.o pci-driver.o search.o hotplug.o + names.o pci-driver.o search.o hotplug.o \ + pci-sysfs.o obj-$(CONFIG_PM) += power.o obj-$(CONFIG_PROC_FS) += proc.o diff -Nru a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c --- a/drivers/pci/hotplug.c Sun Feb 9 21:13:36 2003 +++ b/drivers/pci/hotplug.c Sun Feb 9 21:13:36 2003 @@ -2,6 +2,14 @@ #include #include "pci.h" +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + #ifdef CONFIG_HOTPLUG int pci_hotplug (struct device *dev, char **envp, int num_envp, @@ -57,13 +65,179 @@ return 0; } -#else + +static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent) +{ + struct list_head *ln; + struct pci_dev *dev; + struct pci_dev_wrapped wrapped_dev; + int result = 0; + + DBG("scanning bus %02x\n", wrapped_bus->bus->number); + + if (fn->pre_visit_pci_bus) { + result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent); + if (result) + return result; + } + + ln = wrapped_bus->bus->devices.next; + while (ln != &wrapped_bus->bus->devices) { + dev = pci_dev_b(ln); + ln = ln->next; + + memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped)); + wrapped_dev.dev = dev; + + result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus); + if (result) + return result; + } + + if (fn->post_visit_pci_bus) + result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent); + + return result; +} + +static int pci_visit_bridge (struct pci_visit * fn, + struct pci_dev_wrapped *wrapped_dev, + struct pci_bus_wrapped *wrapped_parent) +{ + struct pci_bus *bus; + struct pci_bus_wrapped wrapped_bus; + int result = 0; + + DBG("scanning bridge %02x, %02x\n", PCI_SLOT(wrapped_dev->dev->devfn), + PCI_FUNC(wrapped_dev->dev->devfn)); + + if (fn->visit_pci_dev) { + result = fn->visit_pci_dev(wrapped_dev, wrapped_parent); + if (result) + return result; + } + + bus = wrapped_dev->dev->subordinate; + if(bus) { + memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped)); + wrapped_bus.bus = bus; + + result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev); + } + return result; +} + +/** + * pci_visit_dev - scans the pci buses. + * Every bus and every function is presented to a custom + * function that can act upon it. + */ +int pci_visit_dev (struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev, + struct pci_bus_wrapped *wrapped_parent) +{ + struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL; + int result = 0; + + if (!dev) + return 0; + + if (fn->pre_visit_pci_dev) { + result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent); + if (result) + return result; + } + + switch (dev->class >> 8) { + case PCI_CLASS_BRIDGE_PCI: + result = pci_visit_bridge(fn, wrapped_dev, + wrapped_parent); + if (result) + return result; + break; + default: + DBG("scanning device %02x, %02x\n", + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + if (fn->visit_pci_dev) { + result = fn->visit_pci_dev (wrapped_dev, + wrapped_parent); + if (result) + return result; + } + } + + if (fn->post_visit_pci_dev) + result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent); + + return result; +} +EXPORT_SYMBOL(pci_visit_dev); + +/** + * pci_is_dev_in_use - query devices' usage + * @dev: PCI device to query + * + * Queries whether a given PCI device is in use by a driver or not. + * Returns 1 if the device is in use, 0 if it is not. + */ +int pci_is_dev_in_use(struct pci_dev *dev) +{ + /* + * dev->driver will be set if the device is in use by a new-style + * driver -- otherwise, check the device's regions to see if any + * driver has claimed them. + */ + + int i; + int inuse = 0; + + if (dev->driver) { + /* Assume driver feels responsible */ + return 1; + } + + for (i = 0; !dev->driver && !inuse && (i < 6); i++) { + if (!pci_resource_start(dev, i)) + continue; + if (pci_resource_flags(dev, i) & IORESOURCE_IO) { + inuse = check_region(pci_resource_start(dev, i), + pci_resource_len(dev, i)); + } else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) { + inuse = check_mem_region(pci_resource_start(dev, i), + pci_resource_len(dev, i)); + } + } + return inuse; +} +EXPORT_SYMBOL(pci_is_dev_in_use); + +/** + * pci_remove_device_safe - remove an unused hotplug device + * @dev: the device to remove + * + * Delete the device structure from the device lists and + * notify userspace (/sbin/hotplug), but only if the device + * in question is not being used by a driver. + * Returns 0 on success. + */ +int pci_remove_device_safe(struct pci_dev *dev) +{ + if (pci_is_dev_in_use(dev)) { + return -EBUSY; + } + pci_remove_device(dev); + return 0; +} +EXPORT_SYMBOL(pci_remove_device_safe); + +#else /* CONFIG_HOTPLUG */ + int pci_hotplug (struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { return -ENODEV; } -#endif + +#endif /* CONFIG_HOTPLUG */ /** * pci_insert_device - insert a pci device @@ -81,6 +255,8 @@ #ifdef CONFIG_PROC_FS pci_proc_attach_device(dev); #endif + /* add sysfs device files */ + pci_create_sysfs_dev_files(dev); } static void diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/pci/pci-sysfs.c Sun Feb 9 21:13:38 2003 @@ -0,0 +1,77 @@ +/* + * drivers/pci/pci-sysfs.c + * + * (C) Copyright 2002 Greg Kroah-Hartman + * (C) Copyright 2002 IBM Corp. + * + * File attributes for PCI devices + * + * Modeled after usb's driverfs.c + * + */ + + +#include +#include +#include +#include + +#include "pci.h" + +#if BITS_PER_LONG == 32 +#define LONG_FORMAT "\t%08lx" +#else +#define LONG_FORMAT "\t%16lx" +#endif + +/* show configuration fields */ +#define pci_config_attr(field, format_string) \ +static ssize_t \ +show_##field (struct device *dev, char *buf) \ +{ \ + struct pci_dev *pdev; \ + \ + pdev = to_pci_dev (dev); \ + return sprintf (buf, format_string, pdev->field); \ +} \ +static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); + +pci_config_attr(vendor, "%04x\n"); +pci_config_attr(device, "%04x\n"); +pci_config_attr(subsystem_vendor, "%04x\n"); +pci_config_attr(subsystem_device, "%04x\n"); +pci_config_attr(class, "%06x\n"); +pci_config_attr(irq, "%u\n"); + +/* show resources */ +static ssize_t +pci_show_resources(struct device * dev, char * buf) +{ + struct pci_dev * pci_dev = to_pci_dev(dev); + char * str = buf; + int i; + + for (i = 0; i < DEVICE_COUNT_RESOURCE && pci_resource_start(pci_dev,i); i++) { + str += sprintf(str,LONG_FORMAT LONG_FORMAT LONG_FORMAT "\n", + pci_resource_start(pci_dev,i), + pci_resource_end(pci_dev,i), + pci_resource_flags(pci_dev,i)); + } + return (str - buf); +} + +static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL); + +void pci_create_sysfs_dev_files (struct pci_dev *pdev) +{ + struct device *dev = &pdev->dev; + + /* current configuration's attributes */ + device_create_file (dev, &dev_attr_vendor); + device_create_file (dev, &dev_attr_device); + device_create_file (dev, &dev_attr_subsystem_vendor); + device_create_file (dev, &dev_attr_subsystem_device); + device_create_file (dev, &dev_attr_class); + device_create_file (dev, &dev_attr_irq); + device_create_file (dev, &dev_attr_resource); +} diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h --- a/drivers/pci/pci.h Sun Feb 9 21:13:30 2003 +++ b/drivers/pci/pci.h Sun Feb 9 21:13:30 2003 @@ -2,4 +2,4 @@ extern int pci_hotplug (struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); - +extern void pci_create_sysfs_dev_files(struct pci_dev *pdev); diff -Nru a/drivers/pci/proc.c b/drivers/pci/proc.c --- a/drivers/pci/proc.c Sun Feb 9 21:13:32 2003 +++ b/drivers/pci/proc.c Sun Feb 9 21:13:32 2003 @@ -373,32 +373,6 @@ struct proc_dir_entry *proc_bus_pci_dir; -/* driverfs files */ -static ssize_t pci_show_irq(struct device * dev, char * buf) -{ - struct pci_dev * pci_dev = to_pci_dev(dev); - return sprintf(buf,"%u\n",pci_dev->irq); -} - -static DEVICE_ATTR(irq,S_IRUGO,pci_show_irq,NULL); - -static ssize_t pci_show_resources(struct device * dev, char * buf) -{ - struct pci_dev * pci_dev = to_pci_dev(dev); - char * str = buf; - int i; - - for (i = 0; i < DEVICE_COUNT_RESOURCE && pci_resource_start(pci_dev,i); i++) { - str += sprintf(str,LONG_FORMAT LONG_FORMAT LONG_FORMAT "\n", - pci_resource_start(pci_dev,i), - pci_resource_end(pci_dev,i), - pci_resource_flags(pci_dev,i)); - } - return (str - buf); -} - -static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL); - int pci_proc_attach_device(struct pci_dev *dev) { struct pci_bus *bus = dev->bus; @@ -422,8 +396,6 @@ e->data = dev; e->size = PCI_CFG_SPACE_SIZE; - device_create_file(&dev->dev,&dev_attr_irq); - device_create_file(&dev->dev,&dev_attr_resource); return 0; } diff -Nru a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig --- a/drivers/pcmcia/Kconfig Sun Feb 9 21:13:34 2003 +++ b/drivers/pcmcia/Kconfig Sun Feb 9 21:13:34 2003 @@ -25,8 +25,8 @@ This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - When compiled this way, there will be modules called pcmcia_core.o - and ds.o. If you want to compile it as a module, say M here and + When compiled this way, there will be modules called pcmcia_core + and ds. If you want to compile it as a module, say M here and read . config CARDBUS diff -Nru a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile --- a/drivers/pcmcia/Makefile Sun Feb 9 21:13:35 2003 +++ b/drivers/pcmcia/Makefile Sun Feb 9 21:13:35 2003 @@ -2,8 +2,6 @@ # Makefile for the kernel pcmcia subsystem (c/o David Hinds) # -export-objs := ds.o cs.o yenta.o sa1100_generic.o - obj-$(CONFIG_PCMCIA) += pcmcia_core.o ds.o ifeq ($(CONFIG_CARDBUS),y) obj-$(CONFIG_PCMCIA) += yenta_socket.o diff -Nru a/drivers/pcmcia/sa1100_trizeps.c b/drivers/pcmcia/sa1100_trizeps.c --- a/drivers/pcmcia/sa1100_trizeps.c Sun Feb 9 21:13:33 2003 +++ b/drivers/pcmcia/sa1100_trizeps.c Sun Feb 9 21:13:33 2003 @@ -13,7 +13,8 @@ #include #include -#include // included trizeps.h +#include +#include #include #include #include @@ -54,7 +55,7 @@ return NUMBER_OF_TRIZEPS_PCMCIA_SLOTS; irq_err: - printk( KERN_ERR __FUNCTION__ ": PCMCIA Request for IRQ %u failed\n", TRIZEPS_IRQ_PCMCIA_CD0 ); + printk( KERN_ERR "%s(): PCMCIA Request for IRQ %u failed\n", __FUNCTION__, TRIZEPS_IRQ_PCMCIA_CD0 ); return -1; } diff -Nru a/drivers/pnp/Kconfig b/drivers/pnp/Kconfig --- a/drivers/pnp/Kconfig Sun Feb 9 21:13:32 2003 +++ b/drivers/pnp/Kconfig Sun Feb 9 21:13:32 2003 @@ -56,7 +56,7 @@ Say Y here if you would like support for ISA Plug and Play devices. Some information is in . - This support is also available as a module called isapnp.o ( = + This support is also available as a module called isapnp ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . diff -Nru a/drivers/pnp/Makefile b/drivers/pnp/Makefile --- a/drivers/pnp/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/pnp/Makefile Sun Feb 9 21:13:28 2003 @@ -9,4 +9,3 @@ obj-$(CONFIG_PNPBIOS) += pnpbios/ obj-$(CONFIG_ISAPNP) += isapnp/ -export-objs := core.o driver.o resource.o $(pnp-card-y) diff -Nru a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile --- a/drivers/pnp/isapnp/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/pnp/isapnp/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for the kernel ISAPNP driver. # -export-objs := core.o compat.o - isapnp-proc-$(CONFIG_PROC_FS) = proc.o obj-y := core.o compat.o $(isapnp-proc-y) diff -Nru a/drivers/pnp/pnpbios/Makefile b/drivers/pnp/pnpbios/Makefile --- a/drivers/pnp/pnpbios/Makefile Sun Feb 9 21:13:35 2003 +++ b/drivers/pnp/pnpbios/Makefile Sun Feb 9 21:13:35 2003 @@ -2,8 +2,6 @@ # Makefile for the kernel PNPBIOS driver. # -export-objs := core.o - pnpbios-proc-$(CONFIG_PROC_FS) = proc.o obj-y := core.o $(pnpbios-proc-y) diff -Nru a/drivers/s390/Kconfig b/drivers/s390/Kconfig --- a/drivers/s390/Kconfig Sun Feb 9 21:13:35 2003 +++ b/drivers/s390/Kconfig Sun Feb 9 21:13:35 2003 @@ -48,7 +48,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called loop.o. + will be called loop. Most users will answer N here. @@ -77,7 +77,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called nbd.o. + will be called nbd. If unsure, say N. @@ -97,7 +97,7 @@ 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 and read . The module will be - called rd.o. + called rd. Most normal users won't need the RAM disk functionality, and can thus say N here. @@ -127,7 +127,7 @@ or zSeries as a disk. This is useful as a _fast_ swap device if you want to access more than 2G of memory when running in 31 bit mode. This option is also available as a module which will be called - xpram.o. If unsure, say "N". + xpram. If unsure, say "N". comment "S/390 block device drivers" @@ -286,7 +286,7 @@ least one of the tape interface options and one of the tape hardware options in order to access a tape device. This option is also available as a module. The module will be - called tape390.o and include all selected interfaces and + called tape390 and include all selected interfaces and hardware drivers. comment "S/390 tape interface support" @@ -368,7 +368,7 @@ 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 dummy.o. If you want to use more than one dummy + will be called dummy. If you want to use more than one dummy device at a time, you need to compile this driver as a module. Instead of 'dummy', the devices will then be called 'dummy0', 'dummy1' etc. @@ -393,7 +393,7 @@ 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 bonding.o. + will be called bonding. config EQUALIZER tristate "EQL (serial line load balancing) support" @@ -414,7 +414,7 @@ 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 will be called eql.o. If you want to compile it as a + The module will be called eql. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -438,7 +438,7 @@ 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 will be called tun.o. If you want to compile it as a + The module will be called tun. If you want to compile it as a module, say M here and read . If you don't know what to use this for, you don't need it. @@ -524,7 +524,7 @@ or zSeries. This device driver supports Token Ring (IEEE 802.5), FDDI (IEEE 802.7) and Ethernet. This option is also available as a module which will be - called lcs.o . If you do not know what it is, it's safe to say "Y". + called lcs . If you do not know what it is, it's safe to say "Y". config CTC tristate "CTC device support" @@ -535,7 +535,7 @@ coupling using ESCON. It also supports virtual CTCs when running under VM. It will use the channel device configuration if this is available. This option is also available as a module which will be - called ctc.o. If you do not know what it is, it's safe to say "Y". + called ctc. If you do not know what it is, it's safe to say "Y". config IUCV tristate "IUCV device support (VM only)" @@ -543,7 +543,7 @@ help Select this option if you want to use inter-user communication vehicle networking under VM or VIF. This option is also available - as a module which will be called iucv.o. If unsure, say "Y". + as a module which will be called iucv. If unsure, say "Y". config CCWGROUP tristate diff -Nru a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile --- a/drivers/s390/block/Makefile Sun Feb 9 21:13:37 2003 +++ b/drivers/s390/block/Makefile Sun Feb 9 21:13:37 2003 @@ -2,8 +2,6 @@ # S/390 block devices # -export-objs := dasd.o dasd_devmap.o dasd_ioctl.o dasd_erp.o - dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_9343_erp.o dasd_fba_mod-objs := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o dasd_diag_mod-objs := dasd_diag.o diff -Nru a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile --- a/drivers/s390/char/Makefile Sun Feb 9 21:13:31 2003 +++ b/drivers/s390/char/Makefile Sun Feb 9 21:13:31 2003 @@ -2,8 +2,6 @@ # S/390 character devices # -export-objs := sclp.o tape_core.o tape_devmap.o tape_std.o - tub3270-objs := tuball.o tubfs.o tubtty.o \ tubttyaid.o tubttybld.o tubttyscl.o \ tubttyrcl.o tubttysiz.o diff -Nru a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c --- a/drivers/s390/char/sclp_tty.c Sun Feb 9 21:13:29 2003 +++ b/drivers/s390/char/sclp_tty.c Sun Feb 9 21:13:29 2003 @@ -198,7 +198,7 @@ break; case TIOCSCLPSDELIM: /* - * set special character used for seperating upper and + * set special character used for separating upper and * lower case, 0x00 disables this feature */ if (get_user(sclp_ioctls.delim, (unsigned char *) arg)) @@ -206,7 +206,7 @@ break; case TIOCSCLPGDELIM: /* - * get special character used for seperating upper and + * get special character used for separating upper and * lower case, 0x00 disables this feature */ if (put_user(sclp_ioctls.delim, (unsigned char *) arg)) @@ -507,7 +507,7 @@ /* * get a EBCDIC string in upper/lower case, - * find out characters in lower/upper case seperated by a special character, + * find out characters in lower/upper case separated by a special character, * modifiy original string, * returns length of resulting string */ diff -Nru a/drivers/s390/char/sclp_tty.h b/drivers/s390/char/sclp_tty.h --- a/drivers/s390/char/sclp_tty.h Sun Feb 9 21:13:32 2003 +++ b/drivers/s390/char/sclp_tty.h Sun Feb 9 21:13:32 2003 @@ -42,7 +42,7 @@ #define TIOCSCLPSINIT _IO(SCLP_IOCTL_LETTER, 6) /* enable/disable conversion from upper to lower case of input */ #define TIOCSCLPSCASE _IOW(SCLP_IOCTL_LETTER, 7, unsigned char) -/* set special character used for seperating upper and lower case, */ +/* set special character used for separating upper and lower case, */ /* 0x00 disables this feature */ #define TIOCSCLPSDELIM _IOW(SCLP_IOCTL_LETTER, 9, unsigned char) @@ -58,7 +58,7 @@ #define TIOCSCLPGOBUF _IOR(SCLP_IOCTL_LETTER, 15, unsigned short) /* Is conversion from upper to lower case of input enabled ? */ #define TIOCSCLPGCASE _IOR(SCLP_IOCTL_LETTER, 17, unsigned char) -/* get special character used for seperating upper and lower case, */ +/* get special character used for separating upper and lower case, */ /* 0x00 disables this feature */ #define TIOCSCLPGDELIM _IOR(SCLP_IOCTL_LETTER, 19, unsigned char) /* get the number of buffers/pages got from kernel at startup */ diff -Nru a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c --- a/drivers/s390/char/tape_char.c Sun Feb 9 21:13:34 2003 +++ b/drivers/s390/char/tape_char.c Sun Feb 9 21:13:34 2003 @@ -64,7 +64,7 @@ * Terminate write command (we write two TMs and skip backward over last) * This ensures that the tape is always correctly terminated. * When the user writes afterwards a new file, he will overwrite the - * second TM and therefore one TM will remain to seperate the + * second TM and therefore one TM will remain to separate the * two files on the tape... */ static inline void diff -Nru a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile --- a/drivers/s390/cio/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/s390/cio/Makefile Sun Feb 9 21:13:28 2003 @@ -3,15 +3,8 @@ # obj-y += airq.o blacklist.o chsc.o cio.o css.o requestirq.o -export-objs += airq.o css.o cio.o requestirq.o - ccw_device-objs += device.o device_fsm.o device_ops.o ccw_device-objs += device_id.o device_pgid.o device_status.o obj-y += ccw_device.o -export-objs += device.o device_ops.o - obj-$(CONFIG_CCWGROUP) += ccwgroup.o -export-objs += ccwgroup.o - obj-$(CONFIG_QDIO) += qdio.o -export-objs += qdio.o diff -Nru a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile --- a/drivers/s390/net/Makefile Sun Feb 9 21:13:31 2003 +++ b/drivers/s390/net/Makefile Sun Feb 9 21:13:31 2003 @@ -2,8 +2,6 @@ # S/390 network devices # -export-objs := iucv.o fsm.o cu3088.o - ctc-objs := ctcmain.o ctctty.o obj-$(CONFIG_IUCV) += iucv.o fsm.o diff -Nru a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c --- a/drivers/s390/net/lcs.c Sun Feb 9 21:13:29 2003 +++ b/drivers/s390/net/lcs.c Sun Feb 9 21:13:29 2003 @@ -61,7 +61,7 @@ */ #define VERSION_LCS_C "$Revision: 1.42 $" -static const char *version="LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; +static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; /** * Some prototypes. diff -Nru a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile --- a/drivers/sbus/char/Makefile Sun Feb 9 21:13:35 2003 +++ b/drivers/sbus/char/Makefile Sun Feb 9 21:13:35 2003 @@ -7,8 +7,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs := bbc_i2c.o - vfc-objs := vfc_dev.o vfc_i2c.o bbc-objs := bbc_i2c.o bbc_envctrl.o diff -Nru a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c --- a/drivers/sbus/char/aurora.c Sun Feb 9 21:13:29 2003 +++ b/drivers/sbus/char/aurora.c Sun Feb 9 21:13:29 2003 @@ -1046,7 +1046,7 @@ &bp->r[chip]->r[CD180_MSVR]); } - /* Now we must calculate some speed dependant things. */ + /* Now we must calculate some speed dependent things. */ /* Set baud rate for port. */ tmp = (((bp->oscfreq + baud/2) / baud + diff -Nru a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c --- a/drivers/sbus/char/bbc_envctrl.c Sun Feb 9 21:13:31 2003 +++ b/drivers/sbus/char/bbc_envctrl.c Sun Feb 9 21:13:31 2003 @@ -30,7 +30,7 @@ * * The max1617 is capable of being programmed with power-off * temperature values, one low limit and one high limit. These - * can be controlled independantly for the cpu or ambient temperature. + * can be controlled independently for the cpu or ambient temperature. * If a limit is violated, the power is simply shut off. The frequency * with which the max1617 does temperature sampling can be controlled * as well. diff -Nru a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c --- a/drivers/scsi/3w-xxxx.c Sun Feb 9 21:13:36 2003 +++ b/drivers/scsi/3w-xxxx.c Sun Feb 9 21:13:36 2003 @@ -2187,7 +2187,7 @@ return (FAILED); } - tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata; + tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; if (tw_dev == NULL) { printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid device extension.\n"); return (FAILED); @@ -2200,14 +2200,14 @@ for (i=0;isrb[i] == SCpnt) { if (tw_dev->state[i] == TW_S_STARTED) { - printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt); + printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->device->id, SCpnt); tw_dev->state[i] = TW_S_COMPLETED; tw_state_request_finish(tw_dev, i); spin_unlock(&tw_dev->tw_lock); return (SUCCESS); } if (tw_dev->state[i] == TW_S_PENDING) { - printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt); + printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->device->id, SCpnt); if (tw_dev->pending_head == TW_Q_LENGTH-1) { tw_dev->pending_head = TW_Q_START; } else { @@ -2221,7 +2221,7 @@ } if (tw_dev->state[i] == TW_S_POSTED) { /* If the command has already been posted, we have to reset the card */ - printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out, resetting card.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt); + printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out, resetting card.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->device->id, SCpnt); /* We have to let AEN requests through before the reset */ spin_unlock(&tw_dev->tw_lock); spin_unlock_irq(tw_dev->host->host_lock); @@ -2254,7 +2254,7 @@ return (FAILED); } - tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata; + tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; if (tw_dev == NULL) { printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid device extension.\n"); return (FAILED); @@ -2356,7 +2356,7 @@ int request_id = 0; int error = 0; unsigned long flags = 0; - TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata; + TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; if (tw_dev == NULL) { printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n"); @@ -2369,7 +2369,7 @@ dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n"); /* Skip scsi command if it isn't for us */ - if ((tw_dev->is_unit_present[SCpnt->target] == FALSE) || (SCpnt->lun != 0)) { + if ((tw_dev->is_unit_present[SCpnt->device->id] == FALSE) || (SCpnt->device->lun != 0)) { SCpnt->result = (DID_BAD_TARGET << 16); done(SCpnt); spin_unlock_irqrestore(&tw_dev->tw_lock, flags); @@ -2618,7 +2618,7 @@ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; memset(param, 0, sizeof(TW_Sector)); - param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->target; + param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->device->id; param->parameter_id = 7; /* unit flags */ param->parameter_size_bytes = 1; param_value = tw_dev->alignment_physical_address[request_id]; @@ -2697,7 +2697,7 @@ command_packet->byte0.sgl_offset = 2; command_packet->size = 4; command_packet->request_id = request_id; - command_packet->byte3.unit = tw_dev->srb[request_id]->target; + command_packet->byte3.unit = tw_dev->srb[request_id]->device->id; command_packet->byte3.host_id = 0; command_packet->status = 0; command_packet->flags = 0; @@ -2711,7 +2711,7 @@ param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; memset(param, 0, sizeof(TW_Sector)); param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + - tw_dev->srb[request_id]->target; + tw_dev->srb[request_id]->device->id; param->parameter_id = 4; /* unitcapacity parameter */ param->parameter_size_bytes = 4; param_value = tw_dev->alignment_physical_address[request_id]; @@ -2817,7 +2817,7 @@ command_packet->byte0.sgl_offset = 3; command_packet->size = 3; command_packet->request_id = request_id; - command_packet->byte3.unit = srb->target; + command_packet->byte3.unit = srb->device->id; command_packet->byte3.host_id = 0; command_packet->status = 0; command_packet->flags = 0; @@ -2924,7 +2924,7 @@ command_packet->byte0.sgl_offset = 0; command_packet->size = 2; command_packet->request_id = request_id; - command_packet->byte3.unit = tw_dev->srb[request_id]->target; + command_packet->byte3.unit = tw_dev->srb[request_id]->device->id; command_packet->byte3.host_id = 0; command_packet->status = 0; command_packet->flags = 0; diff -Nru a/drivers/scsi/53c7,8xx.c b/drivers/scsi/53c7,8xx.c --- a/drivers/scsi/53c7,8xx.c Sun Feb 9 21:13:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,6432 +0,0 @@ -/* - * PERM_OPTIONS are driver options which will be enabled for all NCR boards - * in the system at driver initialization time. - * - * Don't THINK about touching these in PERM_OPTIONS : - * OPTION_IO_MAPPED - * Memory mapped IO does not work under i86 Linux. - * - * OPTION_DEBUG_TEST1 - * Test 1 does bus mastering and interrupt tests, which will help weed - * out brain damaged main boards. - * - * These are development kernel changes. Code for them included in this - * driver release may or may not work. If you turn them on, you should be - * running the latest copy of the development sources from - * - * ftp://tsx-11.mit.edu/pub/linux/ALPHA/scsi/53c7,8xx - * - * and be subscribed to the ncr53c810@colorado.edu mailing list. To - * subscribe, send mail to majordomo@colorado.edu with - * - * subscribe ncr53c810 - * - * in the text. - * - * - * OPTION_NO_ASYNC - * Don't negotiate for asynchronous transfers on the first command - * when OPTION_ALWAYS_SYNCHRONOUS is set. Useful for dain bramaged - * devices which do something bad rather than sending a MESSAGE - * REJECT back to us like they should if they can't cope. - * - * OPTION_SYNCHRONOUS - * Enable support for synchronous transfers. Target negotiated - * synchronous transfers will be responded to. To initiate - * a synchronous transfer request, call - * - * request_synchronous (hostno, target) - * - * from within KGDB. - * - * OPTION_ALWAYS_SYNCHRONOUS - * Negotiate for synchronous transfers with every target after - * driver initialization or a SCSI bus reset. This is a bit dangerous, - * since there are some dain bramaged SCSI devices which will accept - * SDTR messages but keep talking asynchronously. - * - * OPTION_DISCONNECT - * Enable support for disconnect/reconnect. To change the - * default setting on a given host adapter, call - * - * request_disconnect (hostno, allow) - * - * where allow is non-zero to allow, 0 to disallow. - * - * If you really want to run 10MHz FAST SCSI-II transfers, you should - * know that the NCR driver currently ignores parity information. Most - * systems do 5MHz SCSI fine. I've seen a lot that have problems faster - * than 8MHz. To play it safe, we only request 5MHz transfers. - * - * If you'd rather get 10MHz transfers, edit sdtr_message and change - * the fourth byte from 50 to 25. - */ - -#error Please convert me to Documentation/DMA-mapping.txt - -#include - -#ifdef CONFIG_SCSI_NCR53C7xx_sync -#ifdef CONFIG_SCSI_NCR53C7xx_DISCONNECT -#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1|OPTION_DISCONNECT|\ - OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS) -#else -#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1|\ - OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS) -#endif -#else -#ifdef CONFIG_SCSI_NCR53C7xx_DISCONNECT -#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1|OPTION_DISCONNECT|\ - OPTION_SYNCHRONOUS) -#else -#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1|OPTION_SYNCHRONOUS) -#endif -#endif - -/* - * Sponsored by - * iX Multiuser Multitasking Magazine - * Hannover, Germany - * hm@ix.de - * - * Copyright 1993, 1994, 1995 Drew Eckhardt - * Visionary Computing - * (Unix and Linux consulting and custom programming) - * drew@PoohSticks.ORG - * +1 (303) 786-7975 - * - * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation. - * - * For more information, please consult - * - * NCR53C810 - * SCSI I/O Processor - * Programmer's Guide - * - * NCR 53C810 - * PCI-SCSI I/O Processor - * Data Manual - * - * NCR 53C810/53C820 - * PCI-SCSI I/O Processor Design In Guide - * - * For literature on Symbios Logic Inc. formerly NCR, SCSI, - * and Communication products please call (800) 334-5454 or - * (719) 536-3300. - * - * PCI BIOS Specification Revision - * PCI Local Bus Specification - * PCI System Design Guide - * - * PCI Special Interest Group - * M/S HF3-15A - * 5200 N.E. Elam Young Parkway - * Hillsboro, Oregon 97124-6497 - * +1 (503) 696-2000 - * +1 (800) 433-5177 - */ - -/* - * Design issues : - * The cumulative latency needed to propagate a read/write request - * through the file system, buffer cache, driver stacks, SCSI host, and - * SCSI device is ultimately the limiting factor in throughput once we - * have a sufficiently fast host adapter. - * - * So, to maximize performance we want to keep the ratio of latency to data - * transfer time to a minimum by - * 1. Minimizing the total number of commands sent (typical command latency - * including drive and bus mastering host overhead is as high as 4.5ms) - * to transfer a given amount of data. - * - * This is accomplished by placing no arbitrary limit on the number - * of scatter/gather buffers supported, since we can transfer 1K - * per scatter/gather buffer without Eric's cluster patches, - * 4K with. - * - * 2. Minimizing the number of fatal interrupts serviced, since - * fatal interrupts halt the SCSI I/O processor. Basically, - * this means offloading the practical maximum amount of processing - * to the SCSI chip. - * - * On the NCR53c810/820/720, this is accomplished by using - * interrupt-on-the-fly signals when commands complete, - * and only handling fatal errors and SDTR / WDTR messages - * in the host code. - * - * On the NCR53c710, interrupts are generated as on the NCR53c8x0, - * only the lack of an interrupt-on-the-fly facility complicates - * things. Also, SCSI ID registers and commands are - * bit fielded rather than binary encoded. - * - * On the NCR53c700 and NCR53c700-66, operations that are done via - * indirect, table mode on the more advanced chips must be - * replaced by calls through a jump table which - * acts as a surrogate for the DSA. Unfortunately, this - * will mean that we must service an interrupt for each - * disconnect/reconnect. - * - * 3. Eliminating latency by pipelining operations at the different levels. - * - * This driver allows a configurable number of commands to be enqueued - * for each target/lun combination (experimentally, I have discovered - * that two seems to work best) and will ultimately allow for - * SCSI-II tagged queuing. - * - * - * Architecture : - * This driver is built around a Linux queue of commands waiting to - * be executed, and a shared Linux/NCR array of commands to start. Commands - * are transferred to the array by the run_process_issue_queue() function - * which is called whenever a command completes. - * - * As commands are completed, the interrupt routine is triggered, - * looks for commands in the linked list of completed commands with - * valid status, removes these commands from a list of running commands, - * calls the done routine, and flags their target/luns as not busy. - * - * Due to limitations in the intelligence of the NCR chips, certain - * concessions are made. In many cases, it is easier to dynamically - * generate/fix-up code rather than calculate on the NCR at run time. - * So, code is generated or fixed up for - * - * - Handling data transfers, using a variable number of MOVE instructions - * interspersed with CALL MSG_IN, WHEN MSGIN instructions. - * - * The DATAIN and DATAOUT routines are separate, so that an incorrect - * direction can be trapped, and space isn't wasted. - * - * It may turn out that we're better off using some sort - * of table indirect instruction in a loop with a variable - * sized table on the NCR53c710 and newer chips. - * - * - Checking for reselection (NCR53c710 and better) - * - * - Handling the details of SCSI context switches (NCR53c710 and better), - * such as reprogramming appropriate synchronous parameters, - * removing the dsa structure from the NCR's queue of outstanding - * commands, etc. - * - */ - -/* - * Accommodate differences between stock 1.2.x and 1.3.x asm-i386/types.h - * so lusers can drop in 53c7,8xx.* and get something which compiles - * without warnings. - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "scsi.h" -#include "hosts.h" -#include "53c7,8xx.h" -#include -#include - -static int check_address (unsigned long addr, int size); -static void dump_events (struct Scsi_Host *host, int count); -static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host, - int free, int issue); -static void hard_reset (struct Scsi_Host *host); -static void ncr_scsi_reset (struct Scsi_Host *host); -static void print_lots (struct Scsi_Host *host); -static void set_synchronous (struct Scsi_Host *host, int target, int sxfer, - int scntl3, int now_connected); -static int datapath_residual (struct Scsi_Host *host); -static const char * sbcl_to_phase (int sbcl); -static void print_progress (Scsi_Cmnd *cmd); -static void print_queues (struct Scsi_Host *host); -static void process_issue_queue (unsigned long flags); -static int shutdown (struct Scsi_Host *host); -static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result); -static int disable (struct Scsi_Host *host); -static int NCR53c8xx_run_tests (struct Scsi_Host *host); -static int NCR53c8xx_script_len; -static int NCR53c8xx_dsa_len; -static void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); -static void do_NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); -static int ncr_halt (struct Scsi_Host *host); -static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd - *cmd); -static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd); -static void print_dsa (struct Scsi_Host *host, u32 *dsa, - const char *prefix); -static int print_insn (struct Scsi_Host *host, const u32 *insn, - const char *prefix, int kernel); - -static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd); -static void NCR53c8x0_init_fixup (struct Scsi_Host *host); -static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct - NCR53c7x0_cmd *cmd); -static void NCR53c8x0_soft_reset (struct Scsi_Host *host); - -/* INSMOD variables */ -static long long perm_options = PERM_OPTIONS; -/* 14 = .5s; 15 is max; decreasing divides by two. */ -static int selection_timeout = 14; -/* Size of event list (per host adapter) */ -static int track_events = 0; - -static struct Scsi_Host *first_host = NULL; /* Head of list of NCR boards */ -static Scsi_Host_Template *the_template = NULL; - -/* - * KNOWN BUGS : - * - There is some sort of conflict when the PPP driver is compiled with - * support for 16 channels? - * - * - On systems which predate the 1.3.x initialization order change, - * the NCR driver will cause Cannot get free page messages to appear. - * These are harmless, but I don't know of an easy way to avoid them. - * - * - With OPTION_DISCONNECT, on two systems under unknown circumstances, - * we get a PHASE MISMATCH with DSA set to zero (suggests that we - * are occurring somewhere in the reselection code) where - * DSP=some value DCMD|DBC=same value. - * - * Closer inspection suggests that we may be trying to execute - * some portion of the DSA? - * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO) - * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO) - * scsi0 : no current command : unexpected phase MSGIN. - * DSP=0x1c46cc, DCMD|DBC=0x1c46ac, DSA=0x0 - * DSPS=0x0, TEMP=0x1c3e70, DMODE=0x80 - * scsi0 : DSP-> - * 001c46cc : 0x001c46cc 0x00000000 - * 001c46d4 : 0x001c5ea0 0x000011f8 - * - * Changed the print code in the phase_mismatch handler so - * that we call print_lots to try to diagnose this. - * - */ - -/* - * Possible future direction of architecture for max performance : - * - * We're using a single start array for the NCR chip. This is - * sub-optimal, because we cannot add a command which would conflict with - * an executing command to this start queue, and therefore must insert the - * next command for a given I/T/L combination after the first has completed; - * incurring our interrupt latency between SCSI commands. - * - * To allow further pipelining of the NCR and host CPU operation, we want - * to set things up so that immediately on termination of a command destined - * for a given LUN, we get that LUN busy again. - * - * To do this, we need to add a 32 bit pointer to which is jumped to - * on completion of a command. If no new command is available, this - * would point to the usual DSA issue queue select routine. - * - * If one were, it would point to a per-NCR53c7x0_cmd select routine - * which starts execution immediately, inserting the command at the head - * of the start queue if the NCR chip is selected or reselected. - * - * We would change so that we keep a list of outstanding commands - * for each unit, rather than a single running_list. We'd insert - * a new command into the right running list; if the NCR didn't - * have something running for that yet, we'd put it in the - * start queue as well. Some magic needs to happen to handle the - * race condition between the first command terminating before the - * new one is written. - * - * Potential for profiling : - * Call do_gettimeofday(struct timeval *tv) to get 800ns resolution. - */ - - -/* - * TODO : - * 1. To support WIDE transfers, not much needs to happen. We - * should do CHMOVE instructions instead of MOVEs when - * we have scatter/gather segments of uneven length. When - * we do this, we need to handle the case where we disconnect - * between segments. - * - * 2. Currently, when Icky things happen we do a FATAL(). Instead, - * we want to do an integrity check on the parts of the NCR hostdata - * structure which were initialized at boot time; FATAL() if that - * fails, and otherwise try to recover. Keep track of how many - * times this has happened within a single SCSI command; if it - * gets excessive, then FATAL(). - * - * 3. Parity checking is currently disabled, and a few things should - * happen here now that we support synchronous SCSI transfers : - * 1. On soft-reset, we should set the EPC (Enable Parity Checking) - * and AAP (Assert SATN/ on parity error) bits in SCNTL0. - * - * 2. We should enable the parity interrupt in the SIEN0 register. - * - * 3. intr_phase_mismatch() needs to believe that message out is - * always an "acceptable" phase to have a mismatch in. If - * the old phase was MSG_IN, we should send a MESSAGE PARITY - * error. If the old phase was something else, we should send - * a INITIATOR_DETECTED_ERROR message. Note that this could - * cause a RESTORE POINTERS message; so we should handle that - * correctly first. Instead, we should probably do an - * initiator_abort. - * - * 4. MPEE bit of CTEST4 should be set so we get interrupted if - * we detect an error. - * - * - * 5. The initial code has been tested on the NCR53c810. I don't - * have access to NCR53c700, 700-66 (Forex boards), NCR53c710 - * (NCR Pentium systems), NCR53c720, NCR53c820, or NCR53c825 boards to - * finish development on those platforms. - * - * NCR53c820/825/720 - need to add wide transfer support, including WDTR - * negotiation, programming of wide transfer capabilities - * on reselection and table indirect selection. - * - * NCR53c710 - need to add fatal interrupt or GEN code for - * command completion signaling. Need to modify all - * SDID, SCID, etc. registers, and table indirect select code - * since these use bit fielded (ie 1<NOP_insn) ? - /* - * If the IF TRUE bit is set, it's a JUMP instruction. The - * operand is a bus pointer to the dsa_begin routine for this DSA. The - * dsa field of the NCR53c7x0_cmd structure starts with the - * DSA code template. By converting to a virtual address, - * subtracting the code template size, and offset of the - * dsa field, we end up with a pointer to the start of the - * structure (alternatively, we could use the - * dsa_cmnd field, an anachronism from when we weren't - * sure what the relationship between the NCR structures - * and host structures were going to be. - */ - (struct NCR53c7x0_cmd *) ((char *) bus_to_virt (le32_to_cpu(issue[1])) - - (hostdata->E_dsa_code_begin - hostdata->E_dsa_code_template) - - offsetof(struct NCR53c7x0_cmd, dsa)) - /* If the IF TRUE bit is not set, it's a NOP */ - : NULL; -} - - -/* - * Function : static internal_setup(int board, int chip, char *str, int *ints) - * - * Purpose : LILO command line initialization of the overrides array, - * - * Inputs : board - currently, unsupported. chip - 700, 70066, 710, 720 - * 810, 815, 820, 825, although currently only the NCR53c810 is - * supported. - * - */ - -static void -internal_setup(int board, int chip, char *str, int *ints) { - unsigned char pci; /* Specifies a PCI override, with bus, device, - function */ - - pci = (str && !strcmp (str, "pci")) ? 1 : 0; - -/* - * Override syntaxes are as follows : - * ncr53c700,ncr53c700-66,ncr53c710,ncr53c720=mem,io,irq,dma - * ncr53c810,ncr53c820,ncr53c825=mem,io,irq or pci,bus,device,function - */ - - if (commandline_current < OVERRIDE_LIMIT) { - overrides[commandline_current].pci = pci ? 1 : 0; - if (!pci) { - overrides[commandline_current].data.normal.base = ints[1]; - overrides[commandline_current].data.normal.io_port = ints[2]; - overrides[commandline_current].data.normal.irq = ints[3]; - overrides[commandline_current].data.normal.dma = (ints[0] >= 4) ? - ints[4] : DMA_NONE; - /* FIXME: options is now a long long */ - overrides[commandline_current].options = (ints[0] >= 5) ? - ints[5] : 0; - } else { - overrides[commandline_current].data.pci.bus = ints[1]; - overrides[commandline_current].data.pci.device = ints[2]; - overrides[commandline_current].data.pci.function = ints[3]; - /* FIXME: options is now a long long */ - overrides[commandline_current].options = (ints[0] >= 4) ? - ints[4] : 0; - } - overrides[commandline_current].board = board; - overrides[commandline_current].chip = chip; - ++commandline_current; - ++no_overrides; - } else { - printk ("53c7,7x0.c:internal_setup() : too many overrides\n"); - } -} - -/* - * XXX - we might want to implement a single override function - * with a chip type field, revamp the command line configuration, - * etc. - */ - -#define setup_wrapper(x) \ -void ncr53c##x##_setup (char *str, int *ints) { \ - internal_setup (BOARD_GENERIC, x, str, ints); \ -} - -setup_wrapper(700) -setup_wrapper(70066) -setup_wrapper(710) -setup_wrapper(720) -setup_wrapper(810) -setup_wrapper(815) -setup_wrapper(820) -setup_wrapper(825) - -/* - * FIXME: we should junk these, in favor of synchronous_want and - * wide_want in the NCR53c7x0_hostdata structure. - */ - -/* Template for "preferred" synchronous transfer parameters. */ - -static const unsigned char sdtr_message[] = { -#ifdef CONFIG_SCSI_NCR53C7xx_FAST - EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 25 /* *4ns */, 8 /* off */ -#else - EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 50 /* *4ns */, 8 /* off */ -#endif -}; - -/* Template to request asynchronous transfers */ - -static const unsigned char async_message[] = { - EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 0, 0 /* asynchronous */ -}; - -/* Template for "preferred" WIDE transfer parameters */ - -static const unsigned char wdtr_message[] = { - EXTENDED_MESSAGE, 2 /* length */, EXTENDED_WDTR, 1 /* 2^1 bytes */ -}; - -/* - * Function : struct Scsi_Host *find_host (int host) - * - * Purpose : KGDB support function which translates a host number - * to a host structure. - * - * Inputs : host - number of SCSI host - * - * Returns : NULL on failure, pointer to host structure on success. - */ - -#if 0 -static struct Scsi_Host * -find_host (int host) { - struct Scsi_Host *h; - for (h = first_host; h && h->host_no != host; h = h->next); - if (!h) { - printk (KERN_ALERT "scsi%d not found\n", host); - return NULL; - } else if (h->hostt != the_template) { - printk (KERN_ALERT "scsi%d is not a NCR board\n", host); - return NULL; - } - return h; -} - -/* - * Function : request_synchronous (int host, int target) - * - * Purpose : KGDB interface which will allow us to negotiate for - * synchronous transfers. This ill be replaced with a more - * integrated function; perhaps a new entry in the scsi_host - * structure, accessible via an ioctl() or perhaps /proc/scsi. - * - * Inputs : host - number of SCSI host; target - number of target. - * - * Returns : 0 when negotiation has been setup for next SCSI command, - * -1 on failure. - */ - -static int -request_synchronous (int host, int target) { - struct Scsi_Host *h; - struct NCR53c7x0_hostdata *hostdata; - unsigned long flags; - if (target < 0) { - printk (KERN_ALERT "target %d is bogus\n", target); - return -1; - } - if (!(h = find_host (host))) - return -1; - else if (h->this_id == target) { - printk (KERN_ALERT "target %d is host ID\n", target); - return -1; - } - else if (target > h->max_id) { - printk (KERN_ALERT "target %d exceeds maximum of %d\n", target, - h->max_id); - return -1; - } - hostdata = (struct NCR53c7x0_hostdata *)h->hostdata; - - save_flags(flags); - cli(); - if (hostdata->initiate_sdtr & (1 << target)) { - restore_flags(flags); - printk (KERN_ALERT "target %d already doing SDTR\n", target); - return -1; - } - hostdata->initiate_sdtr |= (1 << target); - restore_flags(flags); - return 0; -} - -/* - * Function : request_disconnect (int host, int on_or_off) - * - * Purpose : KGDB support function, tells us to allow or disallow - * disconnections. - * - * Inputs : host - number of SCSI host; on_or_off - non-zero to allow, - * zero to disallow. - * - * Returns : 0 on success, * -1 on failure. - */ - -static int -request_disconnect (int host, int on_or_off) { - struct Scsi_Host *h; - struct NCR53c7x0_hostdata *hostdata; - if (!(h = find_host (host))) - return -1; - hostdata = (struct NCR53c7x0_hostdata *) h->hostdata; - if (on_or_off) - hostdata->options |= OPTION_DISCONNECT; - else - hostdata->options &= ~OPTION_DISCONNECT; - return 0; -} -#endif - -/* - * Function : static void NCR53c7x0_driver_init (struct Scsi_Host *host) - * - * Purpose : Initialize internal structures, as required on startup, or - * after a SCSI bus reset. - * - * Inputs : host - pointer to this host adapter's structure - */ - -static void -NCR53c7x0_driver_init (struct Scsi_Host *host) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - int i, j; - u32 *curr; - for (i = 0; i < 16; ++i) { - hostdata->request_sense[i] = 0; - for (j = 0; j < 8; ++j) - hostdata->busy[i][j] = 0; - set_synchronous (host, i, /* sxfer */ 0, hostdata->saved_scntl3, 0); - } - hostdata->issue_queue = NULL; - hostdata->running_list = hostdata->finished_queue = - hostdata->curr = NULL; - for (i = 0, curr = (u32 *) hostdata->schedule; - i < host->can_queue; ++i, curr += 2) { - curr[0] = hostdata->NOP_insn; - curr[1] = le32_to_cpu(0xdeadbeef); - } - curr[0] = le32_to_cpu(((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) | DBC_TCI_TRUE); - curr[1] = (u32) le32_to_cpu(virt_to_bus (hostdata->script) + - hostdata->E_wait_reselect); - hostdata->reconnect_dsa_head = 0; - hostdata->addr_reconnect_dsa_head = (u32) - le32_to_cpu(virt_to_bus((void *) &(hostdata->reconnect_dsa_head))); - hostdata->expecting_iid = 0; - hostdata->expecting_sto = 0; - if (hostdata->options & OPTION_ALWAYS_SYNCHRONOUS) - hostdata->initiate_sdtr = le32_to_cpu(0xffff); - else - hostdata->initiate_sdtr = 0; - hostdata->talked_to = 0; - hostdata->idle = 1; -} - -/* - * Function : static int ccf_to_clock (int ccf) - * - * Purpose : Return the largest SCSI clock allowable for a given - * clock conversion factor, allowing us to do synchronous periods - * when we don't know what the SCSI clock is by taking at least - * as long as the device says we can. - * - * Inputs : ccf - * - * Returns : clock on success, -1 on failure. - */ - -static int -ccf_to_clock (int ccf) { - switch (ccf) { - case 1: return 25000000; /* Divide by 1.0 */ - case 2: return 37500000; /* Divide by 1.5 */ - case 3: return 50000000; /* Divide by 2.0 */ - case 0: /* Divide by 3.0 */ - case 4: return 66000000; - default: return -1; - } -} - -/* - * Function : static int clock_to_ccf (int clock) - * - * Purpose : Return the clock conversion factor for a given SCSI clock. - * - * Inputs : clock - SCSI clock expressed in Hz. - * - * Returns : ccf on success, -1 on failure. - */ - -static int -clock_to_ccf (int clock) { - if (clock < 16666666) - return -1; - if (clock < 25000000) - return 1; /* Divide by 1.0 */ - else if (clock < 37500000) - return 2; /* Divide by 1.5 */ - else if (clock < 50000000) - return 3; /* Divide by 2.0 */ - else if (clock < 66000000) - return 4; /* Divide by 3.0 */ - else - return -1; -} - -/* - * Function : static int NCR53c7x0_init (struct Scsi_Host *host) - * - * Purpose : initialize the internal structures for a given SCSI host - * - * Inputs : host - pointer to this host adapter's structure - * - * Preconditions : when this function is called, the chip_type - * field of the hostdata structure MUST have been set. - * - * Returns : 0 on success, -1 on failure. - */ - -static int -NCR53c7x0_init (struct Scsi_Host *host) { - NCR53c7x0_local_declare(); - int i, ccf, expected_ccf; - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - struct Scsi_Host *search; - /* - * There are some things which we need to know about in order to provide - * a semblance of support. Print 'em if they aren't what we expect, - * otherwise don't add to the noise. - * - * -1 means we don't know what to expect. - */ - int expected_id = -1; - int expected_clock = -1; - int uninitialized = 0; - /* - * FIXME : this is only on Intel boxes. On other platforms, this - * will differ. - */ - int expected_mapping = OPTION_IO_MAPPED; - - NCR53c7x0_local_setup(host); - - switch (hostdata->chip) { - case 820: - case 825: -#ifdef notyet - host->max_id = 15; -#endif - /* Fall through */ - case 810: - case 815: - hostdata->dstat_sir_intr = NCR53c8x0_dstat_sir_intr; - hostdata->init_save_regs = NULL; - hostdata->dsa_fixup = NCR53c8xx_dsa_fixup; - hostdata->init_fixup = NCR53c8x0_init_fixup; - hostdata->soft_reset = NCR53c8x0_soft_reset; - hostdata->run_tests = NCR53c8xx_run_tests; -/* Is the SCSI clock ever anything else on these chips? */ - expected_clock = hostdata->scsi_clock = 40000000; - expected_id = 7; - break; - default: - printk ("scsi%d : chip type of %d is not supported yet, detaching.\n", - host->host_no, hostdata->chip); - scsi_unregister (host); - return -1; - } - - /* Assign constants accessed by NCR */ - hostdata->NCR53c7xx_zero = 0; - hostdata->NCR53c7xx_msg_reject = le32_to_cpu(MESSAGE_REJECT); - hostdata->NCR53c7xx_msg_abort = le32_to_cpu(ABORT); - hostdata->NCR53c7xx_msg_nop = le32_to_cpu(NOP); - hostdata->NOP_insn = le32_to_cpu((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24); - - if (expected_mapping == -1 || - (hostdata->options & (OPTION_MEMORY_MAPPED)) != - (expected_mapping & OPTION_MEMORY_MAPPED)) - printk ("scsi%d : using %s mapped access\n", host->host_no, - (hostdata->options & OPTION_MEMORY_MAPPED) ? "memory" : - "io"); - - hostdata->dmode = (hostdata->chip == 700 || hostdata->chip == 70066) ? - DMODE_REG_00 : DMODE_REG_10; - hostdata->istat = ((hostdata->chip / 100) == 8) ? - ISTAT_REG_800 : ISTAT_REG_700; - -/* Only the ISTAT register is readable when the NCR is running, so make - sure it's halted. */ - ncr_halt(host); - -/* - * XXX - the NCR53c700 uses bitfielded registers for SCID, SDID, etc, - * as does the 710 with one bit per SCSI ID. Conversely, the NCR - * uses a normal, 3 bit binary representation of these values. - * - * Get the rest of the NCR documentation, and FIND OUT where the change - * was. - */ -#if 0 - tmp = hostdata->this_id_mask = NCR53c7x0_read8(SCID_REG); - for (host->this_id = 0; tmp != 1; tmp >>=1, ++host->this_id); -#else - host->this_id = NCR53c7x0_read8(SCID_REG) & 15; - if (host->this_id == 0) - host->this_id = 7; /* sanitize hostid---0 doesn't make sense */ - hostdata->this_id_mask = 1 << host->this_id; -#endif - -/* - * Note : we should never encounter a board setup for ID0. So, - * if we see ID0, assume that it was uninitialized and set it - * to the industry standard 7. - */ - if (!host->this_id) { - printk("scsi%d : initiator ID was %d, changing to 7\n", - host->host_no, host->this_id); - host->this_id = 7; - hostdata->this_id_mask = 1 << 7; - uninitialized = 1; - }; - - if (expected_id == -1 || host->this_id != expected_id) - printk("scsi%d : using initiator ID %d\n", host->host_no, - host->this_id); - - /* - * Save important registers to allow a soft reset. - */ - - if ((hostdata->chip / 100) == 8) { - /* - * CTEST4 controls burst mode disable. - */ - hostdata->saved_ctest4 = NCR53c7x0_read8(CTEST4_REG_800) & - CTEST4_800_SAVE; - } else { - /* - * CTEST7 controls cache snooping, burst mode, and support for - * external differential drivers. - */ - hostdata->saved_ctest7 = NCR53c7x0_read8(CTEST7_REG) & CTEST7_SAVE; - } - - /* - * On NCR53c700 series chips, DCNTL controls the SCSI clock divisor, - * on 800 series chips, it allows for a totem-pole IRQ driver. - */ - - hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG); - - /* - * DCNTL_800_IRQM controls weather we are using an open drain - * driver (reset) or totem pole driver (set). In all cases, - * it's level active. I suppose this is an issue when we're trying to - * wire-or the same PCI INTx line? - */ - if ((hostdata->chip / 100) == 8) - hostdata->saved_dcntl &= ~DCNTL_800_IRQM; - - /* - * DMODE controls DMA burst length, and on 700 series chips, - * 286 mode and bus width - */ - hostdata->saved_dmode = NCR53c7x0_read8(hostdata->dmode); - - /* - * Now that burst length and enabled/disabled status is known, - * clue the user in on it. - */ - - if ((hostdata->chip / 100) == 8) { - if (hostdata->saved_ctest4 & CTEST4_800_BDIS) { - printk ("scsi%d : burst mode disabled\n", host->host_no); - } else { - switch (hostdata->saved_dmode & DMODE_BL_MASK) { - case DMODE_BL_2: i = 2; break; - case DMODE_BL_4: i = 4; break; - case DMODE_BL_8: i = 8; break; - case DMODE_BL_16: i = 16; break; - default: i = 0; - } - printk ("scsi%d : burst length %d\n", host->host_no, i); - } - } - - /* - * On NCR53c810 and NCR53c820 chips, SCNTL3 contails the synchronous - * and normal clock conversion factors. - */ - if (hostdata->chip / 100 == 8) { - expected_ccf = clock_to_ccf (expected_clock); - hostdata->saved_scntl3 = NCR53c7x0_read8(SCNTL3_REG_800); - ccf = hostdata->saved_scntl3 & SCNTL3_800_CCF_MASK; - if (expected_ccf != -1 && ccf != expected_ccf && !ccf) { - hostdata->saved_scntl3 = (hostdata->saved_scntl3 & - ~SCNTL3_800_CCF_MASK) | expected_ccf; - if (!uninitialized) { - printk ("scsi%d : reset ccf to %d from %d\n", - host->host_no, expected_ccf, ccf); - uninitialized = 1; - } - } - } else - ccf = 0; - - /* - * If we don't have a SCSI clock programmed, pick one on the upper - * bound of that allowed by NCR so that our transfers err on the - * slow side, since transfer period must be >= the agreed - * upon period. - */ - - if ((!hostdata->scsi_clock) && (hostdata->scsi_clock = ccf_to_clock (ccf)) - == -1) { - printk ("scsi%d : clock conversion factor %d unknown.\n" - " synchronous transfers disabled\n", - host->host_no, ccf); - hostdata->options &= ~OPTION_SYNCHRONOUS; - hostdata->scsi_clock = 0; - } - - if (expected_clock == -1 || hostdata->scsi_clock != expected_clock) - printk ("scsi%d : using %dMHz SCSI clock\n", host->host_no, - hostdata->scsi_clock / 1000000); - - for (i = 0; i < 16; ++i) - hostdata->cmd_allocated[i] = 0; - - if (hostdata->init_save_regs) - hostdata->init_save_regs (host); - if (hostdata->init_fixup) - hostdata->init_fixup (host); - - if (!the_template) { - the_template = host->hostt; - first_host = host; - } - - /* - * Linux SCSI drivers have always been plagued with initialization - * problems - some didn't work with the BIOS disabled since they expected - * initialization from it, some didn't work when the networking code - * was enabled and registers got scrambled, etc. - * - * To avoid problems like this, in the future, we will do a soft - * reset on the SCSI chip, taking it back to a sane state. - */ - - hostdata->soft_reset (host); - -#if 1 - hostdata->debug_count_limit = -1; -#else - hostdata->debug_count_limit = 1; -#endif - hostdata->intrs = -1; - hostdata->resets = -1; - memcpy ((void *) hostdata->synchronous_want, (void *) sdtr_message, - sizeof (hostdata->synchronous_want)); - - NCR53c7x0_driver_init (host); - - /* - * Set up an interrupt handler if we aren't already sharing an IRQ - * with another board. - */ - - for (search = first_host; search && !(search->hostt == the_template && - search->irq == host->irq && search != host); search=search->next); - - if (!search) { -#ifdef __powerpc__ - if (request_irq(host->irq, do_NCR53c7x0_intr, SA_SHIRQ, "53c7,8xx", host)) -#else - if (request_irq(host->irq, do_NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx", host)) -#endif - { - - - printk("scsi%d : IRQ%d not free, detaching\n" - " You have either a configuration problem, or a\n" - " broken BIOS. You may wish to manually assign\n" - " an interrupt to the NCR board rather than using\n" - " an automatic setting.\n", - host->host_no, host->irq); - scsi_unregister (host); - return -1; - } - } else { - printk("scsi%d : using interrupt handler previously installed for scsi%d\n", - host->host_no, search->host_no); - } - - - if ((hostdata->run_tests && hostdata->run_tests(host) == -1) || - (hostdata->options & OPTION_DEBUG_TESTS_ONLY)) { - /* XXX Should disable interrupts, etc. here */ - scsi_unregister (host); - return -1; - } else { - if (host->io_port) { - host->n_io_port = 128; - request_region (host->io_port, host->n_io_port, "ncr53c7,8xx"); - } - } - - if (NCR53c7x0_read8 (SBCL_REG) & SBCL_BSY) { - printk ("scsi%d : bus wedge, doing SCSI reset\n", host->host_no); - hard_reset (host); - } - return 0; -} - -/* - * Function : static int normal_init(Scsi_Host_Template *tpnt, int board, - * int chip, u32 base, int io_port, int irq, int dma, int pcivalid, - * struct pci_dev *pci_dev, long long options); - * - * Purpose : initializes a NCR53c7,8x0 based on base addresses, - * IRQ, and DMA channel. - * - * Useful where a new NCR chip is backwards compatible with - * a supported chip, but the DEVICE ID has changed so it - * doesn't show up when the autoprobe does a pci_find_device. - * - * Inputs : tpnt - Template for this SCSI adapter, board - board level - * product, chip - 810, 820, or 825, bus - PCI bus, device_fn - - * device and function encoding as used by PCI BIOS calls. - * - * Returns : 0 on success, -1 on failure. - * - */ - -static int __init -normal_init (Scsi_Host_Template *tpnt, int board, int chip, - u32 base, int io_port, int irq, int dma, int pci_valid, - struct pci_dev *pci_dev, long long options) -{ - struct Scsi_Host *instance; - struct NCR53c7x0_hostdata *hostdata; - char chip_str[80]; - int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0, - schedule_size = 0, ok = 0; - void *tmp; - - options |= perm_options; - - switch (chip) { - case 825: - case 820: - case 815: - case 810: - schedule_size = (tpnt->can_queue + 1) * 8 /* JUMP instruction size */; - script_len = NCR53c8xx_script_len; - dsa_len = NCR53c8xx_dsa_len; - options |= OPTION_INTFLY; - sprintf (chip_str, "NCR53c%d", chip); - break; - default: - printk("scsi-ncr53c7,8xx : unsupported SCSI chip %d\n", chip); - return -1; - } - - printk("scsi-ncr53c7,8xx : %s at memory 0x%x, io 0x%x, irq %d", - chip_str, (unsigned) base, io_port, irq); - if (dma == DMA_NONE) - printk("\n"); - else - printk(", dma %d\n", dma); - - if ((chip / 100 == 8) && !pci_valid) - printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n" - " PCI override instead.\n" - " Syntax : ncr53c8{10,15,20,25}=pci,,,\n" - " and are usually 0.\n"); - - if (options & OPTION_DEBUG_PROBE_ONLY) { - printk ("scsi-ncr53c7,8xx : probe only enabled, aborting initialization\n"); - return -1; - } - - max_cmd_size = sizeof(struct NCR53c7x0_cmd) + dsa_len + - /* Size of dynamic part of command structure : */ - 2 * /* Worst case : we don't know if we need DATA IN or DATA out */ - ( 2 * /* Current instructions per scatter/gather segment */ - tpnt->sg_tablesize + - 3 /* Current startup / termination required per phase */ - ) * - 8 /* Each instruction is eight bytes */; - - /* Allocate fixed part of hostdata, dynamic part to hold appropriate - SCSI SCRIPT(tm) plus a single, maximum-sized NCR53c7x0_cmd structure. - - We need a NCR53c7x0_cmd structure for scan_scsis() when we are - not loaded as a module, and when we're loaded as a module, we - can't use a non-dynamically allocated structure because modules - are vmalloc()'d, which can allow structures to cross page - boundaries and breaks our physical/virtual address assumptions - for DMA. - - So, we stick it past the end of our hostdata structure. - - ASSUMPTION : - Regardless of how many simultaneous SCSI commands we allow, - the probe code only executes a _single_ instruction at a time, - so we only need one here, and don't need to allocate NCR53c7x0_cmd - structures for each target until we are no longer in scan_scsis - and kmalloc() has become functional (memory_init() happens - after all device driver initialization). - */ - - size = sizeof(struct NCR53c7x0_hostdata) + script_len + - /* Note that alignment will be guaranteed, since we put the command - allocated at probe time after the fixed-up SCSI script, which - consists of 32 bit words, aligned on a 32 bit boundary. But - on a 64bit machine we need 8 byte alignment for hostdata->free, so - we add in another 4 bytes to take care of potential misalignment - */ - (sizeof(void *) - sizeof(u32)) + max_cmd_size + schedule_size; - - instance = scsi_register (tpnt, size); - if (!instance) - return -1; - - /* FIXME : if we ever support an ISA NCR53c7xx based board, we - need to check if the chip is running in a 16 bit mode, and if so - unregister it if it is past the 16M (0x1000000) mark */ - - hostdata = (struct NCR53c7x0_hostdata *) - instance->hostdata; - hostdata->size = size; - hostdata->script_count = script_len / sizeof(u32); - hostdata = (struct NCR53c7x0_hostdata *) instance->hostdata; - hostdata->board = board; - hostdata->chip = chip; - if ((hostdata->pci_valid = pci_valid)) { - hostdata->pci_dev = pci_dev; - } - - /* - * Being memory mapped is more desirable, since - * - * - Memory accesses may be faster. - * - * - The destination and source address spaces are the same for - * all instructions, meaning we don't have to twiddle dmode or - * any other registers. - * - * So, we try for memory mapped, and if we don't get it, - * we go for port mapped, and that failing we tell the user - * it can't work. - */ - - if (base) { - instance->base = (unsigned long) base; - /* Check for forced I/O mapping */ - if (!(options & OPTION_IO_MAPPED)) { - options |= OPTION_MEMORY_MAPPED; - ok = 1; - } - } else { - options &= ~OPTION_MEMORY_MAPPED; - } - - if (io_port) { - instance->io_port = io_port; - options |= OPTION_IO_MAPPED; - ok = 1; - } else { - options &= ~OPTION_IO_MAPPED; - } - - if (!ok) { - printk ("scsi%d : not initializing, no I/O or memory mapping known \n", - instance->host_no); - scsi_unregister (instance); - return -1; - } - instance->irq = irq; - instance->dma_channel = dma; - scsi_set_pci_device(instance, pci_dev); - - hostdata->options = options; - hostdata->dsa_len = dsa_len; - hostdata->max_cmd_size = max_cmd_size; - hostdata->num_cmds = 1; - /* Initialize single command */ - tmp = (hostdata->script + hostdata->script_count); - hostdata->free = ROUNDUP(tmp, void *); - hostdata->free->real = tmp; - hostdata->free->size = max_cmd_size; - hostdata->free->free = NULL; - hostdata->free->next = NULL; - hostdata->extra_allocate = 0; - - /* Allocate command start code space */ - hostdata->schedule = (chip == 700 || chip == 70066) ? - NULL : (u32 *) ((char *)hostdata->free + max_cmd_size); - -/* - * For diagnostic purposes, we don't really care how fast things blaze. - * For profiling, we want to access the 800ns resolution system clock, - * using a 'C' call on the host processor. - * - * Therefore, there's no need for the NCR chip to directly manipulate - * this data, and we should put it wherever is most convenient for - * Linux. - */ - if (track_events) - hostdata->events = (struct NCR53c7x0_event *) (track_events ? - vmalloc (sizeof (struct NCR53c7x0_event) * track_events) : NULL); - else - hostdata->events = NULL; - - if (hostdata->events) { - memset ((void *) hostdata->events, 0, sizeof(struct NCR53c7x0_event) * - track_events); - hostdata->event_size = track_events; - hostdata->event_index = 0; - } else - hostdata->event_size = 0; - - return NCR53c7x0_init(instance); -} - - -/* - * Function : static int ncr_pci_init(Scsi_Host_Template *tpnt, int board, - * int chip, int bus, int device_fn, long long options) - * - * Purpose : initializes a NCR53c800 family based on the PCI - * bus, device, and function location of it. Allows - * reprogramming of latency timer and determining addresses - * and whether bus mastering, etc. are OK. - * - * Useful where a new NCR chip is backwards compatible with - * a supported chip, but the DEVICE ID has changed so it - * doesn't show up when the autoprobe does a pci_find_device. - * - * Inputs : tpnt - Template for this SCSI adapter, board - board level - * product, chip - 810, 820, or 825, bus - PCI bus, device_fn - - * device and function encoding as used by PCI BIOS calls. - * - * Returns : 0 on success, -1 on failure. - * - */ - -static int __init -ncr_pci_init (Scsi_Host_Template *tpnt, int board, int chip, - unsigned char bus, unsigned char device_fn, long long options){ - unsigned short command; - unsigned int base, io_port; - unsigned char revision; - int error, expected_chip; - int expected_id = -1, max_revision = -1, min_revision = -1; - int i, irq; - struct pci_dev *pdev = pci_find_slot(bus, device_fn); - - printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d, function %d\n", - bus, (int) (device_fn & 0xf8) >> 3, - (int) device_fn & 7); - - if (!pdev) { - printk("scsi-ncr53c7,8xx : not initializing -- PCI device not found,\n" - " try using memory, port, irq override instead.\n"); - return -1; - } - - if ((error = pci_read_config_word (pdev, PCI_COMMAND, &command)) || - (error = pci_read_config_byte (pdev, PCI_CLASS_REVISION, &revision))) { - printk ("scsi-ncr53c7,8xx : error %d not initializing due to error reading configuration space\n" - " perhaps you specified an incorrect PCI bus, device, or function.\n", error); - return -1; - } - if (pci_enable_device(pdev)) - return -1; - io_port = pci_resource_start(pdev, 0); - base = pci_resource_start(pdev, 1); - irq = pdev->irq; - - /* If any one ever clones the NCR chips, this will have to change */ - - if (pdev->vendor != PCI_VENDOR_ID_NCR) { - printk ("scsi-ncr53c7,8xx : not initializing, 0x%04x is not NCR vendor ID\n", - (int) pdev->vendor); - return -1; - } - - if ( ! (command & PCI_COMMAND_MASTER)) { - printk(KERN_INFO "SCSI: PCI Master Bit has not been set. Setting...\n"); - command |= PCI_COMMAND_MASTER|PCI_COMMAND_IO; - pci_write_config_word(pdev, PCI_COMMAND, command); - } - -#ifdef __powerpc__ - if (io_port >= 0x10000000 && is_prep ) { - /* Mapping on PowerPC can't handle this! */ - unsigned long new_io_port; - new_io_port = (io_port & 0x00FFFFFF) | 0x01000000; - printk("SCSI: I/O moved from %08X to %08x\n", io_port, new_io_port); - io_port = new_io_port; - pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, io_port); - pdev->base_address[0] = io_port; - } -#endif - - /* - * Bit 0 is the address space indicator and must be one for I/O - * space mappings, bit 1 is reserved, discard them after checking - * that they have the correct value of 1. - */ - - if (command & PCI_COMMAND_IO) { - if (!(pdev->resource[0].flags & IORESOURCE_IO)) { - printk ("scsi-ncr53c7,8xx : disabling I/O mapping since base " - "address 0\n contains a non-IO mapping\n"); - io_port = 0; - } - } else { - io_port = 0; - } - - if (command & PCI_COMMAND_MEMORY) { - if (!(pdev->resource[1].flags & IORESOURCE_MEM)) { - printk("scsi-ncr53c7,8xx : disabling memory mapping since base " - "address 1\n contains a non-memory mapping\n"); - base = 0; - } - } else { - base = 0; - } - - if (!io_port && !base) { - printk ("scsi-ncr53c7,8xx : not initializing, both I/O and memory mappings disabled\n"); - return -1; - } - - if (!(command & PCI_COMMAND_MASTER)) { - printk ("scsi-ncr53c7,8xx : not initializing, BUS MASTERING was disabled\n"); - return -1; - } - - for (i = 0; i < NPCI_CHIP_IDS; ++i) { - if (pdev->device == pci_chip_ids[i].pci_device_id) { - max_revision = pci_chip_ids[i].max_revision; - min_revision = pci_chip_ids[i].min_revision; - expected_chip = pci_chip_ids[i].chip; - } - if (chip == pci_chip_ids[i].chip) - expected_id = pci_chip_ids[i].pci_device_id; - } - - if (chip && pdev->device != expected_id) - printk ("scsi-ncr53c7,8xx : warning : device id of 0x%04x doesn't\n" - " match expected 0x%04x\n", - (unsigned int) pdev->device, (unsigned int) expected_id ); - - if (max_revision != -1 && revision > max_revision) - printk ("scsi-ncr53c7,8xx : warning : revision of %d is greater than %d.\n", - (int) revision, max_revision); - else if (min_revision != -1 && revision < min_revision) - printk ("scsi-ncr53c7,8xx : warning : revision of %d is less than %d.\n", - (int) revision, min_revision); - - if (io_port && check_region (io_port, 128)) { - printk ("scsi-ncr53c7,8xx : IO region 0x%x to 0x%x is in use\n", - (unsigned) io_port, (unsigned) io_port + 127); - return -1; - } - - return normal_init (tpnt, board, chip, (int) base, io_port, - (int) irq, DMA_NONE, 1, pdev, options); -} - - -/* - * Function : int NCR53c7xx_detect(Scsi_Host_Template *tpnt) - * - * Purpose : detects and initializes NCR53c7,8x0 SCSI chips - * that were autoprobed, overridden on the LILO command line, - * or specified at compile time. - * - * Inputs : tpnt - template for this SCSI adapter - * - * Returns : number of host adapters detected - * - */ - -int __init -NCR53c7xx_detect(Scsi_Host_Template *tpnt){ - int i; - int current_override; - int count; /* Number of boards detected */ - struct pci_dev *pdev = NULL; - - tpnt->proc_name = "ncr53c7xx"; - - for (current_override = count = 0; current_override < OVERRIDE_LIMIT; - ++current_override) { - if (overrides[current_override].pci ? - !ncr_pci_init (tpnt, overrides[current_override].board, - overrides[current_override].chip, - (unsigned char) overrides[current_override].data.pci.bus, - (((overrides[current_override].data.pci.device - << 3) & 0xf8)|(overrides[current_override].data.pci.function & - 7)), overrides[current_override].options): - !normal_init (tpnt, overrides[current_override].board, - overrides[current_override].chip, - overrides[current_override].data.normal.base, - overrides[current_override].data.normal.io_port, - overrides[current_override].data.normal.irq, - overrides[current_override].data.normal.dma, - 0 /* PCI data invalid */, 0 /* PCI bus place holder */, - 0 /* PCI device_function place holder */, - NULL /* PCI pci_dev place holder */, - overrides[current_override].options)) { - ++count; - } - } - - if (pci_present()) { - for (i = 0; i < NPCI_CHIP_IDS; ++i) - while ((pdev = pci_find_device (PCI_VENDOR_ID_NCR, - pci_chip_ids[i].pci_device_id, - pdev))) - if (!ncr_pci_init (tpnt, BOARD_GENERIC, pci_chip_ids[i].chip, - pdev->bus->number, pdev->devfn, /* no options */ 0)) - ++count; - } - return count; -} - -/* NCR53c810 and NCR53c820 script handling code */ - -#include "53c8xx_d.h" -#ifdef A_int_debug_sync -#define DEBUG_SYNC_INTR A_int_debug_sync -#endif -static int NCR53c8xx_script_len = sizeof (SCRIPT); -static int NCR53c8xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template; - -/* - * Function : static void NCR53c8x0_init_fixup (struct Scsi_Host *host) - * - * Purpose : copy and fixup the SCSI SCRIPTS(tm) code for this device. - * - * Inputs : host - pointer to this host adapter's structure - * - */ - -static void -NCR53c8x0_init_fixup (struct Scsi_Host *host) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - unsigned char tmp; - int i, ncr_to_memory, memory_to_ncr; - u32 base; -#ifdef __powerpc__ - unsigned long *script_ptr; -#endif - NCR53c7x0_local_setup(host); - - - /* XXX - NOTE : this code MUST be made endian aware */ - /* Copy code into buffer that was allocated at detection time. */ - memcpy ((void *) hostdata->script, (void *) SCRIPT, - sizeof(SCRIPT)); - /* Fixup labels */ - for (i = 0; i < PATCHES; ++i) - hostdata->script[LABELPATCHES[i]] += - virt_to_bus(hostdata->script); - /* Fixup addresses of constants that used to be EXTERNAL */ - - patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_abort, - virt_to_bus(&(hostdata->NCR53c7xx_msg_abort))); - patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_reject, - virt_to_bus(&(hostdata->NCR53c7xx_msg_reject))); - patch_abs_32 (hostdata->script, 0, NCR53c7xx_zero, - virt_to_bus(&(hostdata->NCR53c7xx_zero))); - patch_abs_32 (hostdata->script, 0, NCR53c7xx_sink, - virt_to_bus(&(hostdata->NCR53c7xx_sink))); - patch_abs_32 (hostdata->script, 0, NOP_insn, - virt_to_bus(&(hostdata->NOP_insn))); - patch_abs_32 (hostdata->script, 0, schedule, - virt_to_bus((void *) hostdata->schedule)); - - /* Fixup references to external variables: */ - for (i = 0; i < EXTERNAL_PATCHES_LEN; ++i) - hostdata->script[EXTERNAL_PATCHES[i].offset] += - virt_to_bus(EXTERNAL_PATCHES[i].address); - - /* - * Fixup absolutes set at boot-time. - * - * All non-code absolute variables suffixed with "dsa_" and "int_" - * are constants, and need no fixup provided the assembler has done - * it for us (I don't know what the "real" NCR assembler does in - * this case, my assembler does the right magic). - */ - - patch_abs_rwri_data (hostdata->script, 0, dsa_save_data_pointer, - Ent_dsa_code_save_data_pointer - Ent_dsa_zero); - patch_abs_rwri_data (hostdata->script, 0, dsa_restore_pointers, - Ent_dsa_code_restore_pointers - Ent_dsa_zero); - patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect, - Ent_dsa_code_check_reselect - Ent_dsa_zero); - - /* - * Just for the hell of it, preserve the settings of - * Burst Length and Enable Read Line bits from the DMODE - * register. Make sure SCRIPTS start automagically. - */ - - tmp = NCR53c7x0_read8(DMODE_REG_10); - tmp &= (DMODE_800_ERL | DMODE_BL_MASK); - - if (!(hostdata->options & OPTION_MEMORY_MAPPED)) { - base = (u32) host->io_port; - memory_to_ncr = tmp|DMODE_800_DIOM; - ncr_to_memory = tmp|DMODE_800_SIOM; - } else { - base = virt_to_bus((void *)host->base); - memory_to_ncr = ncr_to_memory = tmp; - } - - patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800); - patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG); - - /* - * I needed some variables in the script to be accessible to - * both the NCR chip and the host processor. For these variables, - * I made the arbitrary decision to store them directly in the - * hostdata structure rather than in the RELATIVE area of the - * SCRIPTS. - */ - - - patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp); - patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr); - patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory); - - patch_abs_32 (hostdata->script, 0, msg_buf, - virt_to_bus((void *)&(hostdata->msg_buf))); - patch_abs_32 (hostdata->script, 0, reconnect_dsa_head, - virt_to_bus((void *)&(hostdata->reconnect_dsa_head))); - patch_abs_32 (hostdata->script, 0, addr_reconnect_dsa_head, - virt_to_bus((void *)&(hostdata->addr_reconnect_dsa_head))); - patch_abs_32 (hostdata->script, 0, reselected_identify, - virt_to_bus((void *)&(hostdata->reselected_identify))); -/* reselected_tag is currently unused */ -#if 0 - patch_abs_32 (hostdata->script, 0, reselected_tag, - virt_to_bus((void *)&(hostdata->reselected_tag))); -#endif - - patch_abs_32 (hostdata->script, 0, test_dest, - virt_to_bus((void*)&hostdata->test_dest)); - patch_abs_32 (hostdata->script, 0, test_src, - virt_to_bus(&hostdata->test_source)); - - patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect, - (unsigned char)(Ent_dsa_code_check_reselect - Ent_dsa_zero)); - -/* These are for event logging; the ncr_event enum contains the - actual interrupt numbers. */ -#ifdef A_int_EVENT_SELECT - patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT, (u32) EVENT_SELECT); -#endif -#ifdef A_int_EVENT_DISCONNECT - patch_abs_32 (hostdata->script, 0, int_EVENT_DISCONNECT, (u32) EVENT_DISCONNECT); -#endif -#ifdef A_int_EVENT_RESELECT - patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT, (u32) EVENT_RESELECT); -#endif -#ifdef A_int_EVENT_COMPLETE - patch_abs_32 (hostdata->script, 0, int_EVENT_COMPLETE, (u32) EVENT_COMPLETE); -#endif -#ifdef A_int_EVENT_IDLE - patch_abs_32 (hostdata->script, 0, int_EVENT_IDLE, (u32) EVENT_IDLE); -#endif -#ifdef A_int_EVENT_SELECT_FAILED - patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT_FAILED, - (u32) EVENT_SELECT_FAILED); -#endif -#ifdef A_int_EVENT_BEFORE_SELECT - patch_abs_32 (hostdata->script, 0, int_EVENT_BEFORE_SELECT, - (u32) EVENT_BEFORE_SELECT); -#endif -#ifdef A_int_EVENT_RESELECT_FAILED - patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT_FAILED, - (u32) EVENT_RESELECT_FAILED); -#endif - - /* - * Make sure the NCR and Linux code agree on the location of - * certain fields. - */ - - hostdata->E_accept_message = Ent_accept_message; - hostdata->E_command_complete = Ent_command_complete; - hostdata->E_cmdout_cmdout = Ent_cmdout_cmdout; - hostdata->E_data_transfer = Ent_data_transfer; - hostdata->E_debug_break = Ent_debug_break; - hostdata->E_dsa_code_template = Ent_dsa_code_template; - hostdata->E_dsa_code_template_end = Ent_dsa_code_template_end; - hostdata->E_end_data_transfer = Ent_end_data_transfer; - hostdata->E_initiator_abort = Ent_initiator_abort; - hostdata->E_msg_in = Ent_msg_in; - hostdata->E_other_transfer = Ent_other_transfer; - hostdata->E_other_in = Ent_other_in; - hostdata->E_other_out = Ent_other_out; - hostdata->E_reject_message = Ent_reject_message; - hostdata->E_respond_message = Ent_respond_message; - hostdata->E_select = Ent_select; - hostdata->E_select_msgout = Ent_select_msgout; - hostdata->E_target_abort = Ent_target_abort; -#ifdef Ent_test_0 - hostdata->E_test_0 = Ent_test_0; -#endif - hostdata->E_test_1 = Ent_test_1; - hostdata->E_test_2 = Ent_test_2; -#ifdef Ent_test_3 - hostdata->E_test_3 = Ent_test_3; -#endif - hostdata->E_wait_reselect = Ent_wait_reselect; - hostdata->E_dsa_code_begin = Ent_dsa_code_begin; - - hostdata->dsa_cmdout = A_dsa_cmdout; - hostdata->dsa_cmnd = A_dsa_cmnd; - hostdata->dsa_datain = A_dsa_datain; - hostdata->dsa_dataout = A_dsa_dataout; - hostdata->dsa_end = A_dsa_end; - hostdata->dsa_msgin = A_dsa_msgin; - hostdata->dsa_msgout = A_dsa_msgout; - hostdata->dsa_msgout_other = A_dsa_msgout_other; - hostdata->dsa_next = A_dsa_next; - hostdata->dsa_select = A_dsa_select; - hostdata->dsa_start = Ent_dsa_code_template - Ent_dsa_zero; - hostdata->dsa_status = A_dsa_status; - hostdata->dsa_jump_dest = Ent_dsa_code_fix_jump - Ent_dsa_zero + - 8 /* destination operand */; - - /* sanity check */ - if (A_dsa_fields_start != Ent_dsa_code_template_end - - Ent_dsa_zero) - printk("scsi%d : NCR dsa_fields start is %d not %d\n", - host->host_no, A_dsa_fields_start, Ent_dsa_code_template_end - - Ent_dsa_zero); -#ifdef __powerpc__ -/* The PowerPC is Big Endian - adjust script appropriately */ - script_ptr = hostdata->script; - for (i = 0; i < sizeof(SCRIPT); i += sizeof(long)) - { - *script_ptr++ = le32_to_cpu(*script_ptr); - } -#endif - - printk("scsi%d : NCR code relocated to 0x%lx (virt 0x%p)\n", host->host_no, - virt_to_bus(hostdata->script), hostdata->script); -} - -/* - * Function : static int NCR53c8xx_run_tests (struct Scsi_Host *host) - * - * Purpose : run various verification tests on the NCR chip, - * including interrupt generation, and proper bus mastering - * operation. - * - * Inputs : host - a properly initialized Scsi_Host structure - * - * Preconditions : the NCR chip must be in a halted state. - * - * Returns : 0 if all tests were successful, -1 on error. - * - */ - -static int -NCR53c8xx_run_tests (struct Scsi_Host *host) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - unsigned long timeout; - u32 start; - int failed, i; - unsigned long flags; - NCR53c7x0_local_setup(host); - - /* The NCR chip _must_ be idle to run the test scripts */ - - save_flags(flags); - cli(); - if (!hostdata->idle) { - printk ("scsi%d : chip not idle, aborting tests\n", host->host_no); - restore_flags(flags); - return -1; - } - - /* - * Check for functional interrupts, this could work as an - * autoprobe routine. - */ - - if ((hostdata->options & OPTION_DEBUG_TEST1) && - hostdata->state != STATE_DISABLED) { - hostdata->idle = 0; - hostdata->test_running = 1; - hostdata->test_completed = -1; - hostdata->test_dest = 0; - hostdata->test_source = 0xdeadbeef; - start = virt_to_bus (hostdata->script) + hostdata->E_test_1; - hostdata->state = STATE_RUNNING; - printk ("scsi%d : test 1", host->host_no); - NCR53c7x0_write32 (DSP_REG, start); - printk (" started\n"); - restore_flags(flags); - - /* - * This is currently a .5 second timeout, since (in theory) no slow - * board will take that long. In practice, we've seen one - * pentium which occasionally fails with this, but works with - * 10 times as much? - */ - - timeout = jiffies + 5 * HZ / 10; - while ((hostdata->test_completed == -1) && time_before(jiffies, timeout)) { - barrier(); - cpu_relax(); - } - - failed = 1; - if (hostdata->test_completed == -1) - printk ("scsi%d : driver test 1 timed out%s\n",host->host_no , - (hostdata->test_dest == 0xdeadbeef) ? - " due to lost interrupt.\n" - " Please verify that the correct IRQ is being used for your board,\n" - " and that the motherboard IRQ jumpering matches the PCI setup on\n" - " PCI systems.\n" - " If you are using a NCR53c810 board in a PCI system, you should\n" - " also verify that the board is jumpered to use PCI INTA, since\n" - " most PCI motherboards lack support for INTB, INTC, and INTD.\n" - : ""); - else if (hostdata->test_completed != 1) - printk ("scsi%d : test 1 bad interrupt value (%d)\n", - host->host_no, hostdata->test_completed); - else - failed = (hostdata->test_dest != 0xdeadbeef); - - if (hostdata->test_dest != 0xdeadbeef) { - printk ("scsi%d : driver test 1 read 0x%x instead of 0xdeadbeef indicating a\n" - " probable cache invalidation problem. Please configure caching\n" - " as write-through or disabled\n", - host->host_no, hostdata->test_dest); - } - - if (failed) { - printk ("scsi%d : DSP = 0x%p (script at 0x%p, start at 0x%x)\n", - host->host_no, bus_to_virt(NCR53c7x0_read32(DSP_REG)), - hostdata->script, start); - printk ("scsi%d : DSPS = 0x%x\n", host->host_no, - NCR53c7x0_read32(DSPS_REG)); - return -1; - } - hostdata->test_running = 0; - } - - if ((hostdata->options & OPTION_DEBUG_TEST2) && - hostdata->state != STATE_DISABLED) { - u32 dsa[48]; - unsigned char identify = IDENTIFY(0, 0); - unsigned char cmd[6]; - unsigned char data[36]; - unsigned char status = 0xff; - unsigned char msg = 0xff; - - cmd[0] = INQUIRY; - cmd[1] = cmd[2] = cmd[3] = cmd[5] = 0; - cmd[4] = sizeof(data); - -/* Need to adjust for endian-ness */ - dsa[2] = le32_to_cpu(1); - dsa[3] = le32_to_cpu(virt_to_bus(&identify)); - dsa[4] = le32_to_cpu(6); - dsa[5] = le32_to_cpu(virt_to_bus(&cmd)); - dsa[6] = le32_to_cpu(sizeof(data)); - dsa[7] = le32_to_cpu(virt_to_bus(&data)); - dsa[8] = le32_to_cpu(1); - dsa[9] = le32_to_cpu(virt_to_bus(&status)); - dsa[10] = le32_to_cpu(1); - dsa[11] = le32_to_cpu(virt_to_bus(&msg)); - - for (i = 0; i < 3; ++i) { - cli(); - if (!hostdata->idle) { - printk ("scsi%d : chip not idle, aborting tests\n", host->host_no); - restore_flags(flags); - return -1; - } - - /* SCNTL3 SDID */ - dsa[0] = le32_to_cpu((0x33 << 24) | (i << 16)) ; - hostdata->idle = 0; - hostdata->test_running = 2; - hostdata->test_completed = -1; - start = virt_to_bus(hostdata->script) + hostdata->E_test_2; - hostdata->state = STATE_RUNNING; - NCR53c7x0_write32 (DSA_REG, virt_to_bus(dsa)); - NCR53c7x0_write32 (DSP_REG, start); - restore_flags(flags); - - timeout = jiffies + 5 * HZ; /* arbitrary */ - while ((hostdata->test_completed == -1) && time_before(jiffies, timeout)) { - barrier(); - cpu_relax(); - } - NCR53c7x0_write32 (DSA_REG, 0); - - if (hostdata->test_completed == 2) { - data[35] = 0; - printk ("scsi%d : test 2 INQUIRY to target %d, lun 0 : %s\n", - host->host_no, i, data + 8); - printk ("scsi%d : status ", host->host_no); - print_status (status); - printk ("\nscsi%d : message ", host->host_no); - print_msg (&msg); - printk ("\n"); - } else if (hostdata->test_completed == 3) { - printk("scsi%d : test 2 no connection with target %d\n", - host->host_no, i); - if (!hostdata->idle) { - printk("scsi%d : not idle\n", host->host_no); - restore_flags(flags); - return -1; - } - } else if (hostdata->test_completed == -1) { - printk ("scsi%d : test 2 timed out\n", host->host_no); - restore_flags(flags); - return -1; - } - hostdata->test_running = 0; - } - } - - restore_flags(flags); - return 0; -} - -/* - * Function : static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) - * - * Purpose : copy the NCR53c8xx dsa structure into cmd's dsa buffer, - * performing all necessary relocation. - * - * Inputs : cmd, a NCR53c7x0_cmd structure with a dsa area large - * enough to hold the NCR53c8xx dsa. - */ - -static void -NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) { - Scsi_Cmnd *c = cmd->cmd; - struct Scsi_Host *host = c->host; - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - int i; -#ifdef __powerpc__ - int len; - unsigned long *dsa_ptr; -#endif - - memcpy (cmd->dsa, hostdata->script + (hostdata->E_dsa_code_template / 4), - hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template); -#ifdef __powerpc__ - /* Note: the script has already been 'endianized' */ - dsa_ptr = cmd->dsa; - len = hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template; - for (i = 0; i < len; i += sizeof(long)) - { - *dsa_ptr++ = le32_to_cpu(*dsa_ptr); - } -#endif - - /* - * Note : within the NCR 'C' code, dsa points to the _start_ - * of the DSA structure, and _not_ the offset of dsa_zero within - * that structure used to facilitate shorter signed offsets - * for the 8 bit ALU. - * - * The implications of this are that - * - * - 32 bit A_dsa_* absolute values require an additional - * dsa_zero added to their value to be correct, since they are - * relative to dsa_zero which is in essentially a separate - * space from the code symbols. - * - * - All other symbols require no special treatment. - */ - - patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32), - dsa_temp_lun, c->lun); - patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), - dsa_temp_addr_next, virt_to_bus(&cmd->dsa_next_addr)); - patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), - dsa_temp_next, virt_to_bus(cmd->dsa) + Ent_dsa_zero - - Ent_dsa_code_template + A_dsa_next); - patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), - dsa_temp_sync, virt_to_bus((void *)hostdata->sync[c->target].script)); - patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32), - dsa_temp_target, c->target); - /* XXX - new pointer stuff */ - patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), - dsa_temp_addr_saved_pointer, virt_to_bus(&cmd->saved_data_pointer)); - patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), - dsa_temp_addr_saved_residual, virt_to_bus(&cmd->saved_residual)); - patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), - dsa_temp_addr_residual, virt_to_bus(&cmd->residual)); - - /* XXX - new start stuff */ - patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32), - dsa_temp_addr_dsa_value, virt_to_bus(&cmd->dsa_addr)); -#ifdef __powerpc__ - dsa_ptr = cmd->dsa; - len = hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template; - for (i = 0; i < len; i += sizeof(long)) - { - *dsa_ptr++ = le32_to_cpu(*dsa_ptr); - } -#endif - -} - -/* - * Function : run_process_issue_queue (void) - * - * Purpose : insure that the coroutine is running and will process our - * request. process_issue_queue_running is checked/set here (in an - * inline function) rather than in process_issue_queue itself to reduce - * the chances of stack overflow. - * - */ - -static volatile int process_issue_queue_running = 0; - -static __inline__ void -run_process_issue_queue(void) { - unsigned long flags; - save_flags (flags); - cli(); - if (!process_issue_queue_running) { - process_issue_queue_running = 1; - process_issue_queue(flags); - /* - * process_issue_queue_running is cleared in process_issue_queue - * once it can't do more work, and process_issue_queue exits with - * interrupts disabled. - */ - } - restore_flags (flags); -} - -/* - * Function : static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int - * result) - * - * Purpose : mark SCSI command as finished, OR'ing the host portion - * of the result word into the result field of the corresponding - * Scsi_Cmnd structure, and removing it from the internal queues. - * - * Inputs : cmd - command, result - entire result field - * - * Preconditions : the NCR chip should be in a halted state when - * abnormal_finished is run, since it modifies structures which - * the NCR expects to have exclusive access to. - */ - -static void -abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) { - Scsi_Cmnd *c = cmd->cmd; - struct Scsi_Host *host = c->host; - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - unsigned long flags; - int left, found; - volatile struct NCR53c7x0_cmd * linux_search; - volatile struct NCR53c7x0_cmd * volatile *linux_prev; - volatile u32 *ncr_prev, *curr, ncr_search; - -#if 0 - printk ("scsi%d: abnormal finished\n", host->host_no); -#endif - - save_flags(flags); - cli(); - found = 0; - /* - * Traverse the NCR issue array until we find a match or run out - * of instructions. Instructions in the NCR issue array are - * either JUMP or NOP instructions, which are 2 words in length. - */ - - - for (found = 0, left = host->can_queue, curr = hostdata->schedule; - left > 0; --left, curr += 2) - { - if (issue_to_cmd (host, hostdata, (u32 *) curr) == cmd) - { - curr[0] = hostdata->NOP_insn; - curr[1] = le32_to_cpu(0xdeadbeef); - ++found; - break; - } - } - - /* - * Traverse the NCR reconnect list of DSA structures until we find - * a pointer to this dsa or have found too many command structures. - * We let prev point at the next field of the previous element or - * head of the list, so we don't do anything different for removing - * the head element. - */ - - for (left = host->can_queue, - ncr_search = le32_to_cpu(hostdata->reconnect_dsa_head), - ncr_prev = &hostdata->reconnect_dsa_head; - left >= 0 && ncr_search && - ((char*)bus_to_virt(ncr_search) + hostdata->dsa_start) - != (char *) cmd->dsa; - ncr_prev = (u32*) ((char*)bus_to_virt(ncr_search) + - hostdata->dsa_next), ncr_search = le32_to_cpu(*ncr_prev), --left); - - if (left < 0) { - printk("scsi%d: loop detected in ncr reconnect list\n", - host->host_no); - } else if (ncr_search) { - if (found) - printk("scsi%d: scsi %ld in ncr issue array and reconnect lists\n", - host->host_no, c->pid); - else { - volatile u32 * next = (u32 *) - ((char *)bus_to_virt(ncr_search) + hostdata->dsa_next); - *ncr_prev = *next; -/* If we're at the tail end of the issue queue, update that pointer too. */ - found = 1; - } - } - - /* - * Traverse the host running list until we find this command or discover - * we have too many elements, pointing linux_prev at the next field of the - * linux_previous element or head of the list, search at this element. - */ - - for (left = host->can_queue, linux_search = hostdata->running_list, - linux_prev = &hostdata->running_list; - left >= 0 && linux_search && linux_search != cmd; - linux_prev = &(linux_search->next), - linux_search = linux_search->next, --left); - - if (left < 0) - printk ("scsi%d: loop detected in host running list for scsi pid %ld\n", - host->host_no, c->pid); - else if (linux_search) { - *linux_prev = linux_search->next; - --hostdata->busy[c->target][c->lun]; - } - - /* Return the NCR command structure to the free list */ - cmd->next = hostdata->free; - hostdata->free = cmd; - c->host_scribble = NULL; - - /* And return */ - c->result = result; - c->scsi_done(c); - - restore_flags(flags); - run_process_issue_queue(); -} - -/* - * Function : static void intr_break (struct Scsi_Host *host, - * struct NCR53c7x0_cmd *cmd) - * - * Purpose : Handler for breakpoint interrupts from a SCSI script - * - * Inputs : host - pointer to this host adapter's structure, - * cmd - pointer to the command (if any) dsa was pointing - * to. - * - */ - -static void -intr_break (struct Scsi_Host *host, struct - NCR53c7x0_cmd *cmd) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_break *bp; -#if 0 - Scsi_Cmnd *c = cmd ? cmd->cmd : NULL; -#endif - u32 *dsp; - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - unsigned long flags; - NCR53c7x0_local_setup(host); - - /* - * Find the break point corresponding to this address, and - * dump the appropriate debugging information to standard - * output. - */ - save_flags(flags); - cli(); - dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG)); - for (bp = hostdata->breakpoints; bp && bp->address != dsp; - bp = bp->next); - if (!bp) - panic("scsi%d : break point interrupt from %p with no breakpoint!", - host->host_no, dsp); - - /* - * Configure the NCR chip for manual start mode, so that we can - * point the DSP register at the instruction that follows the - * INT int_debug_break instruction. - */ - - NCR53c7x0_write8 (hostdata->dmode, - NCR53c7x0_read8(hostdata->dmode)|DMODE_MAN); - - /* - * And update the DSP register, using the size of the old - * instruction in bytes. - */ - - restore_flags(flags); -} -/* - * Function : static void print_synchronous (const char *prefix, - * const unsigned char *msg) - * - * Purpose : print a pretty, user and machine parsable representation - * of a SDTR message, including the "real" parameters, data - * clock so we can tell transfer rate at a glance. - * - * Inputs ; prefix - text to prepend, msg - SDTR message (5 bytes) - */ - -static void -print_synchronous (const char *prefix, const unsigned char *msg) { - if (msg[4]) { - int Hz = 1000000000 / (msg[3] * 4); - int integer = Hz / 1000000; - int fraction = (Hz - (integer * 1000000)) / 10000; - printk ("%speriod %dns offset %d %d.%02dMHz %s SCSI%s\n", - prefix, (int) msg[3] * 4, (int) msg[4], integer, fraction, - (((msg[3] * 4) < 200) ? "FAST" : "synchronous"), - (((msg[3] * 4) < 200) ? "-II" : "")); - } else - printk ("%sasynchronous SCSI\n", prefix); -} - -/* - * Function : static void set_synchronous (struct Scsi_Host *host, - * int target, int sxfer, int scntl3, int now_connected) - * - * Purpose : reprogram transfers between the selected SCSI initiator and - * target with the given register values; in the indirect - * select operand, reselection script, and chip registers. - * - * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id, - * sxfer and scntl3 - NCR registers. now_connected - if non-zero, - * we should reprogram the registers now too. - */ - -static void -set_synchronous (struct Scsi_Host *host, int target, int sxfer, int scntl3, - int now_connected) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - u32 *script; - NCR53c7x0_local_setup(host); - - /* These are eight bit registers */ - sxfer &= 0xff; - scntl3 &= 0xff; - - hostdata->sync[target].sxfer_sanity = sxfer; - hostdata->sync[target].scntl3_sanity = scntl3; - -/* - * HARD CODED : synchronous script is EIGHT words long. This - * must agree with 53c7.8xx.h - */ - - if ((hostdata->chip != 700) && (hostdata->chip != 70066)) { - hostdata->sync[target].select_indirect = (scntl3 << 24) | - (target << 16) | (sxfer << 8); - - script = (u32 *) hostdata->sync[target].script; - - /* XXX - add NCR53c7x0 code to reprogram SCF bits if we want to */ - if ((hostdata->chip / 100) == 8) { - script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY | - DCMD_RWRI_OP_MOVE) << 24) | - (SCNTL3_REG_800 << 16) | (scntl3 << 8); - script[1] = 0; - script += 2; - } - - script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY | - DCMD_RWRI_OP_MOVE) << 24) | - (SXFER_REG << 16) | (sxfer << 8); - script[1] = 0; - script += 2; - -#ifdef DEBUG_SYNC_INTR - if (hostdata->options & OPTION_DEBUG_DISCONNECT) { - script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_INT) << 24) | DBC_TCI_TRUE; - script[1] = DEBUG_SYNC_INTR; - script += 2; - } -#endif - - script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_RETURN) << 24) | DBC_TCI_TRUE; - script[1] = 0; - script += 2; - } - - if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS) - printk ("scsi%d : target %d sync parameters are sxfer=0x%x, scntl3=0x%x\n", - host->host_no, target, sxfer, scntl3); - - if (now_connected) { - if ((hostdata->chip / 100) == 8) - NCR53c7x0_write8(SCNTL3_REG_800, scntl3); - NCR53c7x0_write8(SXFER_REG, sxfer); - } -} - - -/* - * Function : static int asynchronous (struct Scsi_Host *host, int target) - * - * Purpose : reprogram between the selected SCSI Host adapter and target - * (assumed to be currently connected) for asynchronous transfers. - * - * Inputs : host - SCSI host structure, target - numeric target ID. - * - * Preconditions : the NCR chip should be in one of the halted states - */ - -static void -asynchronous (struct Scsi_Host *host, int target) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - NCR53c7x0_local_setup(host); - set_synchronous (host, target, /* no offset */ 0, hostdata->saved_scntl3, - 1); - printk ("scsi%d : setting target %d to asynchronous SCSI\n", - host->host_no, target); -} - -/* - * XXX - do we want to go out of our way (ie, add extra code to selection - * in the NCR53c710/NCR53c720 script) to reprogram the synchronous - * conversion bits, or can we be content in just setting the - * sxfer bits? - */ - -/* Table for NCR53c8xx synchronous values */ -static const struct { - int div; /* Total clock divisor * 10 */ - unsigned char scf; /* */ - unsigned char tp; /* 4 + tp = xferp divisor */ -} syncs[] = { -/* div scf tp div scf tp div scf tp */ - { 40, 1, 0}, { 50, 1, 1}, { 60, 1, 2}, - { 70, 1, 3}, { 75, 2, 1}, { 80, 1, 4}, - { 90, 1, 5}, { 100, 1, 6}, { 105, 2, 3}, - { 110, 1, 7}, { 120, 2, 4}, { 135, 2, 5}, - { 140, 3, 3}, { 150, 2, 6}, { 160, 3, 4}, - { 165, 2, 7}, { 180, 3, 5}, { 200, 3, 6}, - { 210, 4, 3}, { 220, 3, 7}, { 240, 4, 4}, - { 270, 4, 5}, { 300, 4, 6}, { 330, 4, 7} -}; - -/* - * Function : static void synchronous (struct Scsi_Host *host, int target, - * char *msg) - * - * Purpose : reprogram transfers between the selected SCSI initiator and - * target for synchronous SCSI transfers such that the synchronous - * offset is less than that requested and period at least as long - * as that requested. Also modify *msg such that it contains - * an appropriate response. - * - * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id, - * msg - synchronous transfer request. - */ - - -static void -synchronous (struct Scsi_Host *host, int target, char *msg) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - int desire, divisor, i, limit; - unsigned char scntl3, sxfer; -/* The diagnostic message fits on one line, even with max. width integers */ - char buf[80]; - -/* Desired transfer clock in Hz */ - desire = 1000000000L / (msg[3] * 4); -/* Scale the available SCSI clock by 10 so we get tenths */ - divisor = (hostdata->scsi_clock * 10) / desire; - -/* NCR chips can handle at most an offset of 8 */ - if (msg[4] > 8) - msg[4] = 8; - - if (hostdata->options & OPTION_DEBUG_SDTR) - printk("scsi%d : optimal synchronous divisor of %d.%01d\n", - host->host_no, divisor / 10, divisor % 10); - - limit = (sizeof(syncs) / sizeof(syncs[0]) -1); - for (i = 0; (i < limit) && (divisor > syncs[i].div); ++i); - - if (hostdata->options & OPTION_DEBUG_SDTR) - printk("scsi%d : selected synchronous divisor of %d.%01d\n", - host->host_no, syncs[i].div / 10, syncs[i].div % 10); - - msg[3] = ((1000000000L / hostdata->scsi_clock) * syncs[i].div / 10 / 4); - - if (hostdata->options & OPTION_DEBUG_SDTR) - printk("scsi%d : selected synchronous period of %dns\n", host->host_no, - msg[3] * 4); - - scntl3 = (hostdata->chip / 100 == 8) ? ((hostdata->saved_scntl3 & - ~SCNTL3_800_SCF_MASK) | (syncs[i].scf << SCNTL3_800_SCF_SHIFT)) : 0; - sxfer = (msg[4] << SXFER_MO_SHIFT) | ((syncs[i].tp) << SXFER_TP_SHIFT); - if (hostdata->options & OPTION_DEBUG_SDTR) - printk ("scsi%d : sxfer=0x%x scntl3=0x%x\n", - host->host_no, (int) sxfer, (int) scntl3); - set_synchronous (host, target, sxfer, scntl3, 1); - sprintf (buf, "scsi%d : setting target %d to ", host->host_no, target); - print_synchronous (buf, msg); -} - -/* - * Function : static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, - * struct NCR53c7x0_cmd *cmd) - * - * Purpose : Handler for INT generated instructions for the - * NCR53c810/820 SCSI SCRIPT - * - * Inputs : host - pointer to this host adapter's structure, - * cmd - pointer to the command (if any) dsa was pointing - * to. - * - */ - -static int -NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct - NCR53c7x0_cmd *cmd) { - NCR53c7x0_local_declare(); - int print; - Scsi_Cmnd *c = cmd ? cmd->cmd : NULL; - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - u32 dsps,*dsp; /* Argument of the INT instruction */ - NCR53c7x0_local_setup(host); - dsps = NCR53c7x0_read32(DSPS_REG); - dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG)); - - if (hostdata->options & OPTION_DEBUG_INTR) - printk ("scsi%d : DSPS = 0x%x\n", host->host_no, dsps); - - switch (dsps) { - case A_int_msg_1: - print = 1; - switch (hostdata->msg_buf[0]) { - /* - * Unless we've initiated synchronous negotiation, I don't - * think that this should happen. - */ - case MESSAGE_REJECT: - hostdata->dsp = hostdata->script + hostdata->E_accept_message / - sizeof(u32); - hostdata->dsp_changed = 1; - if (cmd && (cmd->flags & CMD_FLAG_SDTR)) { - printk ("scsi%d : target %d rejected SDTR\n", host->host_no, - c->target); - cmd->flags &= ~CMD_FLAG_SDTR; - asynchronous (host, c->target); - print = 0; - } - break; - case INITIATE_RECOVERY: - printk ("scsi%d : extended contingent allegiance not supported yet, rejecting\n", - host->host_no); - /* Fall through to default */ - hostdata->dsp = hostdata->script + hostdata->E_reject_message / - sizeof(u32); - hostdata->dsp_changed = 1; - break; - default: - printk ("scsi%d : unsupported message, rejecting\n", - host->host_no); - hostdata->dsp = hostdata->script + hostdata->E_reject_message / - sizeof(u32); - hostdata->dsp_changed = 1; - } - if (print) { - printk ("scsi%d : received message", host->host_no); - if (c) - printk (" from target %d lun %d ", c->target, c->lun); - print_msg ((unsigned char *) hostdata->msg_buf); - printk("\n"); - } - - return SPECIFIC_INT_NOTHING; - - - case A_int_msg_sdtr: -/* - * At this point, hostdata->msg_buf contains - * 0 EXTENDED MESSAGE - * 1 length - * 2 SDTR - * 3 period * 4ns - * 4 offset - */ - - if (cmd) { - char buf[80]; - sprintf (buf, "scsi%d : target %d %s ", host->host_no, c->target, - (cmd->flags & CMD_FLAG_SDTR) ? "accepting" : "requesting"); - print_synchronous (buf, (unsigned char *) hostdata->msg_buf); - - /* - * Initiator initiated, won't happen unless synchronous - * transfers are enabled. If we get a SDTR message in - * response to our SDTR, we should program our parameters - * such that - * offset <= requested offset - * period >= requested period - */ - if (cmd->flags & CMD_FLAG_SDTR) { - cmd->flags &= ~CMD_FLAG_SDTR; - if (hostdata->msg_buf[4]) - synchronous (host, c->target, (unsigned char *) - hostdata->msg_buf); - else - asynchronous (host, c->target); - hostdata->dsp = hostdata->script + hostdata->E_accept_message / - sizeof(u32); - hostdata->dsp_changed = 1; - return SPECIFIC_INT_NOTHING; - } else { - if (hostdata->options & OPTION_SYNCHRONOUS) { - cmd->flags |= CMD_FLAG_DID_SDTR; - synchronous (host, c->target, (unsigned char *) - hostdata->msg_buf); - } else { - hostdata->msg_buf[4] = 0; /* 0 offset = async */ - asynchronous (host, c->target); - } - patch_dsa_32 (cmd->dsa, dsa_msgout_other, 0, le32_to_cpu(5)); - patch_dsa_32 (cmd->dsa, dsa_msgout_other, 1, (u32) - le32_to_cpu(virt_to_bus ((void *)&hostdata->msg_buf))); - hostdata->dsp = hostdata->script + - hostdata->E_respond_message / sizeof(u32); - hostdata->dsp_changed = 1; - } - return SPECIFIC_INT_NOTHING; - } - /* Fall through to abort if we couldn't find a cmd, and - therefore a dsa structure to twiddle */ - case A_int_msg_wdtr: - hostdata->dsp = hostdata->script + hostdata->E_reject_message / - sizeof(u32); - hostdata->dsp_changed = 1; - return SPECIFIC_INT_NOTHING; - case A_int_err_unexpected_phase: - if (hostdata->options & OPTION_DEBUG_INTR) - printk ("scsi%d : unexpected phase\n", host->host_no); - return SPECIFIC_INT_ABORT; - case A_int_err_selected: - printk ("scsi%d : selected by target %d\n", host->host_no, - (int) NCR53c7x0_read8(SDID_REG_800) &7); - hostdata->dsp = hostdata->script + hostdata->E_target_abort / - sizeof(u32); - hostdata->dsp_changed = 1; - return SPECIFIC_INT_NOTHING; - case A_int_err_unexpected_reselect: - printk ("scsi%d : unexpected reselect by target %d lun %d\n", - host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & 7, - hostdata->reselected_identify & 7); - hostdata->dsp = hostdata->script + hostdata->E_initiator_abort / - sizeof(u32); - hostdata->dsp_changed = 1; - return SPECIFIC_INT_NOTHING; -/* - * Since contingent allegiance conditions are cleared by the next - * command issued to a target, we must issue a REQUEST SENSE - * command after receiving a CHECK CONDITION status, before - * another command is issued. - * - * Since this NCR53c7x0_cmd will be freed after use, we don't - * care if we step on the various fields, so modify a few things. - */ - case A_int_err_check_condition: -#if 0 - if (hostdata->options & OPTION_DEBUG_INTR) -#endif - printk ("scsi%d : CHECK CONDITION\n", host->host_no); - if (!c) { - printk("scsi%d : CHECK CONDITION with no SCSI command\n", - host->host_no); - return SPECIFIC_INT_PANIC; - } - - /* - * FIXME : this uses the normal one-byte selection message. - * We may want to renegotiate for synchronous & WIDE transfers - * since these could be the crux of our problem. - * - hostdata->NOP_insn* FIXME : once SCSI-II tagged queuing is implemented, we'll - * have to set this up so that the rest of the DSA - * agrees with this being an untagged queue'd command. - */ - - patch_dsa_32 (cmd->dsa, dsa_msgout, 0, le32_to_cpu(1)); - - /* - * Modify the table indirect for COMMAND OUT phase, since - * Request Sense is a six byte command. - */ - - patch_dsa_32 (cmd->dsa, dsa_cmdout, 0, le32_to_cpu(6)); - - c->cmnd[0] = REQUEST_SENSE; - c->cmnd[1] &= 0xe0; /* Zero all but LUN */ - c->cmnd[2] = 0; - c->cmnd[3] = 0; - c->cmnd[4] = sizeof(c->sense_buffer); - c->cmnd[5] = 0; - - /* - * Disable dataout phase, and program datain to transfer to the - * sense buffer, and add a jump to other_transfer after the - * command so overflow/underrun conditions are detected. - */ - - patch_dsa_32 (cmd->dsa, dsa_dataout, 0, - le32_to_cpu(virt_to_bus(hostdata->script) + hostdata->E_other_transfer)); - patch_dsa_32 (cmd->dsa, dsa_datain, 0, - le32_to_cpu(virt_to_bus(cmd->data_transfer_start))); - cmd->data_transfer_start[0] = le32_to_cpu((((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | - DCMD_BMI_IO)) << 24) | sizeof(c->sense_buffer)); - cmd->data_transfer_start[1] = (u32) le32_to_cpu(virt_to_bus(c->sense_buffer)); - - cmd->data_transfer_start[2] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) - << 24) | DBC_TCI_TRUE); - cmd->data_transfer_start[3] = (u32) le32_to_cpu(virt_to_bus(hostdata->script) + - hostdata->E_other_transfer); - - /* - * Currently, this command is flagged as completed, ie - * it has valid status and message data. Reflag it as - * incomplete. Q - need to do something so that original - * status, etc are used. - */ - - cmd->cmd->result = le32_to_cpu(0xffff); - - /* - * Restart command as a REQUEST SENSE. - */ - hostdata->dsp = (u32 *) hostdata->script + hostdata->E_select / - sizeof(u32); - hostdata->dsp_changed = 1; - return SPECIFIC_INT_NOTHING; - case A_int_debug_break: - return SPECIFIC_INT_BREAK; - case A_int_norm_aborted: - hostdata->dsp = (u32 *) hostdata->schedule; - hostdata->dsp_changed = 1; - if (cmd) - abnormal_finished (cmd, DID_ERROR << 16); - return SPECIFIC_INT_NOTHING; - case A_int_test_1: - case A_int_test_2: - hostdata->idle = 1; - hostdata->test_completed = (dsps - A_int_test_1) / 0x00010000 + 1; - if (hostdata->options & OPTION_DEBUG_INTR) - printk("scsi%d : test%d complete\n", host->host_no, - hostdata->test_completed); - return SPECIFIC_INT_NOTHING; -#ifdef A_int_debug_reselected_ok - case A_int_debug_reselected_ok: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR| - OPTION_DEBUG_DISCONNECT)) { - /* - * Note - this dsa is not based on location relative to - * the command structure, but to location relative to the - * DSA register - */ - u32 *dsa; - dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG)); - - printk("scsi%d : reselected_ok (DSA = 0x%x (virt 0x%p)\n", - host->host_no, NCR53c7x0_read32(DSA_REG), dsa); - printk("scsi%d : resume address is 0x%x (virt 0x%p)\n", - host->host_no, cmd->saved_data_pointer, - bus_to_virt(le32_to_cpu(cmd->saved_data_pointer))); - print_insn (host, hostdata->script + Ent_reselected_ok / - sizeof(u32), "", 1); - printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n", - host->host_no, NCR53c7x0_read8(SXFER_REG), - NCR53c7x0_read8(SCNTL3_REG_800)); - if (c) { - print_insn (host, (u32 *) - hostdata->sync[c->target].script, "", 1); - print_insn (host, (u32 *) - hostdata->sync[c->target].script + 2, "", 1); - } - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_reselect_check - case A_int_debug_reselect_check: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) { - u32 *dsa; -#if 0 - u32 *code; -#endif - /* - * Note - this dsa is not based on location relative to - * the command structure, but to location relative to the - * DSA register - */ - dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG)); - printk("scsi%d : reselected_check_next (DSA = 0x%lx (virt 0x%p))\n", - host->host_no, virt_to_bus(dsa), dsa); - if (dsa) { - printk("scsi%d : resume address is 0x%x (virt 0x%p)\n", - host->host_no, cmd->saved_data_pointer, - bus_to_virt (le32_to_cpu(cmd->saved_data_pointer))); -#if 0 - printk("scsi%d : template code :\n", host->host_no); - for (code = dsa + (Ent_dsa_code_check_reselect - Ent_dsa_zero) - / sizeof(u32); code < (dsa + Ent_dsa_zero / sizeof(u32)); - code += print_insn (host, code, "", 1)); -#endif - } - print_insn (host, hostdata->script + Ent_reselected_ok / - sizeof(u32), "", 1); - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_dsa_schedule - case A_int_debug_dsa_schedule: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) { - u32 *dsa; - /* - * Note - this dsa is not based on location relative to - * the command structure, but to location relative to the - * DSA register - */ - dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG)); - printk("scsi%d : dsa_schedule (old DSA = 0x%lx (virt 0x%p))\n", - host->host_no, virt_to_bus(dsa), dsa); - if (dsa) - printk("scsi%d : resume address is 0x%x (virt 0x%p)\n" - " (temp was 0x%x (virt 0x%p))\n", - host->host_no, cmd->saved_data_pointer, - bus_to_virt (le32_to_cpu(cmd->saved_data_pointer)), - NCR53c7x0_read32 (TEMP_REG), - bus_to_virt (NCR53c7x0_read32(TEMP_REG))); - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_scheduled - case A_int_debug_scheduled: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) { - printk("scsi%d : new I/O 0x%x (virt 0x%p) scheduled\n", - host->host_no, NCR53c7x0_read32(DSA_REG), - bus_to_virt(NCR53c7x0_read32(DSA_REG))); - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_idle - case A_int_debug_idle: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) { - printk("scsi%d : idle\n", host->host_no); - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_cmd - case A_int_debug_cmd: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) { - printk("scsi%d : command sent\n"); - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_dsa_loaded - case A_int_debug_dsa_loaded: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) { - printk("scsi%d : DSA loaded with 0x%x (virt 0x%p)\n", host->host_no, - NCR53c7x0_read32(DSA_REG), - bus_to_virt(NCR53c7x0_read32(DSA_REG))); - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_reselected - case A_int_debug_reselected: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR| - OPTION_DEBUG_DISCONNECT)) { - printk("scsi%d : reselected by target %d lun %d\n", - host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & ~0x80, - (int) hostdata->reselected_identify & 7); - print_queues(host); - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_disconnect_msg - case A_int_debug_disconnect_msg: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) { - if (c) - printk("scsi%d : target %d lun %d disconnecting\n", - host->host_no, c->target, c->lun); - else - printk("scsi%d : unknown target disconnecting\n", - host->host_no); - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_disconnected - case A_int_debug_disconnected: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR| - OPTION_DEBUG_DISCONNECT)) { - printk ("scsi%d : disconnected, new queues are\n", - host->host_no); - print_queues(host); -#if 0 - printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n", - host->host_no, NCR53c7x0_read8(SXFER_REG), - NCR53c7x0_read8(SCNTL3_REG_800)); -#endif - if (c) { - print_insn (host, (u32 *) - hostdata->sync[c->target].script, "", 1); - print_insn (host, (u32 *) - hostdata->sync[c->target].script + 2, "", 1); - } - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_panic - case A_int_debug_panic: - printk("scsi%d : int_debug_panic received\n", host->host_no); - print_lots (host); - return SPECIFIC_INT_PANIC; -#endif -#ifdef A_int_debug_saved - case A_int_debug_saved: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR| - OPTION_DEBUG_DISCONNECT)) { - printk ("scsi%d : saved data pointer 0x%x (virt 0x%p)\n", - host->host_no, cmd->saved_data_pointer, - bus_to_virt (le32_to_cpu(cmd->saved_data_pointer))); - print_progress (c); - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_restored - case A_int_debug_restored: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR| - OPTION_DEBUG_DISCONNECT)) { - if (cmd) { - int size; - printk ("scsi%d : restored data pointer 0x%x (virt 0x%p)\n", - host->host_no, cmd->saved_data_pointer, bus_to_virt ( - le32_to_cpu(cmd->saved_data_pointer))); - size = print_insn (host, (u32 *) - bus_to_virt(le32_to_cpu(cmd->saved_data_pointer)), "", 1); - size = print_insn (host, (u32 *) - bus_to_virt(le32_to_cpu(cmd->saved_data_pointer)) + size, "", 1); - print_progress (c); - } -#if 0 - printk ("scsi%d : datapath residual %d\n", - host->host_no, datapath_residual (host)) ; -#endif - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_sync - case A_int_debug_sync: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR| - OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) { - unsigned char sxfer = NCR53c7x0_read8 (SXFER_REG), - scntl3 = NCR53c7x0_read8 (SCNTL3_REG_800); - if (c) { - if (sxfer != hostdata->sync[c->target].sxfer_sanity || - scntl3 != hostdata->sync[c->target].scntl3_sanity) { - printk ("scsi%d : sync sanity check failed sxfer=0x%x, scntl3=0x%x", - host->host_no, sxfer, scntl3); - NCR53c7x0_write8 (SXFER_REG, sxfer); - NCR53c7x0_write8 (SCNTL3_REG_800, scntl3); - } - } else - printk ("scsi%d : unknown command sxfer=0x%x, scntl3=0x%x\n", - host->host_no, (int) sxfer, (int) scntl3); - } - return SPECIFIC_INT_RESTART; -#endif -#ifdef A_int_debug_datain - case A_int_debug_datain: - if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR| - OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) { - int size; - printk ("scsi%d : In do_datain (%s) sxfer=0x%x, scntl3=0x%x\n" - " datapath residual=%d\n", - host->host_no, sbcl_to_phase (NCR53c7x0_read8 (SBCL_REG)), - (int) NCR53c7x0_read8(SXFER_REG), - (int) NCR53c7x0_read8(SCNTL3_REG_800), - datapath_residual (host)) ; - print_insn (host, dsp, "", 1); - size = print_insn (host, (u32 *) bus_to_virt(le32_to_cpu(dsp[1])), "", 1); - print_insn (host, (u32 *) bus_to_virt(le32_to_cpu(dsp[1])) + size, "", 1); - } - return SPECIFIC_INT_RESTART; -#endif -/* - * FIXME : for 7xx support, we need to read SDID_REG_700 and handle - * the comparison as bitfielded, not binary. - */ -#ifdef A_int_debug_check_dsa - case A_int_debug_check_dsa: - if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) { - int sdid = NCR53c7x0_read8 (SDID_REG_800) & 15; - char *where = dsp - NCR53c7x0_insn_size(NCR53c7x0_read8 - (DCMD_REG)) == hostdata->script + - Ent_select_check_dsa / sizeof(u32) ? - "selection" : "reselection"; - if (c && sdid != c->target) { - printk ("scsi%d : SDID target %d != DSA target %d at %s\n", - host->host_no, sdid, c->target, where); - print_lots(host); - dump_events (host, 20); - return SPECIFIC_INT_PANIC; - } - } - return SPECIFIC_INT_RESTART; -#endif - default: - if ((dsps & 0xff000000) == 0x03000000) { - printk ("scsi%d : misc debug interrupt 0x%x\n", - host->host_no, dsps); - return SPECIFIC_INT_RESTART; - } else if ((dsps & 0xff000000) == 0x05000000) { - if (hostdata->events) { - struct NCR53c7x0_event *event; - ++hostdata->event_index; - if (hostdata->event_index >= hostdata->event_size) - hostdata->event_index = 0; - event = (struct NCR53c7x0_event *) hostdata->events + - hostdata->event_index; - event->event = (enum ncr_event) dsps; - event->dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG)); - /* FIXME : this needs to change for the '7xx family */ - if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) - event->target = NCR53c7x0_read8(SSID_REG_800); - else - event->target = 255; - - if (event->event == EVENT_RESELECT) - event->lun = hostdata->reselected_identify & 0xf; - else if (c) - event->lun = c->lun; - else - event->lun = 255; - do_gettimeofday(&(event->time)); - if (c) { - event->pid = c->pid; - memcpy ((void *) event->cmnd, (void *) c->cmnd, - sizeof (event->cmnd)); - } else { - event->pid = -1; - } - } - return SPECIFIC_INT_RESTART; - } - - printk ("scsi%d : unknown user interrupt 0x%x\n", - host->host_no, (unsigned) dsps); - return SPECIFIC_INT_PANIC; - } -} - -/* - * XXX - the stock NCR assembler won't output the scriptu.h file, - * which undefine's all #define'd CPP symbols from the script.h - * file, which will create problems if you use multiple scripts - * with the same symbol names. - * - * If you insist on using NCR's assembler, you could generate - * scriptu.h from script.h using something like - * - * grep #define script.h | \ - * sed 's/#define[ ][ ]*\([_a-zA-Z][_a-zA-Z0-9]*\).*$/#undefine \1/' \ - * > scriptu.h - */ - -#include "53c8xx_u.h" - -/* XXX - add alternate script handling code here */ - - -#ifdef NCR_DEBUG -/* - * Debugging without a debugger is no fun. So, I've provided - * a debugging interface in the NCR53c7x0 driver. To avoid - * kernel cruft, there's just enough here to act as an interface - * to a user level debugger (aka, GDB). - * - * - * The following restrictions apply to debugger commands : - * 1. The command must be terminated by a newline. - * 2. Command length must be less than 80 bytes including the - * newline. - * 3. The entire command must be written with one system call. - */ - -static const char debugger_help = -"bc - clear breakpoint\n" -"bl - list breakpoints\n" -"bs - set breakpoint\n" -"g - start\n" -"h - halt\n" -"? - this message\n" -"i - info\n" -"mp - print memory\n" -"ms - store memory\n" -"rp - print register\n" -"rs - store register\n" -"s - single step\n" -"tb - begin trace \n" -"te - end trace\n"; - -/* - * Whenever we change a break point, we should probably - * set the NCR up so that it is in a single step mode. - */ - -static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token, - u32 args[]) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - instance->hostdata; - struct NCR53c7x0_break *bp, **prev; - unsigned long flags; - save_flags(flags); - cli(); - for (bp = (struct NCR53c7x0_break *) instance->breakpoints, - prev = (struct NCR53c7x0_break **) &instance->breakpoints; - bp; prev = (struct NCR53c7x0_break **) &(bp->next), - bp = (struct NCR53c7x0_break *) bp->next); - - if (!bp) { - restore_flags(flags); - return -EIO; - } - - /* - * XXX - we need to insure that the processor is halted - * here in order to prevent a race condition. - */ - - memcpy ((void *) bp->addr, (void *) bp->old, sizeof(bp->old)); - if (prev) - *prev = bp->next; - - restore_flags(flags); - return 0; -} - - -static int -debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token, - u32 args[]) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - struct NCR53c7x0_break *bp; - char buf[80]; - size_t len; - unsigned long flags; - /* - * XXX - we need to insure that the processor is halted - * here in order to prevent a race condition. So, if the - * processor isn't halted, print an error message and continue. - */ - - sprintf (buf, "scsi%d : bp : warning : processor not halted\b", - host->host_no); - debugger_kernel_write (host, buf, strlen(buf)); - - save_flags(flags); - cli(); - for (bp = (struct NCR53c7x0_break *) host->breakpoints; - bp; bp = (struct NCR53c7x0_break *) bp->next) { - sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x", - bp->addr, bp->old[0], bp->old[1]); - len = strlen(buf); - if ((bp->old[0] & (DCMD_TYPE_MASK << 24)) == - (DCMD_TYPE_MMI << 24)) { - sprintf(buf + len, "%08x\n", * (u32 *) bp->addr); - } else { - sprintf(buf + len, "\n"); - } - len = strlen(buf); - debugger_kernel_write (host, buf, len); - } - restore_flags(flags); - return 0; -} - -static int -debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token, - u32 args[]) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - struct NCR53c7x0_break *bp; - char buf[80]; - size_t len; - unsigned long flags; - save_flags(flags); - cli(); - - if (hostdata->state != STATE_HALTED) { - sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no); - debugger_kernel_write (host, buf, strlen(buf)); - restore_flags(flags); - return -1; - } - - if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) { - printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n", - host->host_no, sizeof(struct NCR53c7x0_break)); - restore_flags(flags); - return -1; - } - - bp->address = (u32 *) args[0]; - memcpy ((void *) bp->old_instruction, (void *) bp->address, 8); - bp->old_size = (((bp->old_instruction[0] >> 24) & DCMD_TYPE_MASK) == - DCMD_TYPE_MMI ? 3 : 2; - bp->next = hostdata->breakpoints; - hostdata->breakpoints = bp->next; - memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8); - - restore_flags(flags); - return 0; -} - -#define TOKEN(name,nargs) {#name, nargs, debugger_fn_##name} -static const struct debugger_token { - char *name; - int numargs; - int (*fn)(struct debugger_token *token, u32 args[]); -} debugger_tokens[] = { - TOKEN(bc,1), TOKEN(bl,0), TOKEN(bs,1), TOKEN(g,0), TOKEN(halt,0), - {DT_help, "?", 0} , TOKEN(h,0), TOKEN(i,0), TOKEN(mp,2), - TOKEN(ms,3), TOKEN(rp,2), TOKEN(rs,2), TOKEN(s,0), TOKEN(tb,0), TOKEN(te,0) -}; - -#define NDT sizeof(debugger_tokens / sizeof(struct debugger_token)) - -static struct Scsi_Host * inode_to_host (struct inode *inode) { - int dev; - struct Scsi_Host *tmp; - for (dev = MINOR(inode->rdev), host = first_host; - (host->hostt == the_template); --dev, host = host->next) - if (!dev) return host; - return NULL; -} - - -static int -debugger_user_write (struct inode *inode,struct file *filp, - char *buf,int count) { - struct Scsi_Host *host; /* This SCSI host */ - struct NCR53c7x0_hostadata *hostdata; - char input_buf[80], /* Kernel space copy of buf */ - *ptr; /* Pointer to argument list */ - u32 args[3]; /* Arguments */ - int i, j, error, len; - - if (!(host = inode_to_host(inode))) - return -ENXIO; - - hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; - - if (error = verify_area(VERIFY_READ,buf,count)) - return error; - - if (count > 80) - return -EIO; - - memcpy_from_fs(input_buf, buf, count); - - if (input_buf[count - 1] != '\n') - return -EIO; - - input_buf[count - 1]=0; - - for (i = 0; i < NDT; ++i) { - len = strlen (debugger_tokens[i].name); - if (!strncmp(input_buf, debugger_tokens[i].name, len)) - break; - }; - - if (i == NDT) - return -EIO; - - for (ptr = input_buf + len, j = 0; j < debugger_tokens[i].nargs && *ptr;) { - if (*ptr == ' ' || *ptr == '\t') { - ++ptr; - } else if (isdigit(*ptr)) { - args[j++] = simple_strtoul (ptr, &ptr, 0); - } else { - return -EIO; - } - } - - if (j != debugger_tokens[i].nargs) - return -EIO; - - return count; -} - -static int -debugger_user_read (struct inode *inode,struct file *filp, - char *buf,int count) { - struct Scsi_Host *instance; - -} - -static int -debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t - buflen) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - int copy, left; - unsigned long flags; - save_flags(flags); - cli(); - while (buflen) { - left = (hostdata->debug_buf + hostdata->debug_size - 1) - - hostdata->debug_write; - copy = (buflen <= left) ? buflen : left; - memcpy (hostdata->debug_write, buf, copy); - buf += copy; - buflen -= copy; - hostdata->debug_count += copy; - if ((hostdata->debug_write += copy) == - (hostdata->debug_buf + hostdata->debug_size)) - hosdata->debug_write = hostdata->debug_buf; - } - restore_flags(flags); -} - -#endif /* def NCRDEBUG */ - -/* - * Function : static void NCR538xx_soft_reset (struct Scsi_Host *host) - * - * Purpose : perform a soft reset of the NCR53c8xx chip - * - * Inputs : host - pointer to this host adapter's structure - * - * Preconditions : NCR53c7x0_init must have been called for this - * host. - * - */ - -static void -NCR53c8x0_soft_reset (struct Scsi_Host *host) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - NCR53c7x0_local_setup(host); - - - /* - * Do a soft reset of the chip so that everything is - * reinitialized to the power-on state. - * - * Basically follow the procedure outlined in the NCR53c700 - * data manual under Chapter Six, How to Use, Steps Necessary to - * Start SCRIPTS, with the exception of actually starting the - * script and setting up the synchronous transfer gunk. - */ - - NCR53c7x0_write8(ISTAT_REG_800, ISTAT_10_SRST); - NCR53c7x0_write8(ISTAT_REG_800, 0); - NCR53c7x0_write8(hostdata->dmode, hostdata->saved_dmode & ~DMODE_MAN); - - - /* - * Respond to reselection by targets and use our _initiator_ SCSI ID - * for arbitration. If notyet, also respond to SCSI selection. - * - * XXX - Note : we must reprogram this when reselecting as - * a target. - */ - -#ifdef notyet - NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE|SCID_800_SRE); -#else - NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE); -#endif - NCR53c7x0_write8(RESPID_REG_800, hostdata->this_id_mask); - - /* - * Use a maximum (1.6) second handshake to handshake timeout, - * and SCSI recommended .5s selection timeout. - */ - - /* - * The new gcc won't recognize preprocessing directives - * within macro args. - */ -#if 0 - NCR53c7x0_write8(STIME0_REG_800, - ((selection_timeout << STIME0_800_SEL_SHIFT) & STIME0_800_SEL_MASK) - | ((15 << STIME0_800_HTH_SHIFT) & STIME0_800_HTH_MASK)); -#else -/* Disable HTH interrupt */ - NCR53c7x0_write8(STIME0_REG_800, - ((selection_timeout << STIME0_800_SEL_SHIFT) & STIME0_800_SEL_MASK)); -#endif - - - /* - * Enable active negation for happy synchronous transfers. - */ - - NCR53c7x0_write8(STEST3_REG_800, STEST3_800_TE); - - /* - * Enable all interrupts, except parity which we only want when - * the user requests it. - */ - - NCR53c7x0_write8(DIEN_REG, DIEN_800_MDPE | DIEN_800_BF | - DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_800_IID); - - - NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ? - SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA); - NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH); - - /* - * Use saved clock frequency divisor and scripts loaded in 16 bit - * mode flags from the saved dcntl. - */ - - NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl); - NCR53c7x0_write8(CTEST4_REG_800, hostdata->saved_ctest4); - - /* Enable active negation */ - NCR53c7x0_write8(STEST3_REG_800, STEST3_800_TE); -} - -/* - * Function static struct NCR53c7x0_cmd *allocate_cmd (Scsi_Cmnd *cmd) - * - * Purpose : Return the first free NCR53c7x0_cmd structure (which are - * reused in a LIFO manner to minimize cache thrashing). - * - * Side effects : If we haven't yet scheduled allocation of NCR53c7x0_cmd - * structures for this device, do so. Attempt to complete all scheduled - * allocations using kmalloc(), putting NCR53c7x0_cmd structures on - * the free list. Teach programmers not to drink and hack. - * - * Inputs : cmd - SCSI command - * - * Returns : NCR53c7x0_cmd structure allocated on behalf of cmd; - * NULL on failure. - */ - -static struct NCR53c7x0_cmd * -allocate_cmd (Scsi_Cmnd *cmd) { - struct Scsi_Host *host = cmd->host; - struct NCR53c7x0_hostdata *hostdata = - (struct NCR53c7x0_hostdata *) host->hostdata; - void *real; /* Real address */ - int size; /* Size of *tmp */ - struct NCR53c7x0_cmd *tmp; - unsigned long flags; - - if (hostdata->options & OPTION_DEBUG_ALLOCATION) - printk ("scsi%d : num_cmds = %d, can_queue = %d\n" - " target = %d, lun = %d, %s\n", - host->host_no, hostdata->num_cmds, host->can_queue, - cmd->target, cmd->lun, (hostdata->cmd_allocated[cmd->target] & - (1 << cmd->lun)) ? "already allocated" : "not allocated"); - -/* - * If we have not yet reserved commands for this I_T_L nexus, and - * the device exists (as indicated by permanent Scsi_Cmnd structures - * being allocated under 1.3.x, or being outside of scan_scsis in - * 1.2.x), do so now. - */ - if (!(hostdata->cmd_allocated[cmd->target] & (1 << cmd->lun)) && - cmd->device && cmd->device->has_cmdblocks - ) { - if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue) - hostdata->extra_allocate += host->cmd_per_lun; - hostdata->cmd_allocated[cmd->target] |= (1 << cmd->lun); - } - - for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate, - ++hostdata->num_cmds) { - /* historically, kmalloc has returned unaligned addresses; pad so we - have enough room to ROUNDUP */ - size = hostdata->max_cmd_size + sizeof (void *); -/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */ - real = kmalloc (size, GFP_ATOMIC); - if (!real) { - if (hostdata->options & OPTION_DEBUG_ALLOCATION) - printk ("scsi%d : kmalloc(%d) failed\n", - host->host_no, size); - break; - } - tmp = ROUNDUP(real, void *); - tmp->real = real; - tmp->size = size; - tmp->free = ((void (*)(void *, int)) kfree); - save_flags (flags); - cli(); - tmp->next = hostdata->free; - hostdata->free = tmp; - restore_flags (flags); - } - save_flags(flags); - cli(); - tmp = (struct NCR53c7x0_cmd *) hostdata->free; - if (tmp) { - hostdata->free = tmp->next; - } - restore_flags(flags); - if (!tmp) - printk ("scsi%d : can't allocate command for target %d lun %d\n", - host->host_no, cmd->target, cmd->lun); - return tmp; -} - -/* - * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) - * - * - * Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the - * Scsi_Cmnd structure passed in cmd, including dsa and Linux field - * initialization, and dsa code relocation. - * - * Inputs : cmd - SCSI command - * - * Returns : NCR53c7x0_cmd structure corresponding to cmd, - * NULL on failure. - */ - -static struct NCR53c7x0_cmd * -create_cmd (Scsi_Cmnd *cmd) { - NCR53c7x0_local_declare(); - struct Scsi_Host *host = cmd->host; - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - struct NCR53c7x0_cmd *tmp; /* NCR53c7x0_cmd structure for this command */ - int datain, /* Number of instructions per phase */ - dataout; - int data_transfer_instructions, /* Count of dynamic instructions */ - i; /* Counter */ - u32 *cmd_datain, /* Address of datain/dataout code */ - *cmd_dataout; /* Incremented as we assemble */ -#ifdef notyet - unsigned char *msgptr; /* Current byte in select message */ - int msglen; /* Length of whole select message */ -#endif - unsigned long flags; - NCR53c7x0_local_setup(cmd->host); - - if (!(tmp = allocate_cmd (cmd))) - return NULL; - - - /* - * Decide whether we need to generate commands for DATA IN, - * DATA OUT, neither, or both based on the SCSI command - */ - - switch (cmd->cmnd[0]) { - /* These commands do DATA IN */ - case INQUIRY: - case MODE_SENSE: - case READ_6: - case READ_10: - case READ_CAPACITY: - case REQUEST_SENSE: - datain = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3; - dataout = 0; - break; - /* These commands do DATA OUT */ - case MODE_SELECT: - case WRITE_6: - case WRITE_10: -#if 0 - printk("scsi%d : command is ", host->host_no); - print_command(cmd->cmnd); -#endif -#if 0 - printk ("scsi%d : %d scatter/gather segments\n", host->host_no, - cmd->use_sg); -#endif - datain = 0; - dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3; -#if 0 - hostdata->options |= OPTION_DEBUG_INTR; -#endif - break; - /* - * These commands do no data transfer, we should force an - * interrupt if a data phase is attempted on them. - */ - case START_STOP: /* also SCAN, which may do DATA OUT */ - case TEST_UNIT_READY: - datain = dataout = 0; - break; - /* - * We don't know about these commands, so generate code to handle - * both DATA IN and DATA OUT phases. - */ - default: - datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3; - } - - /* - * New code : so that active pointers work correctly regardless - * of where the saved data pointer is at, we want to immediately - * enter the dynamic code after selection, and on a non-data - * phase perform a CALL to the non-data phase handler, with - * returns back to this address. - * - * If a phase mismatch is encountered in the middle of a - * Block MOVE instruction, we want to _leave_ that instruction - * unchanged as the current case is, modify a temporary buffer, - * and point the active pointer (TEMP) at that. - * - * Furthermore, we want to implement a saved data pointer, - * set by the SAVE_DATA_POINTERs message. - * - * So, the data transfer segments will change to - * CALL data_transfer, WHEN NOT data phase - * MOVE x, x, WHEN data phase - * ( repeat ) - * JUMP other_transfer - */ - - data_transfer_instructions = datain + dataout; - - /* - * When we perform a request sense, we overwrite various things, - * including the data transfer code. Make sure we have enough - * space to do that. - */ - - if (data_transfer_instructions < 2) - data_transfer_instructions = 2; - - - /* - * The saved data pointer is set up so that a RESTORE POINTERS message - * will start the data transfer over at the beginning. - */ - - tmp->saved_data_pointer = le32_to_cpu(virt_to_bus (hostdata->script) + - hostdata->E_data_transfer); - - /* - * Initialize Linux specific fields. - */ - - tmp->cmd = cmd; - tmp->next = NULL; - tmp->flags = 0; - tmp->dsa_next_addr = le32_to_cpu(virt_to_bus(tmp->dsa) + hostdata->dsa_next - - hostdata->dsa_start); - tmp->dsa_addr = le32_to_cpu(virt_to_bus(tmp->dsa) - hostdata->dsa_start); - - /* - * Calculate addresses of dynamic code to fill in DSA - */ - - tmp->data_transfer_start = tmp->dsa + (hostdata->dsa_end - - hostdata->dsa_start) / sizeof(u32); - tmp->data_transfer_end = tmp->data_transfer_start + - 2 * data_transfer_instructions; - - cmd_datain = datain ? tmp->data_transfer_start : NULL; - cmd_dataout = dataout ? (datain ? cmd_datain + 2 * datain : tmp-> - data_transfer_start) : NULL; - - /* - * Fill in the NCR53c7x0_cmd structure as follows - * dsa, with fixed up DSA code - * datain code - * dataout code - */ - - /* Copy template code into dsa and perform all necessary fixups */ - if (hostdata->dsa_fixup) - hostdata->dsa_fixup(tmp); - - patch_dsa_32(tmp->dsa, dsa_next, 0, le32_to_cpu(0)); - patch_dsa_32(tmp->dsa, dsa_cmnd, 0, le32_to_cpu(virt_to_bus(cmd))); - - if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS) - if (hostdata->sync[cmd->target].select_indirect != - ((hostdata->sync[cmd->target].scntl3_sanity << 24) | - (cmd->target << 16) | - (hostdata->sync[cmd->target].sxfer_sanity << 8))) { - printk ("scsi%d : sanity check failed select_indirect=0x%x\n", - host->host_no, hostdata->sync[cmd->target].select_indirect); - FATAL(host); - - } - - patch_dsa_32(tmp->dsa, dsa_select, 0, le32_to_cpu(hostdata->sync[cmd->target]. - select_indirect)); - /* - * Right now, we'll do the WIDE and SYNCHRONOUS negotiations on - * different commands; although it should be trivial to do them - * both at the same time. - */ - if (hostdata->initiate_wdtr & (1 << cmd->target)) { - memcpy ((void *) (tmp->select + 1), (void *) wdtr_message, - sizeof(wdtr_message)); - patch_dsa_32(tmp->dsa, dsa_msgout, 0, le32_to_cpu(1 + sizeof(wdtr_message))); - save_flags(flags); - cli(); - hostdata->initiate_wdtr &= ~(1 << cmd->target); - restore_flags(flags); - } else if (hostdata->initiate_sdtr & (1 << cmd->target)) { - memcpy ((void *) (tmp->select + 1), (void *) sdtr_message, - sizeof(sdtr_message)); - patch_dsa_32(tmp->dsa, dsa_msgout, 0, le32_to_cpu(1 + sizeof(sdtr_message))); - tmp->flags |= CMD_FLAG_SDTR; - save_flags(flags); - cli(); - hostdata->initiate_sdtr &= ~(1 << cmd->target); - restore_flags(flags); - - } -#if 1 - else if (!(hostdata->talked_to & (1 << cmd->target)) && - !(hostdata->options & OPTION_NO_ASYNC)) { - memcpy ((void *) (tmp->select + 1), (void *) async_message, - sizeof(async_message)); - patch_dsa_32(tmp->dsa, dsa_msgout, 0, le32_to_cpu(1 + sizeof(async_message))); - tmp->flags |= CMD_FLAG_SDTR; - } -#endif - else - patch_dsa_32(tmp->dsa, dsa_msgout, 0, le32_to_cpu(1)); - hostdata->talked_to |= (1 << cmd->target); - tmp->select[0] = (hostdata->options & OPTION_DISCONNECT) ? - IDENTIFY (1, cmd->lun) : IDENTIFY (0, cmd->lun); - patch_dsa_32(tmp->dsa, dsa_msgout, 1, le32_to_cpu(virt_to_bus(tmp->select))); - patch_dsa_32(tmp->dsa, dsa_cmdout, 0, le32_to_cpu(cmd->cmd_len)); - patch_dsa_32(tmp->dsa, dsa_cmdout, 1, le32_to_cpu(virt_to_bus(cmd->cmnd))); - patch_dsa_32(tmp->dsa, dsa_dataout, 0, le32_to_cpu(cmd_dataout ? - virt_to_bus (cmd_dataout) - : virt_to_bus (hostdata->script) + hostdata->E_other_transfer)); - patch_dsa_32(tmp->dsa, dsa_datain, 0, le32_to_cpu(cmd_datain ? - virt_to_bus (cmd_datain) - : virt_to_bus (hostdata->script) + hostdata->E_other_transfer)); - /* - * XXX - need to make endian aware, should use separate variables - * for both status and message bytes. - */ - patch_dsa_32(tmp->dsa, dsa_msgin, 0, le32_to_cpu(1)); -/* - * FIXME : these only works for little endian. We probably want to - * provide message and status fields in the NCR53c7x0_cmd - * structure, and assign them to cmd->result when we're done. - */ - patch_dsa_32(tmp->dsa, dsa_msgin, 1, le32_to_cpu(virt_to_bus(&cmd->result) + 1)); - patch_dsa_32(tmp->dsa, dsa_status, 0, le32_to_cpu(1)); - patch_dsa_32(tmp->dsa, dsa_status, 1, le32_to_cpu(virt_to_bus(&cmd->result))); - patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, le32_to_cpu(1)); - patch_dsa_32(tmp->dsa, dsa_msgout_other, 1, - le32_to_cpu(virt_to_bus(&(hostdata->NCR53c7xx_msg_nop)))); - - /* - * Generate code for zero or more of the DATA IN, DATA OUT phases - * in the format - * - * CALL data_transfer, WHEN NOT phase - * MOVE first buffer length, first buffer address, WHEN phase - * ... - * MOVE last buffer length, last buffer address, WHEN phase - * JUMP other_transfer - */ - -/* - * See if we're getting to data transfer by generating an unconditional - * interrupt. - */ -#if 0 - if (datain) { - cmd_datain[0] = 0x98080000; - cmd_datain[1] = 0x03ffd00d; - cmd_datain += 2; - } -#endif - -/* - * XXX - I'm undecided whether all of this nonsense is faster - * in the long run, or whether I should just go and implement a loop - * on the NCR chip using table indirect mode? - * - * In any case, this is how it _must_ be done for 53c700/700-66 chips, - * so this stays even when we come up with something better. - * - * When we're limited to 1 simultaneous command, no overlapping processing, - * we're seeing 630K/sec, with 7% CPU usage on a slow Syquest 45M - * drive. - * - * Not bad, not good. We'll see. - */ - - for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4, - cmd_dataout += 4, ++i) { - u32 buf = cmd->use_sg ? - virt_to_bus(((struct scatterlist *)cmd->buffer)[i].address) : - virt_to_bus(cmd->request_buffer); - u32 count = cmd->use_sg ? - ((struct scatterlist *)cmd->buffer)[i].length : - cmd->request_bufflen; - - if (datain) { - /* CALL other_in, WHEN NOT DATA_IN */ - cmd_datain[0] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | - DCMD_TCI_IO) << 24) | - DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE); - cmd_datain[1] = le32_to_cpu(virt_to_bus (hostdata->script) + - hostdata->E_other_in); - /* MOVE count, buf, WHEN DATA_IN */ - cmd_datain[2] = le32_to_cpu(((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | DCMD_BMI_IO) - << 24) | count); - cmd_datain[3] = le32_to_cpu(buf); -#if 0 - print_insn (host, cmd_datain, "dynamic ", 1); - print_insn (host, cmd_datain + 2, "dynamic ", 1); -#endif - } - if (dataout) { - /* CALL other_out, WHEN NOT DATA_OUT */ - cmd_dataout[0] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL) << 24) | - DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE); - cmd_dataout[1] = le32_to_cpu(virt_to_bus(hostdata->script) + - hostdata->E_other_out); - /* MOVE count, buf, WHEN DATA+OUT */ - cmd_dataout[2] = le32_to_cpu(((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I) << 24) - | count); - cmd_dataout[3] = le32_to_cpu(buf); -#if 0 - print_insn (host, cmd_dataout, "dynamic ", 1); - print_insn (host, cmd_dataout + 2, "dynamic ", 1); -#endif - } - } - - /* - * Install JUMP instructions after the data transfer routines to return - * control to the do_other_transfer routines. - */ - - - if (datain) { - cmd_datain[0] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) | - DBC_TCI_TRUE); - cmd_datain[1] = le32_to_cpu(virt_to_bus(hostdata->script) + - hostdata->E_other_transfer); -#if 0 - print_insn (host, cmd_datain, "dynamic jump ", 1); -#endif - cmd_datain += 2; - } -#if 0 - if (datain) { - cmd_datain[0] = 0x98080000; - cmd_datain[1] = 0x03ffdeed; - cmd_datain += 2; - } -#endif - if (dataout) { - cmd_dataout[0] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) | - DBC_TCI_TRUE); - cmd_dataout[1] = le32_to_cpu(virt_to_bus(hostdata->script) + - hostdata->E_other_transfer); -#if 0 - print_insn (host, cmd_dataout, "dynamic jump ", 1); -#endif - cmd_dataout += 2; - } - return tmp; -} - -/* - * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd, - * void (*done)(Scsi_Cmnd *)) - * - * Purpose : enqueues a SCSI command - * - * Inputs : cmd - SCSI command, done - function called on completion, with - * a pointer to the command descriptor. - * - * Returns : 0 - * - * Side effects : - * cmd is added to the per instance driver issue_queue, with major - * twiddling done to the host specific fields of cmd. If the - * process_issue_queue coroutine isn't running, it is restarted. - * - * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to - * hold our own data, and pervert the ptr field of the SCp field - * to create a linked list. - */ - -int -NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) { - struct Scsi_Host *host = cmd->host; - struct NCR53c7x0_hostdata *hostdata = - (struct NCR53c7x0_hostdata *) host->hostdata; - unsigned long flags; - Scsi_Cmnd *tmp; - - cmd->scsi_done = done; - cmd->host_scribble = NULL; - cmd->SCp.ptr = NULL; - cmd->SCp.buffer = NULL; - - save_flags(flags); - cli(); - if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY)) - || ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) && - !(hostdata->debug_lun_limit[cmd->target] & (1 << cmd->lun))) - || cmd->target > host->max_id - || cmd->target == host->this_id - || hostdata->state == STATE_DISABLED) { - printk("scsi%d : disabled or bad target %d lun %d\n", host->host_no, - cmd->target, cmd->lun); - cmd->result = DID_BAD_TARGET << 16; - } else if ((hostdata->options & OPTION_DEBUG_NCOMMANDS_LIMIT) && - (hostdata->debug_count_limit == 0)) { - printk("scsi%d : maximum commands exceeded\n", host->host_no); - cmd->result = DID_BAD_TARGET << 16; - } else if (hostdata->options & OPTION_DEBUG_READ_ONLY) { - switch (cmd->cmnd[0]) { - case WRITE_6: - case WRITE_10: - printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n", - host->host_no); - cmd->result = DID_BAD_TARGET << 16; - } - } else { - if ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) && - hostdata->debug_count_limit != -1) - --hostdata->debug_count_limit; - restore_flags (flags); - cmd->result = le32_to_cpu(0xffff); /* The NCR will overwrite message - and status with valid data */ - cmd->host_scribble = (unsigned char *) tmp = create_cmd (cmd); - } - cli(); - /* - * REQUEST SENSE commands are inserted at the head of the queue - * so that we do not clear the contingent allegiance condition - * they may be looking at. - */ - - if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { - cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue; - hostdata->issue_queue = cmd; - } else { - for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr; - tmp = (Scsi_Cmnd *) tmp->SCp.ptr); - tmp->SCp.ptr = (unsigned char *) cmd; - } - restore_flags (flags); - run_process_issue_queue(); - return 0; -} - -/* - * Function : void to_schedule_list (struct Scsi_Host *host, - * struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd) - * - * Purpose : takes a SCSI command which was just removed from the - * issue queue, and deals with it by inserting it in the first - * free slot in the schedule list or by terminating it immediately. - * - * Inputs : - * host - SCSI host adapter; hostdata - hostdata structure for - * this adapter; cmd - a pointer to the command; should have - * the host_scribble field initialized to point to a valid - * - * Side effects : - * cmd is added to the per instance schedule list, with minor - * twiddling done to the host specific fields of cmd. - * - */ - -static __inline__ void -to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata, - struct NCR53c7x0_cmd *cmd) { - NCR53c7x0_local_declare(); - Scsi_Cmnd *tmp = cmd->cmd; - unsigned long flags; - /* dsa start is negative, so subtraction is used */ - volatile u32 *curr; - - int i; - NCR53c7x0_local_setup(host); -#if 0 - printk("scsi%d : new dsa is 0x%lx (virt 0x%p)\n", host->host_no, - virt_to_bus(dsa), dsa); -#endif - - save_flags(flags); - cli(); - - /* - * Work around race condition : if an interrupt fired and we - * got disabled forget about this command. - */ - - if (hostdata->state == STATE_DISABLED) { - printk("scsi%d : driver disabled\n", host->host_no); - tmp->result = DID_BAD_TARGET << 16; - cmd->next = (struct NCR53c7x0_cmd *) hostdata->free; - hostdata->free = cmd; - tmp->scsi_done(tmp); - restore_flags (flags); - return; - } - - for (i = host->can_queue, curr = hostdata->schedule; - i > 0 && curr[0] != hostdata->NOP_insn; - --i, curr += 2 /* JUMP instructions are two words */); - - if (i > 0) { - ++hostdata->busy[tmp->target][tmp->lun]; - cmd->next = hostdata->running_list; - hostdata->running_list = cmd; - - /* Restore this instruction to a NOP once the command starts */ - cmd->dsa [(hostdata->dsa_jump_dest - hostdata->dsa_start) / - sizeof(u32)] = (u32) le32_to_cpu(virt_to_bus ((void *)curr)); - /* Replace the current jump operand. */ - curr[1] = - le32_to_cpu(virt_to_bus ((void *) cmd->dsa) + hostdata->E_dsa_code_begin - - hostdata->E_dsa_code_template); - /* Replace the NOP instruction with a JUMP */ - curr[0] = le32_to_cpu(((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) | - DBC_TCI_TRUE); - } else { - printk ("scsi%d: no free slot\n", host->host_no); - disable(host); - tmp->result = DID_ERROR << 16; - cmd->next = (struct NCR53c7x0_cmd *) hostdata->free; - hostdata->free = cmd; - tmp->scsi_done(tmp); - restore_flags (flags); - return; - } - - /* - * If the NCR chip is in an idle state, start it running the scheduler - * immediately. Otherwise, signal the chip to jump to schedule as - * soon as it is idle. - */ - if (hostdata->idle) { - hostdata->idle = 0; - hostdata->state = STATE_RUNNING; - NCR53c7x0_write32 (DSP_REG, virt_to_bus ((void *)hostdata->schedule)); - } else { - NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP); - } - - restore_flags(flags); -} - -/* - * Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata - * *hostdata, Scsi_Cmnd *cmd) - * - * Purpose : decide if we can pass the given SCSI command on to the - * device in question or not. - * - * Returns : non-zero when we're busy, 0 when we aren't. - */ - -static __inline__ int -busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata, - Scsi_Cmnd *cmd) { - /* FIXME : in the future, this needs to accommodate SCSI-II tagged - queuing, and we may be able to play with fairness here a bit. - */ - return hostdata->busy[cmd->target][cmd->lun]; -} - -/* - * Function : process_issue_queue (void) - * - * Purpose : transfer commands from the issue queue to NCR start queue - * of each NCR53c7/8xx in the system, avoiding kernel stack - * overflows when the scsi_done() function is invoked recursively. - * - * NOTE : process_issue_queue exits with interrupts *disabled*, so the - * caller must reenable them if it desires. - * - * NOTE : process_issue_queue should be called from both - * NCR53c7x0_queue_command() and from the interrupt handler - * after command completion in case NCR53c7x0_queue_command() - * isn't invoked again but we've freed up resources that are - * needed. - */ - -static void -process_issue_queue (unsigned long flags) { - Scsi_Cmnd *tmp, *prev; - struct Scsi_Host *host; - struct NCR53c7x0_hostdata *hostdata; - int done; - - /* - * We run (with interrupts disabled) until we're sure that none of - * the host adapters have anything that can be done, at which point - * we set process_issue_queue_running to 0 and exit. - * - * Interrupts are enabled before doing various other internal - * instructions, after we've decided that we need to run through - * the loop again. - * - */ - - do { - cli(); /* Freeze request queues */ - done = 1; - for (host = first_host; host && host->hostt == the_template; - host = host->next) { - hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; - cli(); - if (hostdata->issue_queue) { - if (hostdata->state == STATE_DISABLED) { - tmp = (Scsi_Cmnd *) hostdata->issue_queue; - hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr; - tmp->result = DID_BAD_TARGET << 16; - if (tmp->host_scribble) { - ((struct NCR53c7x0_cmd *)tmp->host_scribble)->next = - hostdata->free; - hostdata->free = - (struct NCR53c7x0_cmd *)tmp->host_scribble; - tmp->host_scribble = NULL; - } - tmp->scsi_done (tmp); - done = 0; - } else - for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, - prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) - tmp->SCp.ptr) - if (!tmp->host_scribble || - !busyp (host, hostdata, tmp)) { - if (prev) - prev->SCp.ptr = tmp->SCp.ptr; - else - hostdata->issue_queue = (Scsi_Cmnd *) - tmp->SCp.ptr; - tmp->SCp.ptr = NULL; - if (tmp->host_scribble) { - if (hostdata->options & OPTION_DEBUG_QUEUES) - printk ("scsi%d : moving command for target %d lun %d to start list\n", - host->host_no, tmp->target, tmp->lun); - - - to_schedule_list (host, hostdata, - (struct NCR53c7x0_cmd *) - tmp->host_scribble); - } else { - tmp->result = le32_to_cpu(tmp->result); - if (((tmp->result & 0xff) == 0xff) || - ((tmp->result & 0xff00) == 0xff00)) { - printk ("scsi%d : danger Will Robinson!\n", - host->host_no); - tmp->result = DID_ERROR << 16; - disable (host); - } - tmp->scsi_done(tmp); - } - done = 0; - } /* if target/lun is not busy */ - } /* if hostdata->issue_queue */ - if (!done) - restore_flags (flags); - } /* for host */ - } while (!done); - process_issue_queue_running = 0; -} - -/* - * Function : static void intr_scsi (struct Scsi_Host *host, - * struct NCR53c7x0_cmd *cmd) - * - * Purpose : handle all SCSI interrupts, indicated by the setting - * of the SIP bit in the ISTAT register. - * - * Inputs : host, cmd - host and NCR command causing the interrupt, cmd - * may be NULL. - */ - -static void -intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_hostdata *hostdata = - (struct NCR53c7x0_hostdata *) host->hostdata; - unsigned char sstat0_sist0, sist1, /* Registers */ - fatal; /* Did a fatal interrupt - occur ? */ - - int is_8xx_chip; - NCR53c7x0_local_setup(host); - - fatal = 0; - - is_8xx_chip = ((unsigned) (hostdata->chip - 800)) < 100; - if (is_8xx_chip) { - sstat0_sist0 = NCR53c7x0_read8(SIST0_REG_800); - udelay(1); - sist1 = NCR53c7x0_read8(SIST1_REG_800); - } else { - sstat0_sist0 = NCR53c7x0_read8(SSTAT0_REG); - sist1 = 0; - } - - if (hostdata->options & OPTION_DEBUG_INTR) - printk ("scsi%d : SIST0 0x%0x, SIST1 0x%0x\n", host->host_no, - sstat0_sist0, sist1); - - /* 250ms selection timeout */ - if ((is_8xx_chip && (sist1 & SIST1_800_STO)) || - (!is_8xx_chip && (sstat0_sist0 & SSTAT0_700_STO))) { - fatal = 1; - if (hostdata->options & OPTION_DEBUG_INTR) { - printk ("scsi%d : Selection Timeout\n", host->host_no); - if (cmd) { - printk("scsi%d : target %d, lun %d, command ", - host->host_no, cmd->cmd->target, cmd->cmd->lun); - print_command (cmd->cmd->cmnd); - printk("scsi%d : dsp = 0x%x (virt 0x%p)\n", host->host_no, - NCR53c7x0_read32(DSP_REG), - bus_to_virt(NCR53c7x0_read32(DSP_REG))); - } else { - printk("scsi%d : no command\n", host->host_no); - } - } -/* - * XXX - question : how do we want to handle the Illegal Instruction - * interrupt, which may occur before or after the Selection Timeout - * interrupt? - */ - - if (1) { - hostdata->idle = 1; - hostdata->expecting_sto = 0; - - if (hostdata->test_running) { - hostdata->test_running = 0; - hostdata->test_completed = 3; - } else if (cmd) { - abnormal_finished(cmd, DID_BAD_TARGET << 16); - } -#if 0 - hostdata->intrs = 0; -#endif - } - } - -/* - * FIXME : in theory, we can also get a UDC when a STO occurs. - */ - if (sstat0_sist0 & SSTAT0_UDC) { - fatal = 1; - if (cmd) { - printk("scsi%d : target %d lun %d unexpected disconnect\n", - host->host_no, cmd->cmd->target, cmd->cmd->lun); - print_lots (host); - abnormal_finished(cmd, DID_ERROR << 16); - } else - printk("scsi%d : unexpected disconnect (no command)\n", - host->host_no); - - hostdata->dsp = (u32 *) hostdata->schedule; - hostdata->dsp_changed = 1; - } - - /* SCSI PARITY error */ - if (sstat0_sist0 & SSTAT0_PAR) { - fatal = 1; - if (cmd && cmd->cmd) { - printk("scsi%d : target %d lun %d parity error.\n", - host->host_no, cmd->cmd->target, cmd->cmd->lun); - abnormal_finished (cmd, DID_PARITY << 16); - } else - printk("scsi%d : parity error\n", host->host_no); - /* Should send message out, parity error */ - - /* XXX - Reduce synchronous transfer rate! */ - hostdata->dsp = hostdata->script + hostdata->E_initiator_abort / - sizeof(u32); - hostdata->dsp_changed = 1; - /* SCSI GROSS error */ - } - - if (sstat0_sist0 & SSTAT0_SGE) { - fatal = 1; - printk("scsi%d : gross error\n", host->host_no); - /* Reset SCSI offset */ - if ((hostdata->chip / 100) == 8) { - NCR53c7x0_write8 (STEST2_REG_800, STEST2_800_ROF); - } - - /* - * A SCSI gross error may occur when we have - * - * - A synchronous offset which causes the SCSI FIFO to be overwritten. - * - * - A REQ which causes the maximum synchronous offset programmed in - * the SXFER register to be exceeded. - * - * - A phase change with an outstanding synchronous offset. - * - * - Residual data in the synchronous data FIFO, with a transfer - * other than a synchronous receive is started.$# - */ - - - /* XXX Should deduce synchronous transfer rate! */ - hostdata->dsp = hostdata->script + hostdata->E_initiator_abort / - sizeof(u32); - hostdata->dsp_changed = 1; - /* Phase mismatch */ - } - - if (sstat0_sist0 & SSTAT0_MA) { - fatal = 1; - if (hostdata->options & OPTION_DEBUG_INTR) - printk ("scsi%d : SSTAT0_MA\n", host->host_no); - intr_phase_mismatch (host, cmd); - } - -#if 0 - if (sstat0_sist0 & SIST0_800_RSL) - printk ("scsi%d : Oh no Mr. Bill!\n", host->host_no); -#endif - -/* - * If a fatal SCSI interrupt occurs, we must insure that the DMA and - * SCSI FIFOs were flushed. - */ - - if (fatal) { - if (!hostdata->dstat_valid) { - hostdata->dstat = NCR53c7x0_read8(DSTAT_REG); - hostdata->dstat_valid = 1; - } - -/* XXX - code check for 700/800 chips */ - if (!(hostdata->dstat & DSTAT_DFE)) { - printk ("scsi%d : DMA FIFO not empty\n", host->host_no); - if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) { - printk ("scsi%d: Flushing DMA FIFO\n", - host->host_no); - NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF); - while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) & - DSTAT_DFE)); - } else { - NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF); - while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF); - } - hostdata->dstat |= DSTAT_DFE; - } - } -} - -/* - * Function : do_NCR53c7x0_intr() - * - * Purpose : A quick wrapper function added to grab the io_request_lock - * spin lock prior to entering the real interrupt handler. Needed - * for 2.1.95 and above. - */ -static void -do_NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs) { - unsigned long flags; - - struct Scsi_Host *dev = dev_id; - - spin_lock_irqsave(dev->host_lock, flags); - NCR53c7x0_intr(irq, dev_id, regs); - spin_unlock_irqrestore(dev->host_lock, flags); -} - -/* - * Function : static void NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) - * - * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing - * the same IRQ line. - * - * Inputs : Since we're using the SA_INTERRUPT interrupt handler - * semantics, irq indicates the interrupt which invoked - * this handler. - */ - -static void -NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) { - NCR53c7x0_local_declare(); - struct Scsi_Host *host; /* Host we are looking at */ - unsigned char istat; /* Values of interrupt regs */ - struct NCR53c7x0_hostdata *hostdata; /* host->hostdata */ - struct NCR53c7x0_cmd *cmd, /* command which halted */ - **cmd_prev_ptr; - u32 *dsa; /* DSA */ - int done = 1; /* Indicates when handler - should terminate */ - int interrupted = 0; /* This HA generated - an interrupt */ - int have_intfly; /* Don't print warning - messages when we stack - INTFLYs */ - unsigned long flags; - -#ifdef NCR_DEBUG - char buf[80]; /* Debugging sprintf buffer */ - size_t buflen; /* Length of same */ -#endif - do { - done = 1; - for (host = first_host; host; host = host->next) - if (host->hostt == the_template && host->irq == irq) { - NCR53c7x0_local_setup(host); - - hostdata = (struct NCR53c7x0_hostdata *) host->hostdata; - hostdata->dsp_changed = 0; - interrupted = 0; - have_intfly = 0; - - do { - int is_8xx_chip; - - hostdata->dstat_valid = 0; - interrupted = 0; - /* - * Only read istat once, since reading it again will unstack - * interrupts? - */ - istat = NCR53c7x0_read8(hostdata->istat); - - /* - * INTFLY interrupts are used by the NCR53c720, NCR53c810, - * and NCR53c820 to signify completion of a command. Since - * the SCSI processor continues running, we can't just look - * at the contents of the DSA register and continue running. - */ -/* XXX - this is too big, offends my sense of aesthetics, and should - move to intr_intfly() */ - is_8xx_chip = ((unsigned) (hostdata->chip - 800)) < 100; - if ((hostdata->options & OPTION_INTFLY) && - (is_8xx_chip && (istat & ISTAT_800_INTF))) { - char search_found = 0; /* Got at least one ? */ - done = 0; - interrupted = 1; - - /* - * Clear the INTF bit by writing a one. - * This reset operation is self-clearing. - */ - NCR53c7x0_write8(hostdata->istat, istat|ISTAT_800_INTF); - - if (hostdata->options & OPTION_DEBUG_INTR) - printk ("scsi%d : INTFLY\n", host->host_no); - - /* - * Traverse our list of running commands, and look - * for those with valid (non-0xff ff) status and message - * bytes encoded in the result which signify command - * completion. - */ - - - save_flags(flags); - cli(); -restart: - for (cmd_prev_ptr = (struct NCR53c7x0_cmd **) - &(hostdata->running_list), cmd = - (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ; - cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next), - cmd = (struct NCR53c7x0_cmd *) cmd->next) { - Scsi_Cmnd *tmp; - - if (!cmd) { - printk("scsi%d : very weird.\n", host->host_no); - break; - } - - if (!(tmp = cmd->cmd)) { - printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n", - host->host_no); - continue; - } -#if 0 - printk ("scsi%d : looking at result of 0x%x\n", - host->host_no, cmd->cmd->result); -#endif - -#ifdef __powerpc__ - if (tmp->result == le32_to_cpu(0xffff)) - continue; - tmp->result = le32_to_cpu(tmp->result); -#else - if (((tmp->result & 0xff) == 0xff) || - ((tmp->result & 0xff00) == 0xff00)) - continue; -#endif - - search_found = 1; - - /* Important - remove from list _before_ done is called */ - if (cmd_prev_ptr) - *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next; - - --hostdata->busy[tmp->target][tmp->lun]; - cmd->next = hostdata->free; - hostdata->free = cmd; - - tmp->host_scribble = NULL; - - if (hostdata->options & OPTION_DEBUG_INTR) { - printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ", - host->host_no, tmp->pid, tmp->target, tmp->lun, tmp->result); - print_command (tmp->cmnd); - } - -#if 0 - hostdata->options &= ~OPTION_DEBUG_INTR; -#endif - tmp->scsi_done(tmp); - goto restart; - - } - restore_flags(flags); - - /* - * I think that we're stacking INTFLY interrupts; taking care of - * all the finished commands on the first one, and then getting - * worried when we see the next one. The magic with have_intfly - * should tell if this is the case.. - */ - - if (!search_found && !have_intfly) { - printk ("scsi%d : WARNING : INTFLY with no completed commands.\n", - host->host_no); - } else if (!have_intfly) { - have_intfly = 1; - run_process_issue_queue(); - } - } - - if (istat & (ISTAT_SIP|ISTAT_DIP)) { - done = 0; - interrupted = 1; - hostdata->state = STATE_HALTED; - - if (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ? - SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) - printk ("scsi%d : SCSI FIFO not empty\n", - host->host_no); - - /* - * NCR53c700 and NCR53c700-66 change the current SCSI - * process, hostdata->curr, in the Linux driver so - * cmd = hostdata->curr. - * - * With other chips, we must look through the commands - * executing and find the command structure which - * corresponds to the DSA register. - */ - - if (hostdata->options & OPTION_700) { - cmd = (struct NCR53c7x0_cmd *) hostdata->curr; - } else { - dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG)); - for (cmd = (struct NCR53c7x0_cmd *) - hostdata->running_list; cmd && - (dsa + (hostdata->dsa_start / sizeof(u32))) != - cmd->dsa; - cmd = (struct NCR53c7x0_cmd *)(cmd->next)); - } - if (hostdata->options & OPTION_DEBUG_INTR) { - if (cmd) { - printk("scsi%d : interrupt for pid %lu, id %d, lun %d ", - host->host_no, cmd->cmd->pid, (int) cmd->cmd->target, - (int) cmd->cmd->lun); - print_command (cmd->cmd->cmnd); - } else { - printk("scsi%d : no active command\n", host->host_no); - } - } - if (istat & ISTAT_SIP) { - if (hostdata->options & OPTION_DEBUG_INTR) - printk ("scsi%d : ISTAT_SIP\n", host->host_no); - intr_scsi (host, cmd); - } - - if (istat & ISTAT_DIP) { - if (hostdata->options & OPTION_DEBUG_INTR) - printk ("scsi%d : ISTAT_DIP\n", host->host_no); - intr_dma (host, cmd); - } - - if (!hostdata->dstat_valid) { - hostdata->dstat = NCR53c7x0_read8(DSTAT_REG); - hostdata->dstat_valid = 1; - } - - /* XXX - code check for 700/800 chips */ - if (!(hostdata->dstat & DSTAT_DFE)) { - printk ("scsi%d : DMA FIFO not empty\n", host->host_no); - if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) { - printk ("scsi%d: Flushing DMA FIFO\n", - host->host_no); - NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF); - while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) & - DSTAT_DFE)); - } else - { - NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF); - while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF); - } - hostdata->dstat |= DSTAT_DFE; - } - } - } while (interrupted); - - - - if (hostdata->intrs != -1) - hostdata->intrs++; -#if 0 - if (hostdata->intrs > 40) { - printk("scsi%d : too many interrupts, halting", host->host_no); - disable(host); - } -#endif - - if (!hostdata->idle && hostdata->state == STATE_HALTED) { - if (!hostdata->dsp_changed) { - hostdata->dsp = (u32 *) - bus_to_virt(NCR53c7x0_read32(DSP_REG)); - } - -#if 0 - printk("scsi%d : new dsp is 0x%lx (virt 0x%p)\n", - host->host_no, virt_to_bus(hostdata->dsp), hostdata->dsp); -#endif - - hostdata->state = STATE_RUNNING; - NCR53c7x0_write32 (DSP_REG, virt_to_bus(hostdata->dsp)); - } - } - } while (!done); -} - - -/* - * Function : static int abort_connected (struct Scsi_Host *host) - * - * Purpose : Assuming that the NCR SCSI processor is currently - * halted, break the currently established nexus. Clean - * up of the NCR53c7x0_cmd and Scsi_Cmnd structures should - * be done on receipt of the abort interrupt. - * - * Inputs : host - SCSI host - * - */ - -static int -abort_connected (struct Scsi_Host *host) { -#ifdef NEW_ABORT - NCR53c7x0_local_declare(); -#endif - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; -/* FIXME : this probably should change for production kernels; at the - least, counter should move to a per-host structure. */ - static int counter = 5; -#ifdef NEW_ABORT - int sstat, phase, offset; - u32 *script; - NCR53c7x0_local_setup(host); -#endif - - if (--counter <= 0) { - disable(host); - return 0; - } - - printk ("scsi%d : DANGER : abort_connected() called \n", - host->host_no); - -#ifdef NEW_ABORT - -/* - * New strategy : Rather than using a generic abort routine, - * we'll specifically try to source or sink the appropriate - * amount of data for the phase we're currently in (taking into - * account the current synchronous offset) - */ - - sstat = (NCR53c8x0_read8 ((chip / 100) == 8 ? SSTAT1_REG : SSTAT2_REG); - offset = OFFSET (sstat & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT; - phase = sstat & SSTAT2_PHASE_MASK; - -/* - * SET ATN - * MOVE source_or_sink, WHEN CURRENT PHASE - * < repeat for each outstanding byte > - * JUMP send_abort_message - */ - - script = hostdata->abort_script = kmalloc ( - 8 /* instruction size */ * ( - 1 /* set ATN */ + - (!offset ? 1 : offset) /* One transfer per outstanding byte */ + - 1 /* send abort message */), - GFP_ATOMIC); - - -#else /* def NEW_ABORT */ - hostdata->dsp = hostdata->script + hostdata->E_initiator_abort / - sizeof(u32); -#endif /* def NEW_ABORT */ - hostdata->dsp_changed = 1; - -/* XXX - need to flag the command as aborted after the abort_connected - code runs - */ - return 0; -} - -/* - * Function : static int datapath_residual (Scsi_Host *host) - * - * Purpose : return residual data count of what's in the chip. - * - * Inputs : host - SCSI host - */ - -static int -datapath_residual (struct Scsi_Host *host) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - int count, synchronous, sstat; - NCR53c7x0_local_setup(host); - /* COMPAT : the 700 and 700-66 need to use DFIFO_00_BO_MASK */ - count = ((NCR53c7x0_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) - - (NCR53c7x0_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK; - synchronous = NCR53c7x0_read8 (SXFER_REG) & SXFER_MO_MASK; - /* COMPAT : DDIR is elsewhere on non-'8xx chips. */ - if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) { - /* Receive */ - if (synchronous) - count += (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ? - SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT; - else - if (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ? - SSTAT0_REG : SSTAT1_REG) & SSTAT1_ILF) - ++count; - } else { - /* Send */ - sstat = ((hostdata->chip / 100) == 8) ? NCR53c7x0_read8 (SSTAT0_REG) : - NCR53c7x0_read8 (SSTAT1_REG); - if (sstat & SSTAT1_OLF) - ++count; - if (synchronous && (sstat & SSTAT1_ORF)) - ++count; - } - return count; -} - -/* - * Function : static const char * sbcl_to_phase (int sbcl)_ - * - * Purpose : Convert SBCL register to user-parsable phase representation - * - * Inputs : sbcl - value of sbcl register - */ - - -static const char * -sbcl_to_phase (int sbcl) { - switch (sbcl & SBCL_PHASE_MASK) { - case SBCL_PHASE_DATAIN: - return "DATAIN"; - case SBCL_PHASE_DATAOUT: - return "DATAOUT"; - case SBCL_PHASE_MSGIN: - return "MSGIN"; - case SBCL_PHASE_MSGOUT: - return "MSGOUT"; - case SBCL_PHASE_CMDOUT: - return "CMDOUT"; - case SBCL_PHASE_STATIN: - return "STATUSIN"; - default: - return "unknown"; - } -} - -/* - * Function : static const char * sstat2_to_phase (int sstat)_ - * - * Purpose : Convert SSTAT2 register to user-parsable phase representation - * - * Inputs : sstat - value of sstat register - */ - - -static const char * -sstat2_to_phase (int sstat) { - switch (sstat & SSTAT2_PHASE_MASK) { - case SSTAT2_PHASE_DATAIN: - return "DATAIN"; - case SSTAT2_PHASE_DATAOUT: - return "DATAOUT"; - case SSTAT2_PHASE_MSGIN: - return "MSGIN"; - case SSTAT2_PHASE_MSGOUT: - return "MSGOUT"; - case SSTAT2_PHASE_CMDOUT: - return "CMDOUT"; - case SSTAT2_PHASE_STATIN: - return "STATUSIN"; - default: - return "unknown"; - } -} - -/* - * Function : static void intr_phase_mismatch (struct Scsi_Host *host, - * struct NCR53c7x0_cmd *cmd) - * - * Purpose : Handle phase mismatch interrupts - * - * Inputs : host, cmd - host and NCR command causing the interrupt, cmd - * may be NULL. - * - * Side effects : The abort_connected() routine is called or the NCR chip - * is restarted, jumping to the command_complete entry point, or - * patching the address and transfer count of the current instruction - * and calling the msg_in entry point as appropriate. - */ - -static void -intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) { - NCR53c7x0_local_declare(); - u32 dbc_dcmd, *dsp, *dsp_next; - unsigned char dcmd, sbcl; - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - int residual; - enum {ACTION_ABORT, ACTION_ABORT_PRINT, ACTION_CONTINUE} action = - ACTION_ABORT_PRINT; - const char *where = NULL; - NCR53c7x0_local_setup(host); - - /* - * Corrective action is based on where in the SCSI SCRIPT(tm) the error - * occurred, as well as which SCSI phase we are currently in. - */ - dsp_next = bus_to_virt(NCR53c7x0_read32(DSP_REG)); - - /* - * Fetch the current instruction, and remove the operands for easier - * interpretation. - */ - dbc_dcmd = NCR53c7x0_read32(DBC_REG); - dcmd = (dbc_dcmd & 0xff000000) >> 24; - /* - * Like other processors, the NCR adjusts the instruction pointer before - * instruction decode. Set the DSP address back to what it should - * be for this instruction based on its size (2 or 3 32 bit words). - */ - dsp = dsp_next - NCR53c7x0_insn_size(dcmd); - - - /* - * Read new SCSI phase from the SBCL lines. Since all of our code uses - * a WHEN conditional instead of an IF conditional, we don't need to - * wait for a new REQ. - */ - sbcl = NCR53c7x0_read8(SBCL_REG) & SBCL_PHASE_MASK; - - if (!cmd) { - action = ACTION_ABORT_PRINT; - where = "no current command"; - /* - * The way my SCSI SCRIPTS(tm) are architected, recoverable phase - * mismatches should only occur where we're doing a multi-byte - * BMI instruction. Specifically, this means - * - * - select messages (a SCSI-I target may ignore additional messages - * after the IDENTIFY; any target may reject a SDTR or WDTR) - * - * - command out (targets may send a message to signal an error - * condition, or go into STATUSIN after they've decided - * they don't like the command. - * - * - reply_message (targets may reject a multi-byte message in the - * middle) - * - * - data transfer routines (command completion with buffer space - * left, disconnect message, or error message) - */ - } else if (((dsp >= cmd->data_transfer_start && - dsp < cmd->data_transfer_end)) || dsp == (cmd->residual + 2)) { - if ((dcmd & (DCMD_TYPE_MASK|DCMD_BMI_OP_MASK|DCMD_BMI_INDIRECT| - DCMD_BMI_MSG|DCMD_BMI_CD)) == (DCMD_TYPE_BMI| - DCMD_BMI_OP_MOVE_I)) { - residual = datapath_residual (host); - if (hostdata->options & OPTION_DEBUG_DISCONNECT) - printk ("scsi%d : handling residual transfer (+ %d bytes from DMA FIFO)\n", - host->host_no, residual); - - /* - * The first instruction is a CALL to the alternate handler for - * this data transfer phase, so we can do calls to - * munge_msg_restart as we would if control were passed - * from normal dynamic code. - */ - if (dsp != cmd->residual + 2) { - cmd->residual[0] = le32_to_cpu(((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL | - ((dcmd & DCMD_BMI_IO) ? DCMD_TCI_IO : 0)) << 24) | - DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE); - cmd->residual[1] = le32_to_cpu(virt_to_bus(hostdata->script) - + ((dcmd & DCMD_BMI_IO) - ? hostdata->E_other_in : hostdata->E_other_out)); - } - - /* - * The second instruction is the a data transfer block - * move instruction, reflecting the pointer and count at the - * time of the phase mismatch. - */ - cmd->residual[2] = le32_to_cpu(dbc_dcmd + residual); - cmd->residual[3] = le32_to_cpu(NCR53c7x0_read32(DNAD_REG) - residual); - - /* - * The third and final instruction is a jump to the instruction - * which follows the instruction which had to be 'split' - */ - if (dsp != cmd->residual + 2) { - cmd->residual[4] = le32_to_cpu(((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) - << 24) | DBC_TCI_TRUE); - cmd->residual[5] = le32_to_cpu(virt_to_bus(dsp_next)); - } - - /* - * For the sake of simplicity, transfer control to the - * conditional CALL at the start of the residual buffer. - */ - hostdata->dsp = cmd->residual; - hostdata->dsp_changed = 1; - action = ACTION_CONTINUE; - } else { - where = "non-BMI dynamic DSA code"; - action = ACTION_ABORT_PRINT; - } - } else if (dsp == (hostdata->script + hostdata->E_select_msgout / 4)) { - /* Release ATN */ - NCR53c7x0_write8 (SOCL_REG, 0); - switch (sbcl) { - /* - * Some devices (SQ555 come to mind) grab the IDENTIFY message - * sent on selection, and decide to go into COMMAND OUT phase - * rather than accepting the rest of the messages or rejecting - * them. Handle these devices gracefully. - */ - case SBCL_PHASE_CMDOUT: - hostdata->dsp = dsp + 2 /* two _words_ */; - hostdata->dsp_changed = 1; - printk ("scsi%d : target %d ignored SDTR and went into COMMAND OUT\n", - host->host_no, cmd->cmd->target); - cmd->flags &= ~CMD_FLAG_SDTR; - action = ACTION_CONTINUE; - break; - case SBCL_PHASE_MSGIN: - hostdata->dsp = hostdata->script + hostdata->E_msg_in / - sizeof(u32); - hostdata->dsp_changed = 1; - action = ACTION_CONTINUE; - break; - default: - where="select message out"; - action = ACTION_ABORT_PRINT; - } - /* - * Some SCSI devices will interpret a command as they read the bytes - * off the SCSI bus, and may decide that the command is Bogus before - * they've read the entire command off the bus. - */ - } else if (dsp == hostdata->script + hostdata->E_cmdout_cmdout / sizeof - (u32)) { - hostdata->dsp = hostdata->script + hostdata->E_data_transfer / - sizeof (u32); - hostdata->dsp_changed = 1; - action = ACTION_CONTINUE; - /* FIXME : we need to handle message reject, etc. within msg_respond. */ -#ifdef notyet - } else if (dsp == hostdata->script + hostdata->E_reply_message) { - switch (sbcl) { - /* Any other phase mismatches abort the currently executing command. */ -#endif - } else { - where = "unknown location"; - action = ACTION_ABORT_PRINT; - } - - /* Flush DMA FIFO */ - if (!hostdata->dstat_valid) { - hostdata->dstat = NCR53c7x0_read8(DSTAT_REG); - hostdata->dstat_valid = 1; - } - if (!(hostdata->dstat & DSTAT_DFE)) { - if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) { - printk ("scsi%d: Flushing DMA FIFO\n", - host->host_no); - NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF); - /* FIXME : what about stacked DMA interrupts? */ - while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) & - DSTAT_DFE)); - } else { - NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF); - while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF); - } - hostdata->dstat |= DSTAT_DFE; - } - - switch (action) { - case ACTION_ABORT_PRINT: - printk("scsi%d : %s : unexpected phase %s.\n", - host->host_no, where ? where : "unknown location", - sbcl_to_phase(sbcl)); - print_lots (host); - /* Fall through to ACTION_ABORT */ - case ACTION_ABORT: - abort_connected (host); - break; - case ACTION_CONTINUE: - break; - } - -#if 0 - if (hostdata->dsp_changed) { - printk("scsi%d: new dsp 0x%p\n", host->host_no, hostdata->dsp); - print_insn (host, hostdata->dsp, "", 1); - } -#endif - -} - -/* - * Function : static void intr_bf (struct Scsi_Host *host, - * struct NCR53c7x0_cmd *cmd) - * - * Purpose : handle BUS FAULT interrupts - * - * Inputs : host, cmd - host and NCR command causing the interrupt, cmd - * may be NULL. - */ - -static void -intr_bf (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - u32 *dsp, - *next_dsp, /* Current dsp */ - *dsa, - dbc_dcmd; /* DCMD (high eight bits) + DBC */ - unsigned short pci_status; - int tmp; - unsigned long flags; - char *reason = NULL; - /* Default behavior is for a silent error, with a retry until we've - exhausted retries. */ - enum {MAYBE, ALWAYS, NEVER} retry = MAYBE; - int report = 0; - NCR53c7x0_local_setup(host); - - dbc_dcmd = NCR53c7x0_read32 (DBC_REG); - next_dsp = bus_to_virt (NCR53c7x0_read32(DSP_REG)); - dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff); -/* FIXME - check chip type */ - dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG)); - - /* - * Bus faults can be caused by either a Bad Address or - * Target Abort. We should check the Received Target Abort - * bit of the PCI status register and Master Abort Bit. - * - * - Master Abort bit indicates that no device claimed - * the address with DEVSEL within five clocks - * - * - Target Abort bit indicates that a target claimed it, - * but changed its mind once it saw the byte enables. - * - */ - - if ((hostdata->chip / 100) == 8) { - save_flags (flags); - cli(); - tmp = pci_read_config_word (hostdata->pcidev, PCI_STATUS, &pci_status); - restore_flags (flags); - if (tmp == PCIBIOS_SUCCESSFUL) { - if (pci_status & PCI_STATUS_REC_TARGET_ABORT) { - reason = "PCI target abort"; - pci_status &= ~PCI_STATUS_REC_TARGET_ABORT; - } else if (pci_status & PCI_STATUS_REC_MASTER_ABORT) { - reason = "No device asserted PCI DEVSEL within five bus clocks"; - pci_status &= ~PCI_STATUS_REC_MASTER_ABORT; - } else if (pci_status & PCI_STATUS_PARITY) { - report = 1; - pci_status &= ~PCI_STATUS_PARITY; - } - } else { - printk ("scsi%d : couldn't read status register : error %d\n", - host->host_no, tmp); - retry = NEVER; - } - } - -#ifndef notyet - report = 1; -#endif - if (report && reason) { - printk(KERN_ALERT "scsi%d : BUS FAULT reason = %s\n", - host->host_no, reason ? reason : "unknown"); - print_lots (host); - } - -#ifndef notyet - retry = NEVER; -#endif - - /* - * TODO : we should attempt to recover from any spurious bus - * faults. After X retries, we should figure that things are - * sufficiently wedged, and call NCR53c7xx_reset. - * - * This code should only get executed once we've decided that we - * cannot retry. - */ - - if (retry == NEVER) { - printk(KERN_ALERT " mail drew@PoohSticks.ORG\n"); - FATAL (host); - } -} - -/* - * Function : static void intr_dma (struct Scsi_Host *host, - * struct NCR53c7x0_cmd *cmd) - * - * Purpose : handle all DMA interrupts, indicated by the setting - * of the DIP bit in the ISTAT register. - * - * Inputs : host, cmd - host and NCR command causing the interrupt, cmd - * may be NULL. - */ - -static void -intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - unsigned char dstat; /* DSTAT */ - u32 *dsp, - *next_dsp, /* Current dsp */ - *dsa, - dbc_dcmd; /* DCMD (high eight bits) + DBC */ - int tmp; - unsigned long flags; - NCR53c7x0_local_setup(host); - - if (!hostdata->dstat_valid) { - hostdata->dstat = NCR53c7x0_read8(DSTAT_REG); - hostdata->dstat_valid = 1; - } - - dstat = hostdata->dstat; - - if (hostdata->options & OPTION_DEBUG_INTR) - printk("scsi%d : DSTAT=0x%x\n", host->host_no, (int) dstat); - - dbc_dcmd = NCR53c7x0_read32 (DBC_REG); - next_dsp = bus_to_virt(NCR53c7x0_read32(DSP_REG)); - dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff); -/* XXX - check chip type */ - dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG)); - - /* - * DSTAT_ABRT is the aborted interrupt. This is set whenever the - * SCSI chip is aborted. - * - * With NCR53c700 and NCR53c700-66 style chips, we should only - * get this when the chip is currently running the accept - * reselect/select code and we have set the abort bit in the - * ISTAT register. - * - */ - - if (dstat & DSTAT_ABRT) { -#if 0 - /* XXX - add code here to deal with normal abort */ - if ((hostdata->options & OPTION_700) && (hostdata->state == - STATE_ABORTING)) { - } else -#endif - { - printk(KERN_ALERT "scsi%d : unexpected abort interrupt at\n" - " ", host->host_no); - print_insn (host, dsp, KERN_ALERT "s ", 1); - FATAL (host); - } - } - - /* - * DSTAT_SSI is the single step interrupt. Should be generated - * whenever we have single stepped or are tracing. - */ - - if (dstat & DSTAT_SSI) { - if (hostdata->options & OPTION_DEBUG_TRACE) { - } else if (hostdata->options & OPTION_DEBUG_SINGLE) { - print_insn (host, dsp, "s ", 0); - save_flags(flags); - cli(); -/* XXX - should we do this, or can we get away with writing dsp? */ - - NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) & - ~DCNTL_SSM) | DCNTL_STD); - restore_flags(flags); - } else { - printk(KERN_ALERT "scsi%d : unexpected single step interrupt at\n" - " ", host->host_no); - print_insn (host, dsp, KERN_ALERT "", 1); - printk(KERN_ALERT " mail drew@PoohSticks.ORG\n"); - FATAL (host); - } - } - - /* - * DSTAT_IID / DSTAT_OPC (same bit, same meaning, only the name - * is different) is generated whenever an illegal instruction is - * encountered. - * - * XXX - we may want to emulate INTFLY here, so we can use - * the same SCSI SCRIPT (tm) for NCR53c710 through NCR53c810 - * chips. - */ - - if (dstat & DSTAT_OPC) { - /* - * Ascertain if this IID interrupts occurred before or after a STO - * interrupt. Since the interrupt handling code now leaves - * DSP unmodified until _after_ all stacked interrupts have been - * processed, reading the DSP returns the original DSP register. - * This means that if dsp lies between the select code, and - * message out following the selection code (where the IID interrupt - * would have to have occurred by due to the implicit wait for REQ), - * we have an IID interrupt resulting from a STO condition and - * can ignore it. - */ - - if (((dsp >= (hostdata->script + hostdata->E_select / sizeof(u32))) && - (dsp <= (hostdata->script + hostdata->E_select_msgout / - sizeof(u32) + 8))) || (hostdata->test_running == 2)) { - if (hostdata->options & OPTION_DEBUG_INTR) - printk ("scsi%d : ignoring DSTAT_IID for SSTAT_STO\n", - host->host_no); - if (hostdata->expecting_iid) { - hostdata->expecting_iid = 0; - hostdata->idle = 1; - if (hostdata->test_running == 2) { - hostdata->test_running = 0; - hostdata->test_completed = 3; - } else if (cmd) - abnormal_finished (cmd, DID_BAD_TARGET << 16); - } else { - hostdata->expecting_sto = 1; - } - /* - * We can't guarantee we'll be able to execute the WAIT DISCONNECT - * instruction within the 3.4us of bus free and arbitration delay - * that a target can RESELECT in and assert REQ after we've dropped - * ACK. If this happens, we'll get an illegal instruction interrupt. - * Doing away with the WAIT DISCONNECT instructions broke everything, - * so instead I'll settle for moving one WAIT DISCONNECT a few - * instructions closer to the CLEAR ACK before it to minimize the - * chances of this happening, and handle it if it occurs anyway. - * - * Simply continue with what we were doing, and control should - * be transferred to the schedule routine which will ultimately - * pass control onto the reselection or selection (not yet) - * code. - */ - } else if (dbc_dcmd == 0x48000000 && (NCR53c7x0_read8 (SBCL_REG) & - SBCL_REQ)) { - if (!(hostdata->options & OPTION_NO_PRINT_RACE)) - { - printk("scsi%d: REQ before WAIT DISCONNECT IID\n", - host->host_no); - hostdata->options |= OPTION_NO_PRINT_RACE; - } - } else { - printk(KERN_ALERT "scsi%d : illegal instruction\n", host->host_no); - print_lots (host); - printk(KERN_ALERT " mail drew@PoohSticks.ORG with ALL\n" - " boot messages and diagnostic output\n"); - FATAL (host); - } - } - - /* - * DSTAT_BF are bus fault errors - */ - - if (dstat & DSTAT_800_BF) { - intr_bf (host, cmd); - } - - - /* - * DSTAT_SIR interrupts are generated by the execution of - * the INT instruction. Since the exact values available - * are determined entirely by the SCSI script running, - * and are local to a particular script, a unique handler - * is called for each script. - */ - - if (dstat & DSTAT_SIR) { - if (hostdata->options & OPTION_DEBUG_INTR) - printk ("scsi%d : DSTAT_SIR\n", host->host_no); - switch ((tmp = hostdata->dstat_sir_intr (host, cmd))) { - case SPECIFIC_INT_NOTHING: - case SPECIFIC_INT_RESTART: - break; - case SPECIFIC_INT_ABORT: - abort_connected(host); - break; - case SPECIFIC_INT_PANIC: - printk(KERN_ALERT "scsi%d : failure at ", host->host_no); - print_insn (host, dsp, KERN_ALERT "", 1); - printk(KERN_ALERT " dstat_sir_intr() returned SPECIFIC_INT_PANIC\n"); - FATAL (host); - break; - case SPECIFIC_INT_BREAK: - intr_break (host, cmd); - break; - default: - printk(KERN_ALERT "scsi%d : failure at ", host->host_no); - print_insn (host, dsp, KERN_ALERT "", 1); - printk(KERN_ALERT" dstat_sir_intr() returned unknown value %d\n", - tmp); - FATAL (host); - } - } - - if ((hostdata->chip / 100) == 8 && (dstat & DSTAT_800_MDPE)) { - printk(KERN_ALERT "scsi%d : Master Data Parity Error\n", - host->host_no); - FATAL (host); - } -} - -/* - * Function : static int print_insn (struct Scsi_Host *host, - * u32 *insn, int kernel) - * - * Purpose : print numeric representation of the instruction pointed - * to by insn to the debugging or kernel message buffer - * as appropriate. - * - * If desired, a user level program can interpret this - * information. - * - * Inputs : host, insn - host, pointer to instruction, prefix - - * string to prepend, kernel - use printk instead of debugging buffer. - * - * Returns : size, in u32s, of instruction printed. - */ - -/* - * FIXME: should change kernel parameter so that it takes an ENUM - * specifying severity - either KERN_ALERT or KERN_PANIC so - * all panic messages are output with the same severity. - */ - -static int -print_insn (struct Scsi_Host *host, const u32 *insn, - const char *prefix, int kernel) { - char buf[160], /* Temporary buffer and pointer. ICKY - arbitrary length. */ - - - *tmp; - unsigned char dcmd; /* dcmd register for *insn */ - int size; - - /* - * Check to see if the instruction pointer is not bogus before - * indirecting through it; avoiding red-zone at start of - * memory. - * - * FIXME: icky magic needs to happen here on non-intel boxes which - * don't have kernel memory mapped in like this. Might be reasonable - * to use vverify()? - */ - - if (virt_to_phys((void *)insn) < PAGE_SIZE || - virt_to_phys((void *)(insn + 8)) > virt_to_phys(high_memory) || - ((((dcmd = (insn[0] >> 24) & 0xff) & DCMD_TYPE_MMI) == DCMD_TYPE_MMI) && - virt_to_phys((void *)(insn + 12)) > virt_to_phys(high_memory))) { - size = 0; - sprintf (buf, "%s%p: address out of range\n", - prefix, insn); - } else { -/* - * FIXME : (void *) cast in virt_to_bus should be unnecessary, because - * it should take const void * as argument. - */ - sprintf(buf, "%s0x%lx (virt 0x%p) : 0x%08x 0x%08x (virt 0x%p)", - (prefix ? prefix : ""), virt_to_bus((void *) insn), insn, - insn[0], insn[1], bus_to_virt (le32_to_cpu(insn[1]))); - tmp = buf + strlen(buf); - if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI) { - sprintf (tmp, " 0x%08x (virt 0x%p)\n", insn[2], - bus_to_virt(le32_to_cpu(insn[2]))); - size = 3; - } else { - sprintf (tmp, "\n"); - size = 2; - } - } - - if (kernel) - printk ("%s", buf); -#ifdef NCR_DEBUG - else { - size_t len = strlen(buf); - debugger_kernel_write(host, buf, len); - } -#endif - return size; -} - -/* - * Function : static const char *ncr_state (int state) - * - * Purpose : convert state (probably from hostdata->state) to a string - * - * Inputs : state - * - * Returns : char * representation of state, "unknown" on error. - */ - -#if 0 -static const char * -ncr_state (int state) { - switch (state) { - case STATE_HALTED: return "halted"; - case STATE_WAITING: return "waiting"; - case STATE_RUNNING: return "running"; - case STATE_ABORTING: return "aborting"; - case STATE_DISABLED: return "disabled"; - default: return "unknown"; - } -} -#endif - -/* - * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd) - * - * Purpose : Abort an errant SCSI command, doing all necessary - * cleanup of the issue_queue, running_list, shared Linux/NCR - * dsa issue and reconnect queues. - * - * Inputs : cmd - command to abort, code - entire result field - * - * Returns : 0 on success, -1 on failure. - */ - -int -NCR53c7xx_abort (Scsi_Cmnd *cmd) { - NCR53c7x0_local_declare(); - struct Scsi_Host *host = cmd->host; - struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *) - host->hostdata : NULL; - unsigned long flags; - unsigned long result; - struct NCR53c7x0_cmd *curr, **prev; - Scsi_Cmnd *me, **last; -#if 0 - static long cache_pid = -1; -#endif - - - if (!host) { - printk ("Bogus SCSI command pid %ld; no host structure\n", - cmd->pid); - return SCSI_ABORT_ERROR; - } else if (!hostdata) { - printk ("Bogus SCSI host %d; no hostdata\n", host->host_no); - return SCSI_ABORT_ERROR; - } - NCR53c7x0_local_setup(host); - -/* - * CHECK : I don't think that reading ISTAT will unstack any interrupts, - * since we need to write the INTF bit to clear it, and SCSI/DMA - * interrupts don't clear until we read SSTAT/SIST and DSTAT registers. - * - * See that this is the case. - * - * I suspect that several of our failures may be coming from a new fatal - * interrupt (possibly due to a phase mismatch) happening after we've left - * the interrupt handler, but before the PIC has had the interrupt condition - * cleared. - */ - - if (NCR53c7x0_read8(hostdata->istat) & - (ISTAT_DIP|ISTAT_SIP| - (hostdata->chip / 100 == 8 ? ISTAT_800_INTF : 0))) { - printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no, - cmd->pid); - NCR53c7x0_intr (host->irq, NULL, NULL); - return SCSI_ABORT_BUSY; - } - - save_flags(flags); - cli(); -#if 0 - if (cache_pid == cmd->pid) - panic ("scsi%d : bloody fetus %d\n", host->host_no, cmd->pid); - else - cache_pid = cmd->pid; -#endif - - -/* - * The command could be hiding in the issue_queue. This would be very - * nice, as commands can't be moved from the high level driver's issue queue - * into the shared queue until an interrupt routine is serviced, and this - * moving is atomic. - * - * If this is the case, we don't have to worry about anything - we simply - * pull the command out of the old queue, and call it aborted. - */ - - for (me = (Scsi_Cmnd *) hostdata->issue_queue, - last = (Scsi_Cmnd **) &(hostdata->issue_queue); - me && me != cmd; last = (Scsi_Cmnd **)&(me->SCp.ptr), - me = (Scsi_Cmnd *)me->SCp.ptr); - - if (me) { - *last = (Scsi_Cmnd *) me->SCp.ptr; - if (me->host_scribble) { - ((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free; - hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble; - me->host_scribble = NULL; - } - cmd->result = DID_ABORT << 16; - cmd->scsi_done(cmd); - printk ("scsi%d : found command %ld in Linux issue queue\n", - host->host_no, me->pid); - restore_flags(flags); - run_process_issue_queue(); - return SCSI_ABORT_SUCCESS; - } - -/* - * That failing, the command could be in our list of already executing - * commands. If this is the case, drastic measures are called for. - */ - - for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list, - prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list); - curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **) - &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next); - - if (curr) { - result = le32_to_cpu(cmd->result); - if ((result & 0xff) != 0xff && (result & 0xff00) != 0xff00) { - if (prev) - *prev = (struct NCR53c7x0_cmd *) curr->next; - curr->next = (struct NCR53c7x0_cmd *) hostdata->free; - cmd->host_scribble = NULL; - hostdata->free = curr; - cmd->scsi_done(cmd); - printk ("scsi%d : found finished command %ld in running list\n", - host->host_no, cmd->pid); - restore_flags(flags); - return SCSI_ABORT_NOT_RUNNING; - } else { - printk ("scsi%d : DANGER : command running, can not abort.\n", - cmd->host->host_no); - restore_flags(flags); - return SCSI_ABORT_BUSY; - } - } - -/* - * And if we couldn't find it in any of our queues, it must have been - * a dropped interrupt. - */ - - curr = (struct NCR53c7x0_cmd *) cmd->host_scribble; - if (curr) { - curr->next = hostdata->free; - hostdata->free = curr; - cmd->host_scribble = NULL; - } - - result = le32_to_cpu(cmd->result); - if (((result & 0xff00) == 0xff00) || - ((result & 0xff) == 0xff)) { - printk ("scsi%d : did this command ever run?\n", host->host_no); - cmd->result = DID_ABORT << 16; - } else { - printk ("scsi%d : probably lost INTFLY, normal completion\n", - host->host_no); -/* - * FIXME : We need to add an additional flag which indicates if a - * command was ever counted as BUSY, so if we end up here we can - * decrement the busy count if and only if it is necessary. - */ - --hostdata->busy[cmd->target][cmd->lun]; - } - restore_flags(flags); - cmd->scsi_done(cmd); - -/* - * We need to run process_issue_queue since termination of this command - * may allow another queued command to execute first? - */ - return SCSI_ABORT_NOT_RUNNING; -} - -/* - * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd) - * - * Purpose : perform a hard reset of the SCSI bus and NCR - * chip. - * - * Inputs : cmd - command which caused the SCSI RESET - * - * Returns : 0 on success. - */ - -int -NCR53c7xx_reset (Scsi_Cmnd *cmd, unsigned int reset_flags) { - NCR53c7x0_local_declare(); - unsigned long flags; - int found = 0; - struct NCR53c7x0_cmd * c; - Scsi_Cmnd *tmp; - /* - * When we call scsi_done(), it's going to wake up anything sleeping on the - * resources which were in use by the aborted commands, and we'll start to - * get new commands. - * - * We can't let this happen until after we've re-initialized the driver - * structures, and can't reinitialize those structures until after we've - * dealt with their contents. - * - * So, we need to find all of the commands which were running, stick - * them on a linked list of completed commands (we'll use the host_scribble - * pointer), do our reinitialization, and then call the done function for - * each command. - */ - Scsi_Cmnd *nuke_list = NULL; - struct Scsi_Host *host = cmd->host; - struct NCR53c7x0_hostdata *hostdata = - (struct NCR53c7x0_hostdata *) host->hostdata; - - NCR53c7x0_local_setup(host); - save_flags(flags); - cli(); - ncr_halt (host); - print_lots (host); - dump_events (host, 30); - ncr_scsi_reset (host); - for (tmp = nuke_list = return_outstanding_commands (host, 1 /* free */, - 0 /* issue */ ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer) - if (tmp == cmd) { - found = 1; - break; - } - - /* - * If we didn't find the command which caused this reset in our running - * list, then we've lost it. See that it terminates normally anyway. - */ - if (!found) { - c = (struct NCR53c7x0_cmd *) cmd->host_scribble; - if (c) { - cmd->host_scribble = NULL; - c->next = hostdata->free; - hostdata->free = c; - } else - printk ("scsi%d: lost command %ld\n", host->host_no, cmd->pid); - cmd->SCp.buffer = (struct scatterlist *) nuke_list; - nuke_list = cmd; - } - - NCR53c7x0_driver_init (host); - hostdata->soft_reset (host); - if (hostdata->resets == 0) - disable(host); - else if (hostdata->resets != -1) - --hostdata->resets; - restore_flags(flags); - for (; nuke_list; nuke_list = tmp) { - tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer; - nuke_list->result = DID_RESET << 16; - nuke_list->scsi_done (nuke_list); - } - restore_flags(flags); - return SCSI_RESET_SUCCESS; -} - -/* - * The NCR SDMS bios follows Annex A of the SCSI-CAM draft, and - * therefore shares the scsicam_bios_param function. - */ - -/* - * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) - * - * Purpose : convert instructions stored at NCR pointer into data - * pointer offset. - * - * Inputs : cmd - SCSI command; insn - pointer to instruction. Either current - * DSP, or saved data pointer. - * - * Returns : offset on success, -1 on failure. - */ - - -static int -insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) { - struct NCR53c7x0_hostdata *hostdata = - (struct NCR53c7x0_hostdata *) cmd->host->hostdata; - struct NCR53c7x0_cmd *ncmd = - (struct NCR53c7x0_cmd *) cmd->host_scribble; - int offset = 0, buffers; - struct scatterlist *segment; - char *ptr; - int found = 0; - -/* - * With the current code implementation, if the insn is inside dynamically - * generated code, the data pointer will be the instruction preceding - * the next transfer segment. - */ - - if (!check_address ((unsigned long) ncmd, sizeof (struct NCR53c7x0_cmd)) && - ((insn >= ncmd->data_transfer_start && - insn < ncmd->data_transfer_end) || - (insn >= ncmd->residual && - insn < (ncmd->residual + - sizeof(ncmd->residual))))) { - ptr = bus_to_virt(le32_to_cpu(insn[3])); - - if ((buffers = cmd->use_sg)) { - for (offset = 0, - segment = (struct scatterlist *) cmd->buffer; - buffers && !((found = ((ptr >= segment->address) && - (ptr < (segment->address + segment->length))))); - --buffers, offset += segment->length, ++segment) -#if 0 - printk("scsi%d: comparing 0x%p to 0x%p\n", - cmd->host->host_no, saved, segment->address); -#else - ; -#endif - offset += ptr - segment->address; - } else { - found = 1; - offset = ptr - (char *) (cmd->request_buffer); - } - } else if ((insn >= hostdata->script + - hostdata->E_data_transfer / sizeof(u32)) && - (insn <= hostdata->script + - hostdata->E_end_data_transfer / sizeof(u32))) { - found = 1; - offset = 0; - } - return found ? offset : -1; -} - - - -/* - * Function : void print_progress (Scsi_Cmnd *cmd) - * - * Purpose : print the current location of the saved data pointer - * - * Inputs : cmd - command we are interested in - * - */ - -static void -print_progress (Scsi_Cmnd *cmd) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_cmd *ncmd = - (struct NCR53c7x0_cmd *) cmd->host_scribble; - int offset, i; - char *where; - u32 *ptr; - NCR53c7x0_local_setup (cmd->host); - for (i = 0; i < 2; ++i) { - if (check_address ((unsigned long) ncmd, - sizeof (struct NCR53c7x0_cmd)) == -1) - continue; - if (!i) { - where = "saved"; - ptr = bus_to_virt(le32_to_cpu(ncmd->saved_data_pointer)); - } else { - where = "active"; - ptr = bus_to_virt (NCR53c7x0_read32 (DSP_REG) - - NCR53c7x0_insn_size (NCR53c7x0_read8 (DCMD_REG)) * - sizeof(u32)); - } - offset = insn_to_offset (cmd, ptr); - - if (offset != -1) - printk ("scsi%d : %s data pointer at offset %d\n", - cmd->host->host_no, where, offset); - else { - int size; - printk ("scsi%d : can't determine %s data pointer offset\n", - cmd->host->host_no, where); - if (ncmd) { - size = print_insn (cmd->host, - bus_to_virt(le32_to_cpu(ncmd->saved_data_pointer)), "", 1); - print_insn (cmd->host, - bus_to_virt(le32_to_cpu(ncmd->saved_data_pointer)) + size * sizeof(u32), - "", 1); - } - } - } -} - - -static void -print_dsa (struct Scsi_Host *host, u32 *dsa, const char *prefix) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - int i, len; - char *ptr; - Scsi_Cmnd *cmd; - - if (check_address ((unsigned long) dsa, hostdata->dsa_end - - hostdata->dsa_start) == -1) { - printk("scsi%d : bad dsa virt 0x%p\n", host->host_no, dsa); - return; - } - printk("%sscsi%d : dsa at phys 0x%lx (virt 0x%p)\n" - " + %d : dsa_msgout length = %u, data = 0x%x (virt 0x%p)\n" , - prefix ? prefix : "", - host->host_no, virt_to_bus (dsa), dsa, hostdata->dsa_msgout, - le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32)]), - le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32) + 1]), - bus_to_virt (le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32) + 1]))); - - /* - * Only print messages if they're sane in length so we don't - * blow the kernel printk buffer on something which won't buy us - * anything. - */ - - if (le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32)]) < - sizeof (hostdata->free->select)) - for (i = le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32)]), - ptr = bus_to_virt (le32_to_cpu(dsa[hostdata->dsa_msgout / sizeof(u32) + 1])); - i > 0 && !check_address ((unsigned long) ptr, 1); - ptr += len, i -= len) { - printk(" "); - len = print_msg (ptr); - printk("\n"); - if (!len) - break; - } - - printk(" + %d : select_indirect = 0x%x\n", - hostdata->dsa_select, le32_to_cpu(dsa[hostdata->dsa_select / sizeof(u32)])); - cmd = (Scsi_Cmnd *) bus_to_virt(le32_to_cpu(dsa[hostdata->dsa_cmnd / sizeof(u32)])); - printk(" + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd, - (u32) virt_to_bus(cmd)); - if (cmd) { - printk(" result = 0x%x, target = %d, lun = %d, cmd = ", - cmd->result, cmd->target, cmd->lun); - print_command(cmd->cmnd); - } else - printk("\n"); - printk(" + %d : dsa_next = 0x%x\n", hostdata->dsa_next, - le32_to_cpu(dsa[hostdata->dsa_next / sizeof(u32)])); - if (cmd) { - printk("scsi%d target %d : sxfer_sanity = 0x%x, scntl3_sanity = 0x%x\n" - " script : ", - host->host_no, cmd->target, - hostdata->sync[cmd->target].sxfer_sanity, - hostdata->sync[cmd->target].scntl3_sanity); - for (i = 0; i < (sizeof(hostdata->sync[cmd->target].script) / 4); ++i) - printk ("0x%x ", hostdata->sync[cmd->target].script[i]); - printk ("\n"); - print_progress (cmd); - } -} -/* - * Function : void print_queues (Scsi_Host *host) - * - * Purpose : print the contents of the NCR issue and reconnect queues - * - * Inputs : host - SCSI host we are interested in - * - */ - -static void -print_queues (struct Scsi_Host *host) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - u32 *dsa, *next_dsa; - volatile u32 *curr; - int left; - Scsi_Cmnd *cmd, *next_cmd; - unsigned long flags; - - printk ("scsi%d : issue queue\n", host->host_no); - - for (left = host->can_queue, cmd = (Scsi_Cmnd *) hostdata->issue_queue; - left >= 0 && cmd; - cmd = next_cmd) { - next_cmd = (Scsi_Cmnd *) cmd->SCp.ptr; - save_flags(flags); - cli(); - if (cmd->host_scribble) { - if (check_address ((unsigned long) (cmd->host_scribble), - sizeof (cmd->host_scribble)) == -1) - printk ("scsi%d: scsi pid %ld bad pointer to NCR53c7x0_cmd\n", - host->host_no, cmd->pid); - /* print_dsa does sanity check on address, no need to check */ - else - print_dsa (host, bus_to_virt(le32_to_cpu(((struct NCR53c7x0_cmd *) cmd->host_scribble)-> dsa)), ""); - } else - printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n", - host->host_no, cmd->pid, cmd->target, cmd->lun); - restore_flags(flags); - } - - if (left <= 0) { - printk ("scsi%d : loop detected in issue queue\n", - host->host_no); - } - - /* - * Traverse the NCR reconnect and start DSA structures, printing out - * each element until we hit the end or detect a loop. Currently, - * the reconnect structure is a linked list; and the start structure - * is an array. Eventually, the reconnect structure will become a - * list as well, since this simplifies the code. - */ - - printk ("scsi%d : schedule dsa array :\n", host->host_no); - for (left = host->can_queue, curr = hostdata->schedule; - left > 0; curr += 2, --left) - if (curr[0] != hostdata->NOP_insn) -/* FIXME : convert pointer to dsa_begin to pointer to dsa. */ - print_dsa (host, bus_to_virt (le32_to_cpu(curr[1]) - - (hostdata->E_dsa_code_begin - - hostdata->E_dsa_code_template)), ""); - printk ("scsi%d : end schedule dsa array\n", host->host_no); - - printk ("scsi%d : reconnect_dsa_head :\n", host->host_no); - - for (left = host->can_queue, - dsa = bus_to_virt (le32_to_cpu(hostdata->reconnect_dsa_head)); - left >= 0 && dsa; - dsa = next_dsa) { - save_flags (flags); - cli(); - if (check_address ((unsigned long) dsa, sizeof(dsa)) == -1) { - printk ("scsi%d: bad DSA pointer 0x%p", host->host_no, - dsa); - next_dsa = NULL; - } - else - { - next_dsa = bus_to_virt(le32_to_cpu(dsa[hostdata->dsa_next / sizeof(u32)])); - print_dsa (host, dsa, ""); - } - restore_flags(flags); - } - printk ("scsi%d : end reconnect_dsa_head\n", host->host_no); - if (left < 0) - printk("scsi%d: possible loop in ncr reconnect list\n", - host->host_no); -} - -static void -print_lots (struct Scsi_Host *host) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_hostdata *hostdata = - (struct NCR53c7x0_hostdata *) host->hostdata; - u32 *dsp_next, *dsp, *dsa, dbc_dcmd; - unsigned char dcmd, sbcl; - int i, size; - NCR53c7x0_local_setup(host); - - if ((dsp_next = bus_to_virt(NCR53c7x0_read32 (DSP_REG)))) { - dbc_dcmd = NCR53c7x0_read32(DBC_REG); - dcmd = (dbc_dcmd & 0xff000000) >> 24; - dsp = dsp_next - NCR53c7x0_insn_size(dcmd); - dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG)); - sbcl = NCR53c7x0_read8 (SBCL_REG); - - - printk ("scsi%d : DCMD|DBC=0x%x, DNAD=0x%x (virt 0x%p)\n" - " DSA=0x%lx (virt 0x%p)\n" - " DSPS=0x%x, TEMP=0x%x (virt 0x%p), DMODE=0x%x\n" - " SXFER=0x%x, SCNTL3=0x%x\n" - " %s%s%sphase=%s, %d bytes in SCSI FIFO\n" - " STEST0=0x%x\n", - host->host_no, dbc_dcmd, NCR53c7x0_read32(DNAD_REG), - bus_to_virt(NCR53c7x0_read32(DNAD_REG)), - virt_to_bus(dsa), dsa, - NCR53c7x0_read32(DSPS_REG), NCR53c7x0_read32(TEMP_REG), - bus_to_virt (NCR53c7x0_read32(TEMP_REG)), - (int) NCR53c7x0_read8(hostdata->dmode), - (int) NCR53c7x0_read8(SXFER_REG), - (int) NCR53c7x0_read8(SCNTL3_REG_800), - (sbcl & SBCL_BSY) ? "BSY " : "", - (sbcl & SBCL_SEL) ? "SEL " : "", - (sbcl & SBCL_REQ) ? "REQ " : "", - sstat2_to_phase(NCR53c7x0_read8 (((hostdata->chip / 100) == 8) ? - SSTAT1_REG : SSTAT2_REG)), - (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ? - SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT, - NCR53c7x0_read8 (STEST0_REG_800)); - printk ("scsi%d : DSP 0x%lx (virt 0x%p) ->\n", host->host_no, - virt_to_bus(dsp), dsp); - for (i = 6; i > 0; --i, dsp += size) - size = print_insn (host, dsp, "", 1); - if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) { - printk ("scsi%d : connected (SDID=0x%x, SSID=0x%x)\n", - host->host_no, NCR53c7x0_read8 (SDID_REG_800), - NCR53c7x0_read8 (SSID_REG_800)); - print_dsa (host, dsa, ""); - } - -#if 1 - print_queues (host); -#endif - } -} - -/* - * Function : static int shutdown (struct Scsi_Host *host) - * - * Purpose : does a clean (we hope) shutdown of the NCR SCSI - * chip. Use prior to dumping core, unloading the NCR driver, - * - * Returns : 0 on success - */ -static int -shutdown (struct Scsi_Host *host) { - NCR53c7x0_local_declare(); - unsigned long flags; - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - NCR53c7x0_local_setup(host); - save_flags (flags); - cli(); -/* Get in a state where we can reset the SCSI bus */ - ncr_halt (host); - ncr_scsi_reset (host); - hostdata->soft_reset(host); - - disable (host); - restore_flags (flags); - return 0; -} - -/* - * Function : void ncr_scsi_reset (struct Scsi_Host *host) - * - * Purpose : reset the SCSI bus. - */ - -static void -ncr_scsi_reset (struct Scsi_Host *host) { - NCR53c7x0_local_declare(); - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - unsigned long flags; - int sien = 0; - NCR53c7x0_local_setup(host); - save_flags (flags); - cli(); - if ((hostdata->chip / 100) == 8) { - sien = NCR53c7x0_read8(SIEN0_REG_800); - NCR53c7x0_write8(SIEN0_REG_800, sien & ~SIEN_RST); - } - NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST); - udelay(25); /* Minimum amount of time to assert RST */ - NCR53c7x0_write8(SCNTL1_REG, 0); - if ((hostdata->chip / 100) == 8) { - NCR53c7x0_write8(SIEN0_REG_800, sien); - } - restore_flags (flags); -} - -/* - * Function : void hard_reset (struct Scsi_Host *host) - * - */ - -static void -hard_reset (struct Scsi_Host *host) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - unsigned long flags; - save_flags (flags); - cli(); - ncr_scsi_reset(host); - NCR53c7x0_driver_init (host); - if (hostdata->soft_reset) - hostdata->soft_reset (host); - restore_flags(flags); -} - - -/* - * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host, - * int free, int issue) - * - * Purpose : return a linked list (using the SCp.buffer field as next, - * so we don't perturb hostdata. We don't use a field of the - * NCR53c7x0_cmd structure since we may not have allocated one - * for the command causing the reset.) of Scsi_Cmnd structures that - * had propagated below the Linux issue queue level. If free is set, - * free the NCR53c7x0_cmd structures which are associated with - * the Scsi_Cmnd structures, and clean up any internal - * NCR lists that the commands were on. If issue is set, - * also return commands in the issue queue. - * - * Returns : linked list of commands - * - * NOTE : the caller should insure that the NCR chip is halted - * if the free flag is set. - */ - -static Scsi_Cmnd * -return_outstanding_commands (struct Scsi_Host *host, int free, int issue) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - struct NCR53c7x0_cmd *c; - int i; - u32 *curr; - Scsi_Cmnd *list = NULL, *tmp; - for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c; - c = (struct NCR53c7x0_cmd *) c->next) { - if (c->cmd->SCp.buffer) { - printk ("scsi%d : loop detected in running list!\n", host->host_no); - break; - } else { - printk ("Duh? Bad things happening in the NCR driver\n"); - break; - } - - c->cmd->SCp.buffer = (struct scatterlist *) list; - list = c->cmd; - if (free) { - c->next = hostdata->free; - hostdata->free = c; - } - } - - if (free) { - for (i = 0, curr = (u32 *) hostdata->schedule; - i < host->can_queue; ++i, curr += 2) { - curr[0] = hostdata->NOP_insn; - curr[1] = le32_to_cpu(0xdeadbeef); - } - hostdata->curr = NULL; - } - - if (issue) { - for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; tmp = tmp->next) { - if (tmp->SCp.buffer) { - printk ("scsi%d : loop detected in issue queue!\n", - host->host_no); - break; - } - tmp->SCp.buffer = (struct scatterlist *) list; - list = tmp; - } - if (free) - hostdata->issue_queue = NULL; - - } - return list; -} - -/* - * Function : static int disable (struct Scsi_Host *host) - * - * Purpose : disables the given NCR host, causing all commands - * to return a driver error. Call this so we can unload the - * module during development and try again. Eventually, - * we should be able to find clean workarounds for these - * problems. - * - * Inputs : host - hostadapter to twiddle - * - * Returns : 0 on success. - */ - -static int -disable (struct Scsi_Host *host) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - unsigned long flags; - Scsi_Cmnd *nuke_list, *tmp; - save_flags(flags); - cli(); - if (hostdata->state != STATE_HALTED) - ncr_halt (host); - nuke_list = return_outstanding_commands (host, 1 /* free */, 1 /* issue */); - hard_reset (host); - hostdata->state = STATE_DISABLED; - restore_flags(flags); - printk ("scsi%d : nuking commands\n", host->host_no); - for (; nuke_list; nuke_list = tmp) { - tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer; - nuke_list->result = DID_ERROR << 16; - nuke_list->scsi_done(nuke_list); - } - printk ("scsi%d : done. \n", host->host_no); - printk (KERN_ALERT "scsi%d : disabled. Unload and reload\n", - host->host_no); - return 0; -} - -/* - * Function : static int ncr_halt (struct Scsi_Host *host) - * - * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip - * - * Inputs : host - SCSI chip to halt - * - * Returns : 0 on success - */ - -static int -ncr_halt (struct Scsi_Host *host) { - NCR53c7x0_local_declare(); - unsigned long flags; - unsigned char istat, tmp; - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - int stage; - NCR53c7x0_local_setup(host); - - save_flags(flags); - cli(); - /* Stage 0 : eat all interrupts - Stage 1 : set ABORT - Stage 2 : eat all but abort interrupts - Stage 3 : eat all interrupts - */ - for (stage = 0;;) { - if (stage == 1) { - NCR53c7x0_write8(hostdata->istat, ISTAT_ABRT); - ++stage; - } - istat = NCR53c7x0_read8 (hostdata->istat); - if (istat & ISTAT_SIP) { - if ((hostdata->chip / 100) == 8) { - tmp = NCR53c7x0_read8(SIST0_REG_800); - udelay(1); - tmp = NCR53c7x0_read8(SIST1_REG_800); - } else { - tmp = NCR53c7x0_read8(SSTAT0_REG); - } - } else if (istat & ISTAT_DIP) { - tmp = NCR53c7x0_read8(DSTAT_REG); - if (stage == 2) { - if (tmp & DSTAT_ABRT) { - NCR53c7x0_write8(hostdata->istat, 0); - ++stage; - } else { - printk(KERN_ALERT "scsi%d : could not halt NCR chip\n", - host->host_no); - disable (host); - } - } - } - if (!(istat & (ISTAT_SIP|ISTAT_DIP))) { - if (stage == 0) - ++stage; - else if (stage == 3) - break; - } - } - hostdata->state = STATE_HALTED; - restore_flags(flags); -#if 0 - print_lots (host); -#endif - return 0; -} - -/* - * Function: event_name (int event) - * - * Purpose: map event enum into user-readable strings. - */ - -static const char * -event_name (int event) { - switch (event) { - case EVENT_NONE: return "none"; - case EVENT_ISSUE_QUEUE: return "to issue queue"; - case EVENT_START_QUEUE: return "to start queue"; - case EVENT_SELECT: return "selected"; - case EVENT_DISCONNECT: return "disconnected"; - case EVENT_RESELECT: return "reselected"; - case EVENT_COMPLETE: return "completed"; - case EVENT_IDLE: return "idle"; - case EVENT_SELECT_FAILED: return "select failed"; - case EVENT_BEFORE_SELECT: return "before select"; - case EVENT_RESELECT_FAILED: return "reselect failed"; - default: return "unknown"; - } -} - -/* - * Function : void dump_events (struct Scsi_Host *host, count) - * - * Purpose : print last count events which have occurred. - */ -static void -dump_events (struct Scsi_Host *host, int count) { - struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *) - host->hostdata; - struct NCR53c7x0_event event; - int i; - unsigned long flags; - if (hostdata->events) { - if (count > hostdata->event_size) - count = hostdata->event_size; - for (i = hostdata->event_index; count > 0; - i = (i ? i - 1 : hostdata->event_size -1), --count) { - save_flags(flags); -/* - * By copying the event we're currently examining with interrupts - * disabled, we can do multiple printk(), etc. operations and - * still be guaranteed that they're happening on the same - * event structure. - */ - cli(); -#if 0 - event = hostdata->events[i]; -#else - memcpy ((void *) &event, (void *) &(hostdata->events[i]), - sizeof(event)); -#endif - - restore_flags(flags); - printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %d\n", - host->host_no, event_name (event.event), count, - (long) event.time.tv_sec, (long) event.time.tv_usec, - event.target, event.lun); - if (event.dsa) - printk (" event for dsa 0x%lx (virt 0x%p)\n", - virt_to_bus(event.dsa), event.dsa); - if (event.pid != -1) { - printk (" event for pid %ld ", event.pid); - print_command (event.cmnd); - } - } - } -} - -/* - * Function: check_address - * - * Purpose: Check to see if a possibly corrupt pointer will fault the - * kernel. - * - * Inputs: addr - address; size - size of area - * - * Returns: 0 if area is OK, -1 on error. - * - * NOTES: should be implemented in terms of vverify on kernels - * that have it. - */ - -static int -check_address (unsigned long addr, int size) { - return (virt_to_phys((void *)addr) < PAGE_SIZE || virt_to_phys((void *)(addr + size)) > virt_to_phys(high_memory) ? -1 : 0); -} - -#ifdef MODULE -int -NCR53c7x0_release(struct Scsi_Host *host) { - struct NCR53c7x0_hostdata *hostdata = - (struct NCR53c7x0_hostdata *) host->hostdata; - struct NCR53c7x0_cmd *cmd, *tmp; - shutdown (host); - if (host->irq != IRQ_NONE) - { - int irq_count; - struct Scsi_Host *tmp; - for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next) - if (tmp->hostt == the_template && tmp->irq == host->irq) - ++irq_count; - if (irq_count == 1) - free_irq(host->irq, NULL); - } - if (host->dma_channel != DMA_NONE) - free_dma(host->dma_channel); - if (host->io_port) - release_region(host->io_port, host->n_io_port); - - for (cmd = (struct NCR53c7x0_cmd *) hostdata->free; cmd; cmd = tmp, - --hostdata->num_cmds) { - tmp = (struct NCR53c7x0_cmd *) cmd->next; - /* - * If we're going to loop, try to stop it to get a more accurate - * count of the leaked commands. - */ - cmd->next = NULL; - if (cmd->free) - cmd->free ((void *) cmd->real, cmd->size); - } - if (hostdata->num_cmds) - printk ("scsi%d : leaked %d NCR53c7x0_cmd structures\n", - host->host_no, hostdata->num_cmds); - if (hostdata->events) - vfree ((void *)hostdata->events); - return 1; -} -#endif /* def MODULE */ -MODULE_LICENSE("GPL"); - -static Scsi_Host_Template driver_template = NCR53c7xx; -#include "scsi_module.c" diff -Nru a/drivers/scsi/53c7,8xx.h b/drivers/scsi/53c7,8xx.h --- a/drivers/scsi/53c7,8xx.h Sun Feb 9 21:13:34 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1529 +0,0 @@ -/* - * NCR 53c{7,8}0x0 driver, header file - * - * Sponsored by - * iX Multiuser Multitasking Magazine - * Hannover, Germany - * hm@ix.de - * - * Copyright 1993, 1994, 1995 Drew Eckhardt - * Visionary Computing - * (Unix and Linux consulting and custom programming) - * drew@PoohSticks.ORG - * +1 (303) 786-7975 - * - * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation. - * - * PRE-ALPHA - * - * For more information, please consult - * - * NCR 53C700/53C700-66 - * SCSI I/O Processor - * Data Manual - * - * NCR 53C810 - * PCI-SCSI I/O Processor - * Data Manual - * - * NCR Microelectronics - * 1635 Aeroplaza Drive - * Colorado Springs, CO 80916 - * +1 (719) 578-3400 - * - * Toll free literature number - * +1 (800) 334-5454 - * - */ - -#ifndef NCR53c7x0_H -#define NCR53c7x0_H -#include - -/* - * Prevent name space pollution in hosts.c, and only provide the - * define we need to get the NCR53c7x0 driver into the host template - * array. - */ - -#include - -extern int NCR53c7xx_abort(Scsi_Cmnd *); -extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt); -extern int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -extern int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int); -#ifdef MODULE -extern int NCR53c7xx_release(struct Scsi_Host *); -#else -#define NCR53c7xx_release NULL -#endif - -#define NCR53c7xx { \ - .name = "NCR53c{7,8}xx (rel 17)", \ - .detect = NCR53c7xx_detect, \ - .queuecommand = NCR53c7xx_queue_command, \ - .abort = NCR53c7xx_abort, \ - .reset = NCR53c7xx_reset, \ - .can_queue = 24, \ - .this_id = 7, \ - .sg_tablesize = 127, \ - .cmd_per_lun = 3, \ - .use_clustering = DISABLE_CLUSTERING} - -#ifndef HOSTS_C - -/* Register addresses, ordered numerically */ - -/* SCSI control 0 rw, default = 0xc0 */ -#define SCNTL0_REG 0x00 -#define SCNTL0_ARB1 0x80 /* 0 0 = simple arbitration */ -#define SCNTL0_ARB2 0x40 /* 1 1 = full arbitration */ -#define SCNTL0_STRT 0x20 /* Start Sequence */ -#define SCNTL0_WATN 0x10 /* Select with ATN */ -#define SCNTL0_EPC 0x08 /* Enable parity checking */ -/* Bit 2 is reserved on 800 series chips */ -#define SCNTL0_EPG_700 0x04 /* Enable parity generation */ -#define SCNTL0_AAP 0x02 /* ATN/ on parity error */ -#define SCNTL0_TRG 0x01 /* Target mode */ - -/* SCSI control 1 rw, default = 0x00 */ - -#define SCNTL1_REG 0x01 -#define SCNTL1_EXC 0x80 /* Extra Clock Cycle of Data setup */ -#define SCNTL1_ADB 0x40 /* contents of SODL on bus */ -#define SCNTL1_ESR_700 0x20 /* Enable SIOP response to selection - and reselection */ -#define SCNTL1_DHP_800 0x20 /* Disable halt on parity error or ATN - target mode only */ -#define SCNTL1_CON 0x10 /* Connected */ -#define SCNTL1_RST 0x08 /* SCSI RST/ */ -#define SCNTL1_AESP 0x04 /* Force bad parity */ -#define SCNTL1_SND_700 0x02 /* Start SCSI send */ -#define SCNTL1_IARB_800 0x02 /* Immediate Arbitration, start - arbitration immediately after - busfree is detected */ -#define SCNTL1_RCV_700 0x01 /* Start SCSI receive */ -#define SCNTL1_SST_800 0x01 /* Start SCSI transfer */ - -/* SCSI control 2 rw, */ - -#define SCNTL2_REG_800 0x02 -#define SCNTL2_800_SDU 0x80 /* SCSI disconnect unexpected */ - -/* SCSI control 3 rw */ - -#define SCNTL3_REG_800 0x03 -#define SCNTL3_800_SCF_SHIFT 4 -#define SCNTL3_800_SCF_MASK 0x70 -#define SCNTL3_800_SCF2 0x40 /* Synchronous divisor */ -#define SCNTL3_800_SCF1 0x20 /* 0x00 = SCLK/3 */ -#define SCNTL3_800_SCF0 0x10 /* 0x10 = SCLK/1 */ - /* 0x20 = SCLK/1.5 - 0x30 = SCLK/2 - 0x40 = SCLK/3 */ - -#define SCNTL3_800_CCF_SHIFT 0 -#define SCNTL3_800_CCF_MASK 0x07 -#define SCNTL3_800_CCF2 0x04 /* 0x00 50.01 to 66 */ -#define SCNTL3_800_CCF1 0x02 /* 0x01 16.67 to 25 */ -#define SCNTL3_800_CCF0 0x01 /* 0x02 25.01 - 37.5 - 0x03 37.51 - 50 - 0x04 50.01 - 66 */ - -/* - * SCSI destination ID rw - the appropriate bit is set for the selected - * target ID. This is written by the SCSI SCRIPTS processor. - * default = 0x00 - */ -#define SDID_REG_700 0x02 -#define SDID_REG_800 0x06 - -#define GP_REG_800 0x07 /* General purpose IO */ -#define GP_800_IO1 0x02 -#define GP_800_IO2 0x01 - - -/* SCSI interrupt enable rw, default = 0x00 */ -#define SIEN_REG_700 0x03 -#define SIEN0_REG_800 0x40 -#define SIEN_MA 0x80 /* Phase mismatch (ini) or ATN (tgt) */ -#define SIEN_FC 0x40 /* Function complete */ -#define SIEN_700_STO 0x20 /* Selection or reselection timeout */ -#define SIEN_800_SEL 0x20 /* Selected */ -#define SIEN_700_SEL 0x10 /* Selected or reselected */ -#define SIEN_800_RESEL 0x10 /* Reselected */ -#define SIEN_SGE 0x08 /* SCSI gross error */ -#define SIEN_UDC 0x04 /* Unexpected disconnect */ -#define SIEN_RST 0x02 /* SCSI RST/ received */ -#define SIEN_PAR 0x01 /* Parity error */ - -/* - * SCSI chip ID rw - * NCR53c700 : - * When arbitrating, the highest bit is used, when reselection or selection - * occurs, the chip responds to all IDs for which a bit is set. - * default = 0x00 - * NCR53c810 : - * Uses bit mapping - */ -#define SCID_REG 0x04 -/* Bit 7 is reserved on 800 series chips */ -#define SCID_800_RRE 0x40 /* Enable response to reselection */ -#define SCID_800_SRE 0x20 /* Enable response to selection */ -/* Bits four and three are reserved on 800 series chips */ -#define SCID_800_ENC_MASK 0x07 /* Encoded SCSI ID */ - -/* SCSI transfer rw, default = 0x00 */ -#define SXFER_REG 0x05 -#define SXFER_DHP 0x80 /* Disable halt on parity */ - -#define SXFER_TP2 0x40 /* Transfer period msb */ -#define SXFER_TP1 0x20 -#define SXFER_TP0 0x10 /* lsb */ -#define SXFER_TP_MASK 0x70 -/* FIXME : SXFER_TP_SHIFT == 5 is right for '8xx chips */ -#define SXFER_TP_SHIFT 5 -#define SXFER_TP_4 0x00 /* Divisors */ -#define SXFER_TP_5 0x10<<1 -#define SXFER_TP_6 0x20<<1 -#define SXFER_TP_7 0x30<<1 -#define SXFER_TP_8 0x40<<1 -#define SXFER_TP_9 0x50<<1 -#define SXFER_TP_10 0x60<<1 -#define SXFER_TP_11 0x70<<1 - -#define SXFER_MO3 0x08 /* Max offset msb */ -#define SXFER_MO2 0x04 -#define SXFER_MO1 0x02 -#define SXFER_MO0 0x01 /* lsb */ -#define SXFER_MO_MASK 0x0f -#define SXFER_MO_SHIFT 0 - -/* - * SCSI output data latch rw - * The contents of this register are driven onto the SCSI bus when - * the Assert Data Bus bit of the SCNTL1 register is set and - * the CD, IO, and MSG bits of the SOCL register match the SCSI phase - */ -#define SODL_REG_700 0x06 -#define SODL_REG_800 0x54 - - -/* - * SCSI output control latch rw, default = 0 - * Note that when the chip is being manually programmed as an initiator, - * the MSG, CD, and IO bits must be set correctly for the phase the target - * is driving the bus in. Otherwise no data transfer will occur due to - * phase mismatch. - */ - -#define SBCL_REG 0x0b -#define SBCL_REQ 0x80 /* REQ */ -#define SBCL_ACK 0x40 /* ACK */ -#define SBCL_BSY 0x20 /* BSY */ -#define SBCL_SEL 0x10 /* SEL */ -#define SBCL_ATN 0x08 /* ATN */ -#define SBCL_MSG 0x04 /* MSG */ -#define SBCL_CD 0x02 /* C/D */ -#define SBCL_IO 0x01 /* I/O */ -#define SBCL_PHASE_CMDOUT SBCL_CD -#define SBCL_PHASE_DATAIN SBCL_IO -#define SBCL_PHASE_DATAOUT 0 -#define SBCL_PHASE_MSGIN (SBCL_CD|SBCL_IO|SBCL_MSG) -#define SBCL_PHASE_MSGOUT (SBCL_CD|SBCL_MSG) -#define SBCL_PHASE_STATIN (SBCL_CD|SBCL_IO) -#define SBCL_PHASE_MASK (SBCL_CD|SBCL_IO|SBCL_MSG) - -/* - * SCSI first byte received latch ro - * This register contains the first byte received during a block MOVE - * SCSI SCRIPTS instruction, including - * - * Initiator mode Target mode - * Message in Command - * Status Message out - * Data in Data out - * - * It also contains the selecting or reselecting device's ID and our - * ID. - * - * Note that this is the register the various IF conditionals can - * operate on. - */ -#define SFBR_REG 0x08 - -/* - * SCSI input data latch ro - * In initiator mode, data is latched into this register on the rising - * edge of REQ/. In target mode, data is latched on the rising edge of - * ACK/ - */ -#define SIDL_REG_700 0x09 -#define SIDL_REG_800 0x50 - -/* - * SCSI bus data lines ro - * This register reflects the instantaneous status of the SCSI data - * lines. Note that SCNTL0 must be set to disable parity checking, - * otherwise reading this register will latch new parity. - */ -#define SBDL_REG_700 0x0a -#define SBDL_REG_800 0x58 - -#define SSID_REG_800 0x0a -#define SSID_800_VAL 0x80 /* Exactly two bits asserted at sel */ -#define SSID_800_ENCID_MASK 0x07 /* Device which performed operation */ - - -/* - * SCSI bus control lines rw, - * instantaneous readout of control lines - */ -#define SOCL_REG 0x0b -#define SOCL_REQ 0x80 /* REQ ro */ -#define SOCL_ACK 0x40 /* ACK ro */ -#define SOCL_BSY 0x20 /* BSY ro */ -#define SOCL_SEL 0x10 /* SEL ro */ -#define SOCL_ATN 0x08 /* ATN ro */ -#define SOCL_MSG 0x04 /* MSG ro */ -#define SOCL_CD 0x02 /* C/D ro */ -#define SOCL_IO 0x01 /* I/O ro */ -/* - * Synchronous SCSI Clock Control bits - * 0 - set by DCNTL - * 1 - SCLK / 1.0 - * 2 - SCLK / 1.5 - * 3 - SCLK / 2.0 - */ -#define SBCL_SSCF1 0x02 /* wo, -66 only */ -#define SBCL_SSCF0 0x01 /* wo, -66 only */ -#define SBCL_SSCF_MASK 0x03 - -/* - * XXX note : when reading the DSTAT and STAT registers to clear interrupts, - * insure that 10 clocks elapse between the two - */ -/* DMA status ro */ -#define DSTAT_REG 0x0c -#define DSTAT_DFE 0x80 /* DMA FIFO empty */ -#define DSTAT_800_MDPE 0x40 /* Master Data Parity Error */ -#define DSTAT_800_BF 0x20 /* Bus Fault */ -#define DSTAT_ABRT 0x10 /* Aborted - set on error */ -#define DSTAT_SSI 0x08 /* SCRIPTS single step interrupt */ -#define DSTAT_SIR 0x04 /* SCRIPTS interrupt received - - set when INT instruction is - executed */ -#define DSTAT_WTD 0x02 /* Watchdog timeout detected */ -#define DSTAT_OPC 0x01 /* Illegal instruction */ -#define DSTAT_800_IID 0x01 /* Same thing, different name */ - - -/* NCR53c800 moves this stuff into SIST0 */ -#define SSTAT0_REG 0x0d /* SCSI status 0 ro */ -#define SIST0_REG_800 0x42 -#define SSTAT0_MA 0x80 /* ini : phase mismatch, - * tgt : ATN/ asserted - */ -#define SSTAT0_CMP 0x40 /* function complete */ -#define SSTAT0_700_STO 0x20 /* Selection or reselection timeout */ -#define SIST0_800_SEL 0x20 /* Selected */ -#define SSTAT0_700_SEL 0x10 /* Selected or reselected */ -#define SIST0_800_RSL 0x10 /* Reselected */ -#define SSTAT0_SGE 0x08 /* SCSI gross error */ -#define SSTAT0_UDC 0x04 /* Unexpected disconnect */ -#define SSTAT0_RST 0x02 /* SCSI RST/ received */ -#define SSTAT0_PAR 0x01 /* Parity error */ - -/* And uses SSTAT0 for what was SSTAT1 */ - -#define SSTAT1_REG 0x0e /* SCSI status 1 ro */ -#define SSTAT1_ILF 0x80 /* SIDL full */ -#define SSTAT1_ORF 0x40 /* SODR full */ -#define SSTAT1_OLF 0x20 /* SODL full */ -#define SSTAT1_AIP 0x10 /* Arbitration in progress */ -#define SSTAT1_LOA 0x08 /* Lost arbitration */ -#define SSTAT1_WOA 0x04 /* Won arbitration */ -#define SSTAT1_RST 0x02 /* Instant readout of RST/ */ -#define SSTAT1_SDP 0x01 /* Instant readout of SDP/ */ - -#define SSTAT2_REG 0x0f /* SCSI status 2 ro */ -#define SSTAT2_FF3 0x80 /* number of bytes in synchronous */ -#define SSTAT2_FF2 0x40 /* data FIFO */ -#define SSTAT2_FF1 0x20 -#define SSTAT2_FF0 0x10 -#define SSTAT2_FF_MASK 0xf0 -#define SSTAT2_FF_SHIFT 4 - -/* - * Latched signals, latched on the leading edge of REQ/ for initiators, - * ACK/ for targets. - */ -#define SSTAT2_SDP 0x08 /* SDP */ -#define SSTAT2_MSG 0x04 /* MSG */ -#define SSTAT2_CD 0x02 /* C/D */ -#define SSTAT2_IO 0x01 /* I/O */ -#define SSTAT2_PHASE_CMDOUT SSTAT2_CD -#define SSTAT2_PHASE_DATAIN SSTAT2_IO -#define SSTAT2_PHASE_DATAOUT 0 -#define SSTAT2_PHASE_MSGIN (SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG) -#define SSTAT2_PHASE_MSGOUT (SSTAT2_CD|SSTAT2_MSG) -#define SSTAT2_PHASE_STATIN (SSTAT2_CD|SSTAT2_IO) -#define SSTAT2_PHASE_MASK (SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG) - - -/* NCR53c700-66 only */ -#define SCRATCHA_REG_00 0x10 /* through 0x13 Scratch A rw */ -/* NCR53c710 and higher */ -#define DSA_REG 0x10 /* DATA structure address */ - -#define CTEST0_REG_700 0x14 /* Chip test 0 ro */ -#define CTEST0_REG_800 0x18 /* Chip test 0 rw, general purpose */ -/* 0x80 - 0x04 are reserved */ -#define CTEST0_700_RTRG 0x02 /* Real target mode */ -#define CTEST0_700_DDIR 0x01 /* Data direction, 1 = - * SCSI bus to host, 0 = - * host to SCSI. - */ - -#define CTEST1_REG_700 0x15 /* Chip test 1 ro */ -#define CTEST1_REG_800 0x19 /* Chip test 1 ro */ -#define CTEST1_FMT3 0x80 /* Identify which byte lanes are empty */ -#define CTEST1_FMT2 0x40 /* in the DMA FIFO */ -#define CTEST1_FMT1 0x20 -#define CTEST1_FMT0 0x10 - -#define CTEST1_FFL3 0x08 /* Identify which bytes lanes are full */ -#define CTEST1_FFL2 0x04 /* in the DMA FIFO */ -#define CTEST1_FFL1 0x02 -#define CTEST1_FFL0 0x01 - -#define CTEST2_REG_700 0x16 /* Chip test 2 ro */ -#define CTEST2_REG_800 0x1a /* Chip test 2 ro */ - -#define CTEST2_800_DDIR 0x80 /* 1 = SCSI->host */ -#define CTEST2_800_SIGP 0x40 /* A copy of SIGP in ISTAT. - Reading this register clears */ -#define CTEST2_800_CIO 0x20 /* Configured as IO */. -#define CTEST2_800_CM 0x10 /* Configured as memory */ - -/* 0x80 - 0x40 are reserved on 700 series chips */ -#define CTEST2_700_SOFF 0x20 /* SCSI Offset Compare, - * As an initiator, this bit is - * one when the synchronous offset - * is zero, as a target this bit - * is one when the synchronous - * offset is at the maximum - * defined in SXFER - */ -#define CTEST2_700_SFP 0x10 /* SCSI FIFO parity bit, - * reading CTEST3 unloads a byte - * from the FIFO and sets this - */ -#define CTEST2_700_DFP 0x08 /* DMA FIFO parity bit, - * reading CTEST6 unloads a byte - * from the FIFO and sets this - */ -#define CTEST2_TEOP 0x04 /* SCSI true end of process, - * indicates a totally finished - * transfer - */ -#define CTEST2_DREQ 0x02 /* Data request signal */ -/* 0x01 is reserved on 700 series chips */ -#define CTEST2_800_DACK 0x01 - -/* - * Chip test 3 ro - * Unloads the bottom byte of the eight deep SCSI synchronous FIFO, - * check SSTAT2 FIFO full bits to determine size. Note that a GROSS - * error results if a read is attempted on this register. Also note - * that 16 and 32 bit reads of this register will cause corruption. - */ -#define CTEST3_REG_700 0x17 -/* Chip test 3 rw */ -#define CTEST3_REG_800 0x1b -#define CTEST3_800_V3 0x80 /* Chip revision */ -#define CTEST3_800_V2 0x40 -#define CTEST3_800_V1 0x20 -#define CTEST3_800_V0 0x10 -#define CTEST3_800_FLF 0x08 /* Flush DMA FIFO */ -#define CTEST3_800_CLF 0x04 /* Clear DMA FIFO */ -#define CTEST3_800_FM 0x02 /* Fetch mode pin */ -/* bit 0 is reserved on 800 series chips */ - -#define CTEST4_REG_700 0x18 /* Chip test 4 rw */ -#define CTEST4_REG_800 0x21 /* Chip test 4 rw */ -/* 0x80 is reserved on 700 series chips */ -#define CTEST4_800_BDIS 0x80 /* Burst mode disable */ -#define CTEST4_ZMOD 0x40 /* High impedance mode */ -#define CTEST4_SZM 0x20 /* SCSI bus high impedance */ -#define CTEST4_700_SLBE 0x10 /* SCSI loopback enabled */ -#define CTEST4_800_SRTM 0x10 /* Shadow Register Test Mode */ -#define CTEST4_700_SFWR 0x08 /* SCSI FIFO write enable, - * redirects writes from SODL - * to the SCSI FIFO. - */ -#define CTEST4_800_MPEE 0x08 /* Enable parity checking - during master cycles on PCI - bus */ - -/* - * These bits send the contents of the CTEST6 register to the appropriate - * byte lane of the 32 bit DMA FIFO. Normal operation is zero, otherwise - * the high bit means the low two bits select the byte lane. - */ -#define CTEST4_FBL2 0x04 -#define CTEST4_FBL1 0x02 -#define CTEST4_FBL0 0x01 -#define CTEST4_FBL_MASK 0x07 -#define CTEST4_FBL_0 0x04 /* Select DMA FIFO byte lane 0 */ -#define CTEST4_FBL_1 0x05 /* Select DMA FIFO byte lane 1 */ -#define CTEST4_FBL_2 0x06 /* Select DMA FIFO byte lane 2 */ -#define CTEST4_FBL_3 0x07 /* Select DMA FIFO byte lane 3 */ -#define CTEST4_800_SAVE (CTEST4_800_BDIS) - - -#define CTEST5_REG_700 0x19 /* Chip test 5 rw */ -#define CTEST5_REG_800 0x22 /* Chip test 5 rw */ -/* - * Clock Address Incrementor. When set, it increments the - * DNAD register to the next bus size boundary. It automatically - * resets itself when the operation is complete. - */ -#define CTEST5_ADCK 0x80 -/* - * Clock Byte Counter. When set, it decrements the DBC register to - * the next bus size boundary. - */ -#define CTEST5_BBCK 0x40 -/* - * Reset SCSI Offset. Setting this bit to 1 clears the current offset - * pointer in the SCSI synchronous offset counter (SSTAT). This bit - * is set to 1 if a SCSI Gross Error Condition occurs. The offset should - * be cleared when a synchronous transfer fails. When written, it is - * automatically cleared after the SCSI synchronous offset counter is - * reset. - */ -/* Bit 5 is reserved on 800 series chips */ -#define CTEST5_700_ROFF 0x20 -/* - * Master Control for Set or Reset pulses. When 1, causes the low - * four bits of register to set when set, 0 causes the low bits to - * clear when set. - */ -#define CTEST5_MASR 0x10 -#define CTEST5_DDIR 0x08 /* DMA direction */ -/* - * Bits 2-0 are reserved on 800 series chips - */ -#define CTEST5_700_EOP 0x04 /* End of process */ -#define CTEST5_700_DREQ 0x02 /* Data request */ -#define CTEST5_700_DACK 0x01 /* Data acknowledge */ - -/* - * Chip test 6 rw - writing to this register writes to the byte - * lane in the DMA FIFO as determined by the FBL bits in the CTEST4 - * register. - */ -#define CTEST6_REG_700 0x1a -#define CTEST6_REG_800 0x23 - -#define CTEST7_REG 0x1b /* Chip test 7 rw */ -/* 0x80 - 0x40 are reserved on NCR53c700 and NCR53c700-66 chips */ -#define CTEST7_10_CDIS 0x80 /* Cache burst disable */ -#define CTEST7_10_SC1 0x40 /* Snoop control bits */ -#define CTEST7_10_SC0 0x20 -#define CTEST7_10_SC_MASK 0x60 -/* 0x20 is reserved on the NCR53c700 */ -#define CTEST7_0060_FM 0x20 /* Fetch mode */ -#define CTEST7_STD 0x10 /* Selection timeout disable */ -#define CTEST7_DFP 0x08 /* DMA FIFO parity bit for CTEST6 */ -#define CTEST7_EVP 0x04 /* 1 = host bus even parity, 0 = odd */ -#define CTEST7_10_TT1 0x02 /* Transfer type */ -#define CTEST7_00_DC 0x02 /* Set to drive DC low during instruction - fetch */ -#define CTEST7_DIFF 0x01 /* Differential mode */ - -#define CTEST7_SAVE ( CTEST7_EVP | CTEST7_DIFF ) - - -#define TEMP_REG 0x1c /* through 0x1f Temporary stack rw */ - -#define DFIFO_REG 0x20 /* DMA FIFO rw */ -/* - * 0x80 is reserved on the NCR53c710, the CLF and FLF bits have been - * moved into the CTEST8 register. - */ -#define DFIFO_00_FLF 0x80 /* Flush DMA FIFO to memory */ -#define DFIFO_00_CLF 0x40 /* Clear DMA and SCSI FIFOs */ -#define DFIFO_BO6 0x40 -#define DFIFO_BO5 0x20 -#define DFIFO_BO4 0x10 -#define DFIFO_BO3 0x08 -#define DFIFO_BO2 0x04 -#define DFIFO_BO1 0x02 -#define DFIFO_BO0 0x01 -#define DFIFO_10_BO_MASK 0x7f /* 7 bit counter */ -#define DFIFO_00_BO_MASK 0x3f /* 6 bit counter */ - -/* - * Interrupt status rw - * Note that this is the only register which can be read while SCSI - * SCRIPTS are being executed. - */ -#define ISTAT_REG_700 0x21 -#define ISTAT_REG_800 0x14 -#define ISTAT_ABRT 0x80 /* Software abort, write - *1 to abort, wait for interrupt. */ -/* 0x40 and 0x20 are reserved on NCR53c700 and NCR53c700-66 chips */ -#define ISTAT_10_SRST 0x40 /* software reset */ -#define ISTAT_10_SIGP 0x20 /* signal script */ -/* 0x10 is reserved on NCR53c700 series chips */ -#define ISTAT_800_SEM 0x10 /* semaphore */ -#define ISTAT_CON 0x08 /* 1 when connected */ -#define ISTAT_800_INTF 0x04 /* Interrupt on the fly */ -#define ISTAT_700_PRE 0x04 /* Pointer register empty. - * Set to 1 when DSPS and DSP - * registers are empty in pipeline - * mode, always set otherwise. - */ -#define ISTAT_SIP 0x02 /* SCSI interrupt pending from - * SCSI portion of SIOP see - * SSTAT0 - */ -#define ISTAT_DIP 0x01 /* DMA interrupt pending - * see DSTAT - */ - -/* NCR53c700-66 and NCR53c710 only */ -#define CTEST8_REG 0x22 /* Chip test 8 rw */ -#define CTEST8_0066_EAS 0x80 /* Enable alternate SCSI clock, - * ie read from SCLK/ rather than CLK/ - */ -#define CTEST8_0066_EFM 0x40 /* Enable fetch and master outputs */ -#define CTEST8_0066_GRP 0x20 /* Generate Receive Parity for - * pass through. This insures that - * bad parity won't reach the host - * bus. - */ -#define CTEST8_0066_TE 0x10 /* TolerANT enable. Enable - * active negation, should only - * be used for slow SCSI - * non-differential. - */ -#define CTEST8_0066_HSC 0x08 /* Halt SCSI clock */ -#define CTEST8_0066_SRA 0x04 /* Shorten REQ/ACK filtering, - * must be set for fast SCSI-II - * speeds. - */ -#define CTEST8_0066_DAS 0x02 /* Disable automatic target/initiator - * switching. - */ -#define CTEST8_0066_LDE 0x01 /* Last disconnect enable. - * The status of pending - * disconnect is maintained by - * the core, eliminating - * the possibility of missing a - * selection or reselection - * while waiting to fetch a - * WAIT DISCONNECT opcode. - */ - -#define CTEST8_10_V3 0x80 /* Chip revision */ -#define CTEST8_10_V2 0x40 -#define CTEST8_10_V1 0x20 -#define CTEST8_10_V0 0x10 -#define CTEST8_10_V_MASK 0xf0 -#define CTEST8_10_FLF 0x08 /* Flush FIFOs */ -#define CTEST8_10_CLF 0x04 /* Clear FIFOs */ -#define CTEST8_10_FM 0x02 /* Fetch pin mode */ -#define CTEST8_10_SM 0x01 /* Snoop pin mode */ - - -/* - * The CTEST9 register may be used to differentiate between a - * NCR53c700 and a NCR53c710. - * - * Write 0xff to this register. - * Read it. - * If the contents are 0xff, it is a NCR53c700 - * If the contents are 0x00, it is a NCR53c700-66 first revision - * If the contents are some other value, it is some other NCR53c700-66 - */ -#define CTEST9_REG_00 0x23 /* Chip test 9 ro */ -#define LCRC_REG_10 0x23 - -/* - * 0x24 through 0x27 are the DMA byte counter register. Instructions - * write their high 8 bits into the DCMD register, the low 24 bits into - * the DBC register. - * - * Function is dependent on the command type being executed. - */ - - -#define DBC_REG 0x24 -/* - * For Block Move Instructions, DBC is a 24 bit quantity representing - * the number of bytes to transfer. - * For Transfer Control Instructions, DBC is bit fielded as follows : - */ -/* Bits 20 - 23 should be clear */ -#define DBC_TCI_TRUE (1 << 19) /* Jump when true */ -#define DBC_TCI_COMPARE_DATA (1 << 18) /* Compare data */ -#define DBC_TCI_COMPARE_PHASE (1 << 17) /* Compare phase with DCMD field */ -#define DBC_TCI_WAIT_FOR_VALID (1 << 16) /* Wait for REQ */ -/* Bits 8 - 15 are reserved on some implementations ? */ -#define DBC_TCI_MASK_MASK 0xff00 /* Mask for data compare */ -#define DBC_TCI_MASK_SHIFT 8 -#define DBC_TCI_DATA_MASK 0xff /* Data to be compared */ -#define DBC_TCI_DATA_SHIFT 0 - -#define DBC_RWRI_IMMEDIATE_MASK 0xff00 /* Immediate data */ -#define DBC_RWRI_IMMEDIATE_SHIFT 8 /* Amount to shift */ -#define DBC_RWRI_ADDRESS_MASK 0x3f0000 /* Register address */ -#define DBC_RWRI_ADDRESS_SHIFT 16 - - -/* - * DMA command r/w - */ -#define DCMD_REG 0x27 -#define DCMD_TYPE_MASK 0xc0 /* Masks off type */ -#define DCMD_TYPE_BMI 0x00 /* Indicates a Block Move instruction */ -#define DCMD_BMI_IO 0x01 /* I/O, CD, and MSG bits selecting */ -#define DCMD_BMI_CD 0x02 /* the phase for the block MOVE */ -#define DCMD_BMI_MSG 0x04 /* instruction */ - -#define DCMD_BMI_OP_MASK 0x18 /* mask for opcode */ -#define DCMD_BMI_OP_MOVE_T 0x00 /* MOVE */ -#define DCMD_BMI_OP_MOVE_I 0x08 /* MOVE Initiator */ - -#define DCMD_BMI_INDIRECT 0x20 /* Indirect addressing */ - -#define DCMD_TYPE_TCI 0x80 /* Indicates a Transfer Control - instruction */ -#define DCMD_TCI_IO 0x01 /* I/O, CD, and MSG bits selecting */ -#define DCMD_TCI_CD 0x02 /* the phase for the block MOVE */ -#define DCMD_TCI_MSG 0x04 /* instruction */ -#define DCMD_TCI_OP_MASK 0x38 /* mask for opcode */ -#define DCMD_TCI_OP_JUMP 0x00 /* JUMP */ -#define DCMD_TCI_OP_CALL 0x08 /* CALL */ -#define DCMD_TCI_OP_RETURN 0x10 /* RETURN */ -#define DCMD_TCI_OP_INT 0x18 /* INT */ - -#define DCMD_TYPE_RWRI 0x40 /* Indicates I/O or register Read/Write - instruction */ -#define DCMD_RWRI_OPC_MASK 0x38 /* Opcode mask */ -#define DCMD_RWRI_OPC_WRITE 0x28 /* Write SFBR to register */ -#define DCMD_RWRI_OPC_READ 0x30 /* Read register to SFBR */ -#define DCMD_RWRI_OPC_MODIFY 0x38 /* Modify in place */ - -#define DCMD_RWRI_OP_MASK 0x07 -#define DCMD_RWRI_OP_MOVE 0x00 -#define DCMD_RWRI_OP_SHL 0x01 -#define DCMD_RWRI_OP_OR 0x02 -#define DCMD_RWRI_OP_XOR 0x03 -#define DCMD_RWRI_OP_AND 0x04 -#define DCMD_RWRI_OP_SHR 0x05 -#define DCMD_RWRI_OP_ADD 0x06 -#define DCMD_RWRI_OP_ADDC 0x07 - -#define DCMD_TYPE_MMI 0xc0 /* Indicates a Memory Move instruction - (three words) */ - - -#define DNAD_REG 0x28 /* through 0x2b DMA next address for - data */ -#define DSP_REG 0x2c /* through 0x2f DMA SCRIPTS pointer rw */ -#define DSPS_REG 0x30 /* through 0x33 DMA SCRIPTS pointer - save rw */ -#define DMODE_REG_00 0x34 /* DMA mode rw */ -#define DMODE_00_BL1 0x80 /* Burst length bits */ -#define DMODE_00_BL0 0x40 -#define DMODE_BL_MASK 0xc0 -/* Burst lengths (800) */ -#define DMODE_BL_2 0x00 /* 2 transfer */ -#define DMODE_BL_4 0x40 /* 4 transfers */ -#define DMODE_BL_8 0x80 /* 8 transfers */ -#define DMODE_BL_16 0xc0 /* 16 transfers */ - -#define DMODE_700_BW16 0x20 /* Host buswidth = 16 */ -#define DMODE_700_286 0x10 /* 286 mode */ -#define DMODE_700_IOM 0x08 /* Transfer to IO port */ -#define DMODE_700_FAM 0x04 /* Fixed address mode */ -#define DMODE_700_PIPE 0x02 /* Pipeline mode disables - * automatic fetch / exec - */ -#define DMODE_MAN 0x01 /* Manual start mode, - * requires a 1 to be written - * to the start DMA bit in the DCNTL - * register to run scripts - */ - -#define DMODE_700_SAVE ( DMODE_00_BL_MASK | DMODE_00_BW16 | DMODE_00_286 ) - -/* NCR53c800 series only */ -#define SCRATCHA_REG_800 0x34 /* through 0x37 Scratch A rw */ -/* NCR53c710 only */ -#define SCRATCB_REG_10 0x34 /* through 0x37 scratch B rw */ - -#define DMODE_REG_10 0x38 /* DMA mode rw, NCR53c710 and newer */ -#define DMODE_800_SIOM 0x20 /* Source IO = 1 */ -#define DMODE_800_DIOM 0x10 /* Destination IO = 1 */ -#define DMODE_800_ERL 0x08 /* Enable Read Line */ - -/* 35-38 are reserved on 700 and 700-66 series chips */ -#define DIEN_REG 0x39 /* DMA interrupt enable rw */ -/* 0x80, 0x40, and 0x20 are reserved on 700-series chips */ -#define DIEN_800_MDPE 0x40 /* Master data parity error */ -#define DIEN_800_BF 0x20 /* BUS fault */ -#define DIEN_ABRT 0x10 /* Enable aborted interrupt */ -#define DIEN_SSI 0x08 /* Enable single step interrupt */ -#define DIEN_SIR 0x04 /* Enable SCRIPTS INT command - * interrupt - */ -/* 0x02 is reserved on 800 series chips */ -#define DIEN_700_WTD 0x02 /* Enable watchdog timeout interrupt */ -#define DIEN_700_OPC 0x01 /* Enable illegal instruction - * interrupt - */ -#define DIEN_800_IID 0x01 /* Same meaning, different name */ - -/* - * DMA watchdog timer rw - * set in 16 CLK input periods. - */ -#define DWT_REG 0x3a - -/* DMA control rw */ -#define DCNTL_REG 0x3b -#define DCNTL_700_CF1 0x80 /* Clock divisor bits */ -#define DCNTL_700_CF0 0x40 -#define DCNTL_700_CF_MASK 0xc0 -/* Clock divisors Divisor SCLK range (MHZ) */ -#define DCNTL_700_CF_2 0x00 /* 2.0 37.51-50.00 */ -#define DCNTL_700_CF_1_5 0x40 /* 1.5 25.01-37.50 */ -#define DCNTL_700_CF_1 0x80 /* 1.0 16.67-25.00 */ -#define DCNTL_700_CF_3 0xc0 /* 3.0 50.01-66.67 (53c700-66) */ - -#define DCNTL_700_S16 0x20 /* Load scripts 16 bits at a time */ -#define DCNTL_SSM 0x10 /* Single step mode */ -#define DCNTL_700_LLM 0x08 /* Low level mode, can only be set - * after selection */ -#define DCNTL_800_IRQM 0x08 /* Totem pole IRQ pin */ -#define DCNTL_STD 0x04 /* Start DMA / SCRIPTS */ -/* 0x02 is reserved */ -#define DCNTL_00_RST 0x01 /* Software reset, resets everything - * but 286 mode bit in DMODE. On the - * NCR53c710, this bit moved to CTEST8 - */ -#define DCNTL_10_COM 0x01 /* 700 software compatibility mode */ - -#define DCNTL_700_SAVE ( DCNTL_CF_MASK | DCNTL_S16) - - -/* NCR53c700-66 only */ -#define SCRATCHB_REG_00 0x3c /* through 0x3f scratch b rw */ -#define SCRATCHB_REG_800 0x5c /* through 0x5f scratch b rw */ -/* NCR53c710 only */ -#define ADDER_REG_10 0x3c /* Adder, NCR53c710 only */ - -#define SIEN1_REG_800 0x41 -#define SIEN1_800_STO 0x04 /* selection/reselection timeout */ -#define SIEN1_800_GEN 0x02 /* general purpose timer */ -#define SIEN1_800_HTH 0x01 /* handshake to handshake */ - -#define SIST1_REG_800 0x43 -#define SIST1_800_STO 0x04 /* selection/reselection timeout */ -#define SIST1_800_GEN 0x02 /* general purpose timer */ -#define SIST1_800_HTH 0x01 /* handshake to handshake */ - -#define SLPAR_REG_800 0x44 /* Parity */ - -#define MACNTL_REG_800 0x46 /* Memory access control */ -#define MACNTL_800_TYP3 0x80 -#define MACNTL_800_TYP2 0x40 -#define MACNTL_800_TYP1 0x20 -#define MACNTL_800_TYP0 0x10 -#define MACNTL_800_DWR 0x08 -#define MACNTL_800_DRD 0x04 -#define MACNTL_800_PSCPT 0x02 -#define MACNTL_800_SCPTS 0x01 - -#define GPCNTL_REG_800 0x47 /* General Purpose Pin Control */ - -/* Timeouts are expressed such that 0=off, 1=100us, doubling after that */ -#define STIME0_REG_800 0x48 /* SCSI Timer Register 0 */ -#define STIME0_800_HTH_MASK 0xf0 /* Handshake to Handshake timeout */ -#define STIME0_800_HTH_SHIFT 4 -#define STIME0_800_SEL_MASK 0x0f /* Selection timeout */ -#define STIME0_800_SEL_SHIFT 0 - -#define STIME1_REG_800 0x49 -#define STIME1_800_GEN_MASK 0x0f /* General purpose timer */ - -#define RESPID_REG_800 0x4a /* Response ID, bit fielded. 8 - bits on narrow chips, 16 on WIDE */ - -#define STEST0_REG_800 0x4c -#define STEST0_800_SLT 0x08 /* Selection response logic test */ -#define STEST0_800_ART 0x04 /* Arbitration priority encoder test */ -#define STEST0_800_SOZ 0x02 /* Synchronous offset zero */ -#define STEST0_800_SOM 0x01 /* Synchronous offset maximum */ - -#define STEST1_REG_800 0x4d -#define STEST1_800_SCLK 0x80 /* Disable SCSI clock */ - -#define STEST2_REG_800 0x4e -#define STEST2_800_SCE 0x80 /* Enable SOCL/SODL */ -#define STEST2_800_ROF 0x40 /* Reset SCSI sync offset */ -#define STEST2_800_SLB 0x10 /* Enable SCSI loopback mode */ -#define STEST2_800_SZM 0x08 /* SCSI high impedance mode */ -#define STEST2_800_EXT 0x02 /* Extend REQ/ACK filter 30 to 60ns */ -#define STEST2_800_LOW 0x01 /* SCSI low level mode */ - -#define STEST3_REG_800 0x4f -#define STEST3_800_TE 0x80 /* Enable active negation */ -#define STEST3_800_STR 0x40 /* SCSI FIFO test read */ -#define STEST3_800_HSC 0x20 /* Halt SCSI clock */ -#define STEST3_800_DSI 0x10 /* Disable single initiator response */ -#define STEST3_800_TTM 0x04 /* Time test mode */ -#define STEST3_800_CSF 0x02 /* Clear SCSI FIFO */ -#define STEST3_800_STW 0x01 /* SCSI FIFO test write */ - -#define OPTION_PARITY 0x1 /* Enable parity checking */ -#define OPTION_TAGGED_QUEUE 0x2 /* Enable SCSI-II tagged queuing */ -#define OPTION_700 0x8 /* Always run NCR53c700 scripts */ -#define OPTION_INTFLY 0x10 /* Use INTFLY interrupts */ -#define OPTION_DEBUG_INTR 0x20 /* Debug interrupts */ -#define OPTION_DEBUG_INIT_ONLY 0x40 /* Run initialization code and - simple test code, return - DID_NO_CONNECT if any SCSI - commands are attempted. */ -#define OPTION_DEBUG_READ_ONLY 0x80 /* Return DID_ERROR if any - SCSI write is attempted */ -#define OPTION_DEBUG_TRACE 0x100 /* Animated trace mode, print - each address and instruction - executed to debug buffer. */ -#define OPTION_DEBUG_SINGLE 0x200 /* stop after executing one - instruction */ -#define OPTION_SYNCHRONOUS 0x400 /* Enable sync SCSI. */ -#define OPTION_MEMORY_MAPPED 0x800 /* NCR registers have valid - memory mapping */ -#define OPTION_IO_MAPPED 0x1000 /* NCR registers have valid - I/O mapping */ -#define OPTION_DEBUG_PROBE_ONLY 0x2000 /* Probe only, don't even init */ -#define OPTION_DEBUG_TESTS_ONLY 0x4000 /* Probe, init, run selected tests */ -#define OPTION_DEBUG_TEST0 0x08000 /* Run test 0 */ -#define OPTION_DEBUG_TEST1 0x10000 /* Run test 1 */ -#define OPTION_DEBUG_TEST2 0x20000 /* Run test 2 */ -#define OPTION_DEBUG_DUMP 0x40000 /* Dump commands */ -#define OPTION_DEBUG_TARGET_LIMIT 0x80000 /* Only talk to target+luns specified */ -#define OPTION_DEBUG_NCOMMANDS_LIMIT 0x100000 /* Limit the number of commands */ -#define OPTION_DEBUG_SCRIPT 0x200000 /* Print when checkpoints are passed */ -#define OPTION_DEBUG_FIXUP 0x400000 /* print fixup values */ -#define OPTION_DEBUG_DSA 0x800000 -#define OPTION_DEBUG_CORRUPTION 0x1000000 /* Detect script corruption */ -#define OPTION_DEBUG_SDTR 0x2000000 /* Debug SDTR problem */ -#define OPTION_DEBUG_MISMATCH 0x4000000 /* Debug phase mismatches */ -#define OPTION_DISCONNECT 0x8000000 /* Allow disconnect */ -#define OPTION_DEBUG_DISCONNECT 0x10000000 -#define OPTION_ALWAYS_SYNCHRONOUS 0x20000000 /* Negotiate sync. transfers - on power up */ -#define OPTION_DEBUG_QUEUES 0x80000000 -#define OPTION_DEBUG_ALLOCATION 0x100000000LL -#define OPTION_DEBUG_SYNCHRONOUS 0x200000000LL /* Sanity check SXFER and - SCNTL3 registers */ -#define OPTION_NO_ASYNC 0x400000000LL /* Don't automagically send - SDTR for async transfers when - we haven't been told to do - a synchronous transfer. */ -#define OPTION_NO_PRINT_RACE 0x800000000LL /* Don't print message when - the reselect/WAIT DISCONNECT - race condition hits */ -#if !defined(PERM_OPTIONS) -#define PERM_OPTIONS 0 -#endif - -struct NCR53c7x0_synchronous { - u32 select_indirect; /* Value used for indirect selection */ - u32 script[8]; /* Size ?? Script used when target is - reselected */ - unsigned char synchronous_want[5]; /* Per target desired SDTR */ -/* - * Set_synchronous programs these, select_indirect and current settings after - * int_debug_should show a match. - */ - unsigned char sxfer_sanity, scntl3_sanity; -}; - -#define CMD_FLAG_SDTR 1 /* Initiating synchronous - transfer negotiation */ -#define CMD_FLAG_WDTR 2 /* Initiating wide transfer - negotiation */ -#define CMD_FLAG_DID_SDTR 4 /* did SDTR */ -#define CMD_FLAG_DID_WDTR 8 /* did WDTR */ - -struct NCR53c7x0_table_indirect { - u32 count; - void *address; -}; - -enum ncr_event { - EVENT_NONE = 0, -/* - * Order is IMPORTANT, since these must correspond to the event interrupts - * in 53c7,8xx.scr - */ - - EVENT_ISSUE_QUEUE = 0x5000000, /* Command was added to issue queue */ - EVENT_START_QUEUE, /* Command moved to start queue */ - EVENT_SELECT, /* Command completed selection */ - EVENT_DISCONNECT, /* Command disconnected */ - EVENT_RESELECT, /* Command reselected */ - EVENT_COMPLETE, /* Command completed */ - EVENT_IDLE, - EVENT_SELECT_FAILED, - EVENT_BEFORE_SELECT, - EVENT_RESELECT_FAILED -}; - -struct NCR53c7x0_event { - enum ncr_event event; /* What type of event */ - unsigned char target; - unsigned char lun; - struct timeval time; - u32 *dsa; /* What's in the DSA register now (virt) */ -/* - * A few things from that SCSI pid so we know what happened after - * the Scsi_Cmnd structure in question may have disappeared. - */ - unsigned long pid; /* The SCSI PID which caused this - event */ - unsigned char cmnd[12]; -}; - -/* - * Things in the NCR53c7x0_cmd structure are split into two parts : - * - * 1. A fixed portion, for things which are not accessed directly by static NCR - * code (ie, are referenced only by the Linux side of the driver, - * or only by dynamically generated code). - * - * 2. The DSA portion, for things which are accessed directly by static NCR - * code. - * - * This is a little ugly, but it - * 1. Avoids conflicts between the NCR code's picture of the structure, and - * Linux code's idea of what it looks like. - * - * 2. Minimizes the pain in the Linux side of the code needed - * to calculate real dsa locations for things, etc. - * - */ - -struct NCR53c7x0_cmd { - void *real; /* Real, unaligned address for - free function */ - void (* free)(void *, int); /* Command to deallocate; NULL - for structures allocated with - scsi_register, etc. */ - Scsi_Cmnd *cmd; /* Associated Scsi_Cmnd - structure, Scsi_Cmnd points - at NCR53c7x0_cmd using - host_scribble structure */ - - int size; /* scsi_malloc'd size of this - structure */ - - int flags; /* CMD_* flags */ - -/* - * SDTR and WIDE messages are an either/or affair - * in this message, since we will go into message out and send - * _the whole mess_ without dropping out of message out to - * let the target go into message in after sending the first - * message. - */ - - unsigned char select[11]; /* Select message, includes - IDENTIFY - (optional) QUEUE TAG - (optional) SDTR or WDTR - */ - - - volatile struct NCR53c7x0_cmd *next; /* Linux maintained lists (free, - running, eventually finished */ - - - u32 *data_transfer_start; /* Start of data transfer routines */ - u32 *data_transfer_end; /* Address after end of data transfer o - routines */ -/* - * The following three fields were moved from the DSA proper to here - * since only dynamically generated NCR code refers to them, meaning - * we don't need dsa_* absolutes, and it is simpler to let the - * host code refer to them directly. - */ - -/* - * HARD CODED : residual and saved_residual need to agree with the sizes - * used in NCR53c7,8xx.scr. - * - * FIXME: we want to consider the case where we have odd-length - * scatter/gather buffers and a WIDE transfer, in which case - * we'll need to use the CHAIN MOVE instruction. Ick. - */ - u32 residual[6]; /* Residual data transfer which - allows pointer code to work - right. - - [0-1] : Conditional call to - appropriate other transfer - routine. - [2-3] : Residual block transfer - instruction. - [4-5] : Jump to instruction - after splice. - */ - u32 saved_residual[6]; /* Copy of old residual, so we - can get another partial - transfer and still recover - */ - - u32 saved_data_pointer; /* Saved data pointer */ - - u32 dsa_next_addr; /* _Address_ of dsa_next field - in this dsa for RISCy - style constant. */ - - u32 dsa_addr; /* Address of dsa; RISCy style - constant */ - - u32 dsa[0]; /* Variable length (depending - on host type, number of scatter / - gather buffers, etc). */ -}; - -struct NCR53c7x0_break { - u32 *address, old_instruction[2]; - struct NCR53c7x0_break *next; - unsigned char old_size; /* Size of old instruction */ -}; - -/* Indicates that the NCR is not executing code */ -#define STATE_HALTED 0 -/* - * Indicates that the NCR is executing the wait for select / reselect - * script. Only used when running NCR53c700 compatible scripts, only - * state during which an ABORT is _not_ considered an error condition. - */ -#define STATE_WAITING 1 -/* Indicates that the NCR is executing other code. */ -#define STATE_RUNNING 2 -/* - * Indicates that the NCR was being aborted. - */ -#define STATE_ABORTING 3 -/* Indicates that the NCR was successfully aborted. */ -#define STATE_ABORTED 4 -/* Indicates that the NCR has been disabled due to a fatal error */ -#define STATE_DISABLED 5 - -/* - * Where knowledge of SCSI SCRIPT(tm) specified values are needed - * in an interrupt handler, an interrupt handler exists for each - * different SCSI script so we don't have name space problems. - * - * Return values of these handlers are as follows : - */ -#define SPECIFIC_INT_NOTHING 0 /* don't even restart */ -#define SPECIFIC_INT_RESTART 1 /* restart at the next instruction */ -#define SPECIFIC_INT_ABORT 2 /* recoverable error, abort cmd */ -#define SPECIFIC_INT_PANIC 3 /* unrecoverable error, panic */ -#define SPECIFIC_INT_DONE 4 /* normal command completion */ -#define SPECIFIC_INT_BREAK 5 /* break point encountered */ - -struct NCR53c7x0_hostdata { - int size; /* Size of entire Scsi_Host - structure */ - int board; /* set to board type, useful if - we have host specific things, - ie, a general purpose I/O - bit is being used to enable - termination, etc. */ - - int chip; /* set to chip type; 700-66 is - 700-66, rest are last three - digits of part number */ - /* - * PCI device, only for NCR53c8x0 chips. - * pci_valid indicates that the PCI configuration information - * is valid, and we can twiddle MAX_LAT, etc. as recommended - * for maximum performance in the NCR documentation. - */ - struct pci_dev *pci_dev; - unsigned pci_valid:1; - - u32 *dsp; /* dsp to restart with after - all stacked interrupts are - handled. */ - - unsigned dsp_changed:1; /* Has dsp changed within this - set of stacked interrupts ? */ - - unsigned char dstat; /* Most recent value of dstat */ - unsigned dstat_valid:1; - - unsigned expecting_iid:1; /* Expect IID interrupt */ - unsigned expecting_sto:1; /* Expect STO interrupt */ - - /* - * The code stays cleaner if we use variables with function - * pointers and offsets that are unique for the different - * scripts rather than having a slew of switch(hostdata->chip) - * statements. - * - * It also means that the #defines from the SCSI SCRIPTS(tm) - * don't have to be visible outside of the script-specific - * instructions, preventing name space pollution. - */ - - void (* init_fixup)(struct Scsi_Host *host); - void (* init_save_regs)(struct Scsi_Host *host); - void (* dsa_fixup)(struct NCR53c7x0_cmd *cmd); - void (* soft_reset)(struct Scsi_Host *host); - int (* run_tests)(struct Scsi_Host *host); - - /* - * Called when DSTAT_SIR is set, indicating an interrupt generated - * by the INT instruction, where values are unique for each SCSI - * script. Should return one of the SPEC_* values. - */ - - int (* dstat_sir_intr)(struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd); - - int dsa_len; /* Size of DSA structure */ - - /* - * Location of DSA fields for the SCSI SCRIPT corresponding to this - * chip. - */ - - s32 dsa_start; - s32 dsa_end; - s32 dsa_next; - s32 dsa_prev; - s32 dsa_cmnd; - s32 dsa_select; - s32 dsa_msgout; - s32 dsa_cmdout; - s32 dsa_dataout; - s32 dsa_datain; - s32 dsa_msgin; - s32 dsa_msgout_other; - s32 dsa_write_sync; - s32 dsa_write_resume; - s32 dsa_check_reselect; - s32 dsa_status; - s32 dsa_saved_pointer; - s32 dsa_jump_dest; - - /* - * Important entry points that generic fixup code needs - * to know about, fixed up. - */ - - s32 E_accept_message; - s32 E_command_complete; - s32 E_data_transfer; - s32 E_dsa_code_template; - s32 E_dsa_code_template_end; - s32 E_end_data_transfer; - s32 E_msg_in; - s32 E_initiator_abort; - s32 E_other_transfer; - s32 E_other_in; - s32 E_other_out; - s32 E_target_abort; - s32 E_debug_break; - s32 E_reject_message; - s32 E_respond_message; - s32 E_select; - s32 E_select_msgout; - s32 E_test_0; - s32 E_test_1; - s32 E_test_2; - s32 E_test_3; - s32 E_dsa_zero; - s32 E_cmdout_cmdout; - s32 E_wait_reselect; - s32 E_dsa_code_begin; - - long long options; /* Bitfielded set of options enabled */ - volatile u32 test_completed; /* Test completed */ - int test_running; /* Test currently running */ - s32 test_source; - volatile s32 test_dest; - - volatile int state; /* state of driver, only used for - OPTION_700 */ - - unsigned char dmode; /* - * set to the address of the DMODE - * register for this chip. - */ - unsigned char istat; /* - * set to the address of the ISTAT - * register for this chip. - */ - - int scsi_clock; /* - * SCSI clock in HZ. 0 may be used - * for unknown, although this will - * disable synchronous negotiation. - */ - - volatile int intrs; /* Number of interrupts */ - volatile int resets; /* Number of SCSI resets */ - unsigned char saved_dmode; - unsigned char saved_ctest4; - unsigned char saved_ctest7; - unsigned char saved_dcntl; - unsigned char saved_scntl3; - - unsigned char this_id_mask; - - /* Debugger information */ - struct NCR53c7x0_break *breakpoints, /* Linked list of all break points */ - *breakpoint_current; /* Current breakpoint being stepped - through, NULL if we are running - normally. */ -#ifdef NCR_DEBUG - int debug_size; /* Size of debug buffer */ - volatile int debug_count; /* Current data count */ - volatile char *debug_buf; /* Output ring buffer */ - volatile char *debug_write; /* Current write pointer */ - volatile char *debug_read; /* Current read pointer */ -#endif /* def NCR_DEBUG */ - - /* XXX - primitive debugging junk, remove when working ? */ - int debug_print_limit; /* Number of commands to print - out exhaustive debugging - information for if - OPTION_DEBUG_DUMP is set */ - - unsigned char debug_lun_limit[16]; /* If OPTION_DEBUG_TARGET_LIMIT - set, puke if commands are sent - to other target/lun combinations */ - - int debug_count_limit; /* Number of commands to execute - before puking to limit debugging - output */ - - - volatile unsigned idle:1; /* set to 1 if idle */ - - /* - * Table of synchronous+wide transfer parameters set on a per-target - * basis. - */ - - volatile struct NCR53c7x0_synchronous sync[16]; - - volatile Scsi_Cmnd *issue_queue; - /* waiting to be issued by - Linux driver */ - volatile struct NCR53c7x0_cmd *running_list; - /* commands running, maintained - by Linux driver */ - - volatile struct NCR53c7x0_cmd *curr; /* currently connected - nexus, ONLY valid for - NCR53c700/NCR53c700-66 - */ - - volatile struct NCR53c7x0_cmd *spare; /* pointer to spare, - allocated at probe time, - which we can use for - initialization */ - volatile struct NCR53c7x0_cmd *free; - int max_cmd_size; /* Maximum size of NCR53c7x0_cmd - based on number of - scatter/gather segments, etc. - */ - volatile int num_cmds; /* Number of commands - allocated */ - volatile int extra_allocate; - volatile unsigned char cmd_allocated[16]; /* Have we allocated commands - for this target yet? If not, - do so ASAP */ - volatile unsigned char busy[16][8]; /* number of commands - executing on each target - */ - /* - * Eventually, I'll switch to a coroutine for calling - * cmd->done(cmd), etc. so that we can overlap interrupt - * processing with this code for maximum performance. - */ - - volatile struct NCR53c7x0_cmd *finished_queue; - - - /* Shared variables between SCRIPT and host driver */ - volatile u32 *schedule; /* Array of JUMPs to dsa_begin - routines of various DSAs. - When not in use, replace - with jump to next slot */ - - - volatile unsigned char msg_buf[16]; /* buffer for messages - other than the command - complete message */ - - /* Per-target default synchronous and WIDE messages */ - volatile unsigned char synchronous_want[16][5]; - volatile unsigned char wide_want[16][4]; - - /* Bit fielded set of targets we want to speak synchronously with */ - volatile u16 initiate_sdtr; - /* Bit fielded set of targets we want to speak wide with */ - volatile u16 initiate_wdtr; - /* Bit fielded list of targets we've talked to. */ - volatile u16 talked_to; - - /* Array of bit-fielded lun lists that we need to request_sense */ - volatile unsigned char request_sense[16]; - - u32 addr_reconnect_dsa_head; /* RISCy style constant, - address of following */ - volatile u32 reconnect_dsa_head; - /* Data identifying nexus we are trying to match during reselection */ - volatile unsigned char reselected_identify; /* IDENTIFY message */ - volatile unsigned char reselected_tag; /* second byte of queue tag - message or 0 */ - /* These were static variables before we moved them */ - - s32 NCR53c7xx_zero; - s32 NCR53c7xx_sink; - u32 NOP_insn; - char NCR53c7xx_msg_reject; - char NCR53c7xx_msg_abort; - char NCR53c7xx_msg_nop; - - volatile int event_size, event_index; - volatile struct NCR53c7x0_event *events; - - /* If we need to generate code to kill off the currently connected - command, this is where we do it. Should have a BMI instruction - to source or sink the current data, followed by a JUMP - to abort_connected */ - - u32 *abort_script; - - int script_count; /* Size of script in words */ - u32 script[0]; /* Relocated SCSI script */ - -}; - -#define IRQ_NONE 255 -#define DMA_NONE 255 -#define IRQ_AUTO 254 -#define DMA_AUTO 254 - -#define BOARD_GENERIC 0 - -#define NCR53c7x0_insn_size(insn) \ - (((insn) & DCMD_TYPE_MASK) == DCMD_TYPE_MMI ? 3 : 2) - - -#define NCR53c7x0_local_declare() \ - volatile unsigned char *NCR53c7x0_address_memory; \ - unsigned int NCR53c7x0_address_io; \ - int NCR53c7x0_memory_mapped - -#define NCR53c7x0_local_setup(host) \ - NCR53c7x0_address_memory = (void *) (host)->base; \ - NCR53c7x0_address_io = (unsigned int) (host)->io_port; \ - NCR53c7x0_memory_mapped = ((struct NCR53c7x0_hostdata *) \ - host->hostdata)-> options & OPTION_MEMORY_MAPPED - -#define NCR53c7x0_read8(address) \ - (NCR53c7x0_memory_mapped ? \ - (unsigned int)readb(NCR53c7x0_address_memory + (address)) : \ - inb(NCR53c7x0_address_io + (address))) - -#define NCR53c7x0_read16(address) \ - (NCR53c7x0_memory_mapped ? \ - (unsigned int)readw(NCR53c7x0_address_memory + (address)) : \ - inw(NCR53c7x0_address_io + (address))) - -#define NCR53c7x0_read32(address) \ - (NCR53c7x0_memory_mapped ? \ - (unsigned int) readl(NCR53c7x0_address_memory + (address)) : \ - inl(NCR53c7x0_address_io + (address))) - -#define NCR53c7x0_write8(address,value) \ - (NCR53c7x0_memory_mapped ? \ - ({writeb((value), NCR53c7x0_address_memory + (address)); mb();}) : \ - outb((value), NCR53c7x0_address_io + (address))) - -#define NCR53c7x0_write16(address,value) \ - (NCR53c7x0_memory_mapped ? \ - ({writew((value), NCR53c7x0_address_memory + (address)); mb();}) : \ - outw((value), NCR53c7x0_address_io + (address))) - -#define NCR53c7x0_write32(address,value) \ - (NCR53c7x0_memory_mapped ? \ - ({writel((value), NCR53c7x0_address_memory + (address)); mb();}) : \ - outl((value), NCR53c7x0_address_io + (address))) - -/* Patch arbitrary 32 bit words in the script */ -#define patch_abs_32(script, offset, symbol, value) \ - for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof \ - (u32)); ++i) { \ - (script)[A_##symbol##_used[i] - (offset)] += (value); \ - if (hostdata->options & OPTION_DEBUG_FIXUP) \ - printk("scsi%d : %s reference %d at 0x%x in %s is now 0x%x\n",\ - host->host_no, #symbol, i, A_##symbol##_used[i] - \ - (int)(offset), #script, (script)[A_##symbol##_used[i] - \ - (offset)]); \ - } - -/* Patch read/write instruction immediate field */ -#define patch_abs_rwri_data(script, offset, symbol, value) \ - for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof \ - (u32)); ++i) \ - (script)[A_##symbol##_used[i] - (offset)] = \ - ((script)[A_##symbol##_used[i] - (offset)] & \ - ~DBC_RWRI_IMMEDIATE_MASK) | \ - (((value) << DBC_RWRI_IMMEDIATE_SHIFT) & \ - DBC_RWRI_IMMEDIATE_MASK) - -/* Patch transfer control instruction data field */ -#define patch_abs_tci_data(script, offset, symbol, value) \ - for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof \ - (u32)); ++i) \ - (script)[A_##symbol##_used[i] - (offset)] = \ - ((script)[A_##symbol##_used[i] - (offset)] & \ - ~DBC_TCI_DATA_MASK) | \ - (((value) << DBC_TCI_DATA_SHIFT) & \ - DBC_TCI_DATA_MASK) - -/* Patch field in dsa structure (assignment should be +=?) */ -#define patch_dsa_32(dsa, symbol, word, value) \ - { \ - (dsa)[(hostdata->symbol - hostdata->dsa_start) / sizeof(u32) \ - + (word)] = (value); \ - if (hostdata->options & OPTION_DEBUG_DSA) \ - printk("scsi : dsa %s symbol %s(%d) word %d now 0x%x\n", \ - #dsa, #symbol, hostdata->symbol, \ - (word), (u32) le32_to_cpu(value)); \ - } - -/* Paranoid people could use panic() here. */ -#define FATAL(host) shutdown((host)); - -#endif /* NCR53c7x0_C */ -#endif /* NCR53c7x0_H */ diff -Nru a/drivers/scsi/53c7,8xx.scr b/drivers/scsi/53c7,8xx.scr --- a/drivers/scsi/53c7,8xx.scr Sun Feb 9 21:13:37 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1304 +0,0 @@ -#undef DEBUG -#undef EVENTS -; NCR 53c810 driver, main script -; Sponsored by -; iX Multiuser Multitasking Magazine -; hm@ix.de -; -; Copyright 1993, 1994, 1995 Drew Eckhardt -; Visionary Computing -; (Unix and Linux consulting and custom programming) -; drew@PoohSticks.ORG -; +1 (303) 786-7975 -; -; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation. -; -; PRE-ALPHA -; -; For more information, please consult -; -; NCR 53C810 -; PCI-SCSI I/O Processor -; Data Manual -; -; NCR 53C710 -; SCSI I/O Processor -; Programmers Guide -; -; NCR Microelectronics -; 1635 Aeroplaza Drive -; Colorado Springs, CO 80916 -; 1+ (719) 578-3400 -; -; Toll free literature number -; +1 (800) 334-5454 -; -; IMPORTANT : This code is self modifying due to the limitations of -; the NCR53c7,8xx series chips. Persons debugging this code with -; the remote debugger should take this into account, and NOT set -; breakpoints in modified instructions. -; -; Design: -; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard -; microcontroller using a simple instruction set. -; -; So, to minimize the effects of interrupt latency, and to maximize -; throughput, this driver offloads the practical maximum amount -; of processing to the SCSI chip while still maintaining a common -; structure. -; -; Where tradeoffs were needed between efficiency on the older -; chips and the newer NCR53c800 series, the NCR53c800 series -; was chosen. -; -; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully -; automate SCSI transfers without host processor intervention, this -; isn't the case with the NCR53c710 and newer chips which allow -; -; - reads and writes to the internal registers from within the SCSI -; scripts, allowing the SCSI SCRIPTS(tm) code to save processor -; state so that multiple threads of execution are possible, and also -; provide an ALU for loop control, etc. -; -; - table indirect addressing for some instructions. This allows -; pointers to be located relative to the DSA ((Data Structure -; Address) register. -; -; These features make it possible to implement a mailbox style interface, -; where the same piece of code is run to handle I/O for multiple threads -; at once minimizing our need to relocate code. Since the NCR53c700/ -; NCR53c800 series have a unique combination of features, making a -; a standard ingoing/outgoing mailbox system, costly, I've modified it. -; -; - Mailboxes are a mixture of code and data. This lets us greatly -; simplify the NCR53c810 code and do things that would otherwise -; not be possible. -; -; The saved data pointer is now implemented as follows : -; -; Control flow has been architected such that if control reaches -; munge_save_data_pointer, on a restore pointers message or -; reconnection, a jump to the address formerly in the TEMP register -; will allow the SCSI command to resume execution. -; - -; -; Note : the DSA structures must be aligned on 32 bit boundaries, -; since the source and destination of MOVE MEMORY instructions -; must share the same alignment and this is the alignment of the -; NCR registers. -; - -ABSOLUTE dsa_temp_lun = 0 ; Patch to lun for current dsa -ABSOLUTE dsa_temp_next = 0 ; Patch to dsa next for current dsa -ABSOLUTE dsa_temp_addr_next = 0 ; Patch to address of dsa next address - ; for current dsa -ABSOLUTE dsa_temp_sync = 0 ; Patch to address of per-target - ; sync routine -ABSOLUTE dsa_temp_target = 0 ; Patch to id for current dsa -ABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command - ; saved data pointer -ABSOLUTE dsa_temp_addr_residual = 0 ; Patch to address of per-command - ; current residual code -ABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command - ; saved residual code -ABSOLUTE dsa_temp_addr_new_value = 0 ; Address of value for JUMP operand -ABSOLUTE dsa_temp_addr_array_value = 0 ; Address to copy to -ABSOLUTE dsa_temp_addr_dsa_value = 0 ; Address of this DSA value - -; -; Once a device has initiated reselection, we need to compare it -; against the singly linked list of commands which have disconnected -; and are pending reselection. These commands are maintained in -; an unordered singly linked list of DSA structures, through the -; DSA pointers at their 'centers' headed by the reconnect_dsa_head -; pointer. -; -; To avoid complications in removing commands from the list, -; I minimize the amount of expensive (at eight operations per -; addition @ 500-600ns each) pointer operations which must -; be done in the NCR driver by precomputing them on the -; host processor during dsa structure generation. -; -; The fixed-up per DSA code knows how to recognize the nexus -; associated with the corresponding SCSI command, and modifies -; the source and destination pointers for the MOVE MEMORY -; instruction which is executed when reselected_ok is called -; to remove the command from the list. Similarly, DSA is -; loaded with the address of the next DSA structure and -; reselected_check_next is called if a failure occurs. -; -; Perhaps more concisely, the net effect of the mess is -; -; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head, -; src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) { -; src = &dsa->next; -; if (target_id == dsa->id && target_lun == dsa->lun) { -; *dest = *src; -; break; -; } -; } -; -; if (!dsa) -; error (int_err_unexpected_reselect); -; else -; longjmp (dsa->jump_resume, 0); -; -; - -#if (CHIP != 700) && (CHIP != 70066) -; Define DSA structure used for mailboxes -ENTRY dsa_code_template -dsa_code_template: -ENTRY dsa_code_begin -dsa_code_begin: - MOVE dmode_memory_to_ncr TO DMODE - MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch - MOVE dmode_memory_to_memory TO DMODE - CALL scratch_to_dsa - CALL select -; Handle the phase mismatch which may have resulted from the -; MOVE FROM dsa_msgout if we returned here. The CLEAR ATN -; may or may not be necessary, and we should update script_asm.pl -; to handle multiple pieces. - CLEAR ATN - CLEAR ACK - -; Replace second operand with address of JUMP instruction dest operand -; in schedule table for this DSA. Becomes dsa_jump_dest in 53c7,8xx.c. -ENTRY dsa_code_fix_jump -dsa_code_fix_jump: - MOVE MEMORY 4, NOP_insn, 0 - JUMP select_done - -; wrong_dsa loads the DSA register with the value of the dsa_next -; field. -; -wrong_dsa: -; Patch the MOVE MEMORY INSTRUCTION such that -; the destination address is the address of the OLD -; next pointer. -; - MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 8 - MOVE dmode_memory_to_ncr TO DMODE -; -; Move the _contents_ of the next pointer into the DSA register as -; the next I_T_L or I_T_L_Q tupple to check against the established -; nexus. -; - MOVE MEMORY 4, dsa_temp_next, addr_scratch - MOVE dmode_memory_to_memory TO DMODE - CALL scratch_to_dsa - JUMP reselected_check_next - -ABSOLUTE dsa_save_data_pointer = 0 -ENTRY dsa_code_save_data_pointer -dsa_code_save_data_pointer: - MOVE dmode_ncr_to_memory TO DMODE - MOVE MEMORY 4, addr_temp, dsa_temp_addr_saved_pointer - MOVE dmode_memory_to_memory TO DMODE -; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h - MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual - CLEAR ACK -#ifdef DEBUG - INT int_debug_saved -#endif - RETURN -ABSOLUTE dsa_restore_pointers = 0 -ENTRY dsa_code_restore_pointers -dsa_code_restore_pointers: - MOVE dmode_memory_to_ncr TO DMODE - MOVE MEMORY 4, dsa_temp_addr_saved_pointer, addr_temp - MOVE dmode_memory_to_memory TO DMODE -; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h - MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual - CLEAR ACK -#ifdef DEBUG - INT int_debug_restored -#endif - RETURN - -ABSOLUTE dsa_check_reselect = 0 -; dsa_check_reselect determines whether or not the current target and -; lun match the current DSA -ENTRY dsa_code_check_reselect -dsa_code_check_reselect: - MOVE SSID TO SFBR ; SSID contains 3 bit target ID -; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips - JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0xf8 -; -; Hack - move to scratch first, since SFBR is not writeable -; via the CPU and hence a MOVE MEMORY instruction. -; - MOVE dmode_memory_to_ncr TO DMODE - MOVE MEMORY 1, reselected_identify, addr_scratch - MOVE dmode_memory_to_memory TO DMODE - MOVE SCRATCH0 TO SFBR -; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips - JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8 -; Patch the MOVE MEMORY INSTRUCTION such that -; the source address is the address of this dsa's -; next pointer. - MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 4 - CALL reselected_ok - CALL dsa_temp_sync -; Release ACK on the IDENTIFY message _after_ we've set the synchronous -; transfer parameters! - CLEAR ACK -; Implicitly restore pointers on reselection, so a RETURN -; will transfer control back to the right spot. - CALL REL (dsa_code_restore_pointers) - RETURN -ENTRY dsa_zero -dsa_zero: -ENTRY dsa_code_template_end -dsa_code_template_end: - -; Perform sanity check for dsa_fields_start == dsa_code_template_end - -; dsa_zero, puke. - -ABSOLUTE dsa_fields_start = 0 ; Sanity marker - ; pad 48 bytes (fix this RSN) -ABSOLUTE dsa_next = 48 ; len 4 Next DSA - ; del 4 Previous DSA address -ABSOLUTE dsa_cmnd = 56 ; len 4 Scsi_Cmnd * for this thread. -ABSOLUTE dsa_select = 60 ; len 4 Device ID, Period, Offset for - ; table indirect select -ABSOLUTE dsa_msgout = 64 ; len 8 table indirect move parameter for - ; select message -ABSOLUTE dsa_cmdout = 72 ; len 8 table indirect move parameter for - ; command -ABSOLUTE dsa_dataout = 80 ; len 4 code pointer for dataout -ABSOLUTE dsa_datain = 84 ; len 4 code pointer for datain -ABSOLUTE dsa_msgin = 88 ; len 8 table indirect move for msgin -ABSOLUTE dsa_status = 96 ; len 8 table indirect move for status byte -ABSOLUTE dsa_msgout_other = 104 ; len 8 table indirect for normal message out - ; (Synchronous transfer negotiation, etc). -ABSOLUTE dsa_end = 112 - -ABSOLUTE schedule = 0 ; Array of JUMP dsa_begin or JUMP (next), - ; terminated by a call to JUMP wait_reselect - -; Linked lists of DSA structures -ABSOLUTE reconnect_dsa_head = 0 ; Link list of DSAs which can reconnect -ABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable containing - ; address of reconnect_dsa_head - -; These select the source and destination of a MOVE MEMORY instruction -ABSOLUTE dmode_memory_to_memory = 0x0 -ABSOLUTE dmode_memory_to_ncr = 0x0 -ABSOLUTE dmode_ncr_to_memory = 0x0 - -ABSOLUTE addr_scratch = 0x0 -ABSOLUTE addr_temp = 0x0 -#endif /* CHIP != 700 && CHIP != 70066 */ - -; Interrupts - -; MSB indicates type -; 0 handle error condition -; 1 handle message -; 2 handle normal condition -; 3 debugging interrupt -; 4 testing interrupt -; Next byte indicates specific error - -; XXX not yet implemented, I'm not sure if I want to - -; Next byte indicates the routine the error occurred in -; The LSB indicates the specific place the error occurred - -ABSOLUTE int_err_unexpected_phase = 0x00000000 ; Unexpected phase encountered -ABSOLUTE int_err_selected = 0x00010000 ; SELECTED (nee RESELECTED) -ABSOLUTE int_err_unexpected_reselect = 0x00020000 -ABSOLUTE int_err_check_condition = 0x00030000 -ABSOLUTE int_err_no_phase = 0x00040000 -ABSOLUTE int_msg_wdtr = 0x01000000 ; WDTR message received -ABSOLUTE int_msg_sdtr = 0x01010000 ; SDTR received -ABSOLUTE int_msg_1 = 0x01020000 ; single byte special message - ; received - -ABSOLUTE int_norm_select_complete = 0x02000000 ; Select complete, reprogram - ; registers. -ABSOLUTE int_norm_reselect_complete = 0x02010000 ; Nexus established -ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete -ABSOLUTE int_norm_disconnected = 0x02030000 ; Disconnected -ABSOLUTE int_norm_aborted =0x02040000 ; Aborted *dsa -ABSOLUTE int_norm_reset = 0x02050000 ; Generated BUS reset. -ABSOLUTE int_debug_break = 0x03000000 ; Break point -#ifdef DEBUG -ABSOLUTE int_debug_scheduled = 0x03010000 ; new I/O scheduled -ABSOLUTE int_debug_idle = 0x03020000 ; scheduler is idle -ABSOLUTE int_debug_dsa_loaded = 0x03030000 ; dsa reloaded -ABSOLUTE int_debug_reselected = 0x03040000 ; NCR reselected -ABSOLUTE int_debug_head = 0x03050000 ; issue head overwritten -ABSOLUTE int_debug_disconnected = 0x03060000 ; disconnected -ABSOLUTE int_debug_disconnect_msg = 0x03070000 ; got message to disconnect -ABSOLUTE int_debug_dsa_schedule = 0x03080000 ; in dsa_schedule -ABSOLUTE int_debug_reselect_check = 0x03090000 ; Check for reselection of DSA -ABSOLUTE int_debug_reselected_ok = 0x030a0000 ; Reselection accepted -#endif -ABSOLUTE int_debug_panic = 0x030b0000 ; Panic driver -#ifdef DEBUG -ABSOLUTE int_debug_saved = 0x030c0000 ; save/restore pointers -ABSOLUTE int_debug_restored = 0x030d0000 -ABSOLUTE int_debug_sync = 0x030e0000 ; Sanity check synchronous - ; parameters. -ABSOLUTE int_debug_datain = 0x030f0000 ; going into data in phase - ; now. -ABSOLUTE int_debug_check_dsa = 0x03100000 ; Sanity check DSA against - ; SDID. -#endif - -ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete -ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete -ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete - - -; These should start with 0x05000000, with low bits incrementing for -; each one. - -#ifdef EVENTS -ABSOLUTE int_EVENT_SELECT = 0 -ABSOLUTE int_EVENT_DISCONNECT = 0 -ABSOLUTE int_EVENT_RESELECT = 0 -ABSOLUTE int_EVENT_COMPLETE = 0 -ABSOLUTE int_EVENT_IDLE = 0 -ABSOLUTE int_EVENT_SELECT_FAILED = 0 -ABSOLUTE int_EVENT_BEFORE_SELECT = 0 -ABSOLUTE int_EVENT_RESELECT_FAILED = 0 -#endif - -ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message -ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message -ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source -ABSOLUTE NCR53c7xx_sink = 0 ; long to dump worthless data in -ABSOLUTE NOP_insn = 0 ; NOP instruction - -; Pointer to message, potentially multi-byte -ABSOLUTE msg_buf = 0 - -; Pointer to holding area for reselection information -ABSOLUTE reselected_identify = 0 -ABSOLUTE reselected_tag = 0 - -; Request sense command pointer, it's a 6 byte command, should -; be constant for all commands since we always want 16 bytes of -; sense and we don't need to change any fields as we did under -; SCSI-I when we actually cared about the LUN field. -;EXTERNAL NCR53c7xx_sense ; Request sense command - -#if (CHIP != 700) && (CHIP != 70066) -; dsa_schedule -; PURPOSE : after a DISCONNECT message has been received, and pointers -; saved, insert the current DSA structure at the head of the -; disconnected queue and fall through to the scheduler. -; -; CALLS : OK -; -; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list -; of disconnected commands -; -; MODIFIES : SCRATCH, reconnect_dsa_head -; -; EXITS : always passes control to schedule - -ENTRY dsa_schedule -dsa_schedule: -#if 0 - INT int_debug_dsa_schedule -#endif - -; -; Calculate the address of the next pointer within the DSA -; structure of the command that is currently disconnecting -; - CALL dsa_to_scratch - MOVE SCRATCH0 + dsa_next TO SCRATCH0 - MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY - MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY - MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY - -; Point the next field of this DSA structure at the current disconnected -; list - MOVE dmode_ncr_to_memory TO DMODE - MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8 - MOVE dmode_memory_to_memory TO DMODE -dsa_schedule_insert: - MOVE MEMORY 4, reconnect_dsa_head, 0 - -; And update the head pointer. - CALL dsa_to_scratch - MOVE dmode_ncr_to_memory TO DMODE - MOVE MEMORY 4, addr_scratch, reconnect_dsa_head - MOVE dmode_memory_to_memory TO DMODE -/* Temporarily, see what happens. */ -#ifndef ORIGINAL - MOVE SCNTL2 & 0x7f TO SCNTL2 - CLEAR ACK -#endif - WAIT DISCONNECT -#ifdef EVENTS - INT int_EVENT_DISCONNECT; -#endif -#if 0 - INT int_debug_disconnected -#endif - JUMP schedule -#endif - -; -; select -; -; PURPOSE : establish a nexus for the SCSI command referenced by DSA. -; On success, the current DSA structure is removed from the issue -; queue. Usually, this is entered as a fall-through from schedule, -; although the contingent allegiance handling code will write -; the select entry address to the DSP to restart a command as a -; REQUEST SENSE. A message is sent (usually IDENTIFY, although -; additional SDTR or WDTR messages may be sent). COMMAND OUT -; is handled. -; -; INPUTS : DSA - SCSI command, issue_dsa_head -; -; CALLS : NOT OK -; -; MODIFIES : SCRATCH, issue_dsa_head -; -; EXITS : on reselection or selection, go to select_failed -; otherwise, RETURN so control is passed back to -; dsa_begin. -; - -ENTRY select -select: - -#if 0 -#ifdef EVENTS - INT int_EVENT_BEFORE_SELECT -#endif -#endif - -#if 0 -#ifdef DEBUG - INT int_debug_scheduled -#endif -#endif - CLEAR TARGET - -; XXX -; -; In effect, SELECTION operations are backgrounded, with execution -; continuing until code which waits for REQ or a fatal interrupt is -; encountered. -; -; So, for more performance, we could overlap the code which removes -; the command from the NCRs issue queue with the selection, but -; at this point I don't want to deal with the error recovery. -; - -#if (CHIP != 700) && (CHIP != 70066) - SELECT ATN FROM dsa_select, select_failed - JUMP select_msgout, WHEN MSG_OUT -ENTRY select_msgout -select_msgout: - MOVE FROM dsa_msgout, WHEN MSG_OUT -#else -ENTRY select_msgout - SELECT ATN 0, select_failed -select_msgout: - MOVE 0, 0, WHEN MSGOUT -#endif - -#ifdef EVENTS - INT int_EVENT_SELECT -#endif - RETURN - -; -; select_done -; -; PURPOSE: continue on to normal data transfer; called as the exit -; point from dsa_begin. -; -; INPUTS: dsa -; -; CALLS: OK -; -; - -select_done: - -#ifdef DEBUG -ENTRY select_check_dsa -select_check_dsa: - INT int_debug_check_dsa -#endif - -; After a successful selection, we should get either a CMD phase or -; some transfer request negotiation message. - - JUMP cmdout, WHEN CMD - INT int_err_unexpected_phase, WHEN NOT MSG_IN - -select_msg_in: - CALL msg_in, WHEN MSG_IN - JUMP select_msg_in, WHEN MSG_IN - -cmdout: - INT int_err_unexpected_phase, WHEN NOT CMD -#if (CHIP == 700) - INT int_norm_selected -#endif -ENTRY cmdout_cmdout -cmdout_cmdout: -#if (CHIP != 700) && (CHIP != 70066) - MOVE FROM dsa_cmdout, WHEN CMD -#else - MOVE 0, 0, WHEN CMD -#endif /* (CHIP != 700) && (CHIP != 70066) */ - -; -; data_transfer -; other_out -; other_in -; other_transfer -; -; PURPOSE : handle the main data transfer for a SCSI command in -; several parts. In the first part, data_transfer, DATA_IN -; and DATA_OUT phases are allowed, with the user provided -; code (usually dynamically generated based on the scatter/gather -; list associated with a SCSI command) called to handle these -; phases. -; -; After control has passed to one of the user provided -; DATA_IN or DATA_OUT routines, back calls are made to -; other_transfer_in or other_transfer_out to handle non-DATA IN -; and DATA OUT phases respectively, with the state of the active -; data pointer being preserved in TEMP. -; -; On completion, the user code passes control to other_transfer -; which causes DATA_IN and DATA_OUT to result in unexpected_phase -; interrupts so that data overruns may be trapped. -; -; INPUTS : DSA - SCSI command -; -; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in -; other_transfer -; -; MODIFIES : SCRATCH -; -; EXITS : if STATUS IN is detected, signifying command completion, -; the NCR jumps to command_complete. If MSG IN occurs, a -; CALL is made to msg_in. Otherwise, other_transfer runs in -; an infinite loop. -; - -ENTRY data_transfer -data_transfer: - JUMP cmdout_cmdout, WHEN CMD - CALL msg_in, WHEN MSG_IN - INT int_err_unexpected_phase, WHEN MSG_OUT - JUMP do_dataout, WHEN DATA_OUT - JUMP do_datain, WHEN DATA_IN - JUMP command_complete, WHEN STATUS - JUMP data_transfer -ENTRY end_data_transfer -end_data_transfer: - -; -; FIXME: On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain -; should be fixed up whenever the nexus changes so it can point to the -; correct routine for that command. -; - -#if (CHIP != 700) && (CHIP != 70066) -; Nasty jump to dsa->dataout -do_dataout: - CALL dsa_to_scratch - MOVE SCRATCH0 + dsa_dataout TO SCRATCH0 - MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY - MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY - MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY - MOVE dmode_ncr_to_memory TO DMODE - MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4 - MOVE dmode_memory_to_memory TO DMODE -dataout_to_jump: - MOVE MEMORY 4, 0, dataout_jump + 4 -dataout_jump: - JUMP 0 - -; Nasty jump to dsa->dsain -do_datain: - CALL dsa_to_scratch - MOVE SCRATCH0 + dsa_datain TO SCRATCH0 - MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY - MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY - MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY - MOVE dmode_ncr_to_memory TO DMODE - MOVE MEMORY 4, addr_scratch, datain_to_jump + 4 - MOVE dmode_memory_to_memory TO DMODE -ENTRY datain_to_jump -datain_to_jump: - MOVE MEMORY 4, 0, datain_jump + 4 -#if 0 - INT int_debug_datain -#endif -datain_jump: - JUMP 0 -#endif /* (CHIP != 700) && (CHIP != 70066) */ - - -; Note that other_out and other_in loop until a non-data phase -; is discovered, so we only execute return statements when we -; can go on to the next data phase block move statement. - -ENTRY other_out -other_out: -#if 0 - INT 0x03ffdead -#endif - INT int_err_unexpected_phase, WHEN CMD - JUMP msg_in_restart, WHEN MSG_IN - INT int_err_unexpected_phase, WHEN MSG_OUT - INT int_err_unexpected_phase, WHEN DATA_IN - JUMP command_complete, WHEN STATUS - JUMP other_out, WHEN NOT DATA_OUT - RETURN - -ENTRY other_in -other_in: -#if 0 - INT 0x03ffdead -#endif - INT int_err_unexpected_phase, WHEN CMD - JUMP msg_in_restart, WHEN MSG_IN - INT int_err_unexpected_phase, WHEN MSG_OUT - INT int_err_unexpected_phase, WHEN DATA_OUT - JUMP command_complete, WHEN STATUS - JUMP other_in, WHEN NOT DATA_IN - RETURN - - -ENTRY other_transfer -other_transfer: - INT int_err_unexpected_phase, WHEN CMD - CALL msg_in, WHEN MSG_IN - INT int_err_unexpected_phase, WHEN MSG_OUT - INT int_err_unexpected_phase, WHEN DATA_OUT - INT int_err_unexpected_phase, WHEN DATA_IN - JUMP command_complete, WHEN STATUS - JUMP other_transfer - -; -; msg_in_restart -; msg_in -; munge_msg -; -; PURPOSE : process messages from a target. msg_in is called when the -; caller hasn't read the first byte of the message. munge_message -; is called when the caller has read the first byte of the message, -; and left it in SFBR. msg_in_restart is called when the caller -; hasn't read the first byte of the message, and wishes RETURN -; to transfer control back to the address of the conditional -; CALL instruction rather than to the instruction after it. -; -; Various int_* interrupts are generated when the host system -; needs to intervene, as is the case with SDTR, WDTR, and -; INITIATE RECOVERY messages. -; -; When the host system handles one of these interrupts, -; it can respond by reentering at reject_message, -; which rejects the message and returns control to -; the caller of msg_in or munge_msg, accept_message -; which clears ACK and returns control, or reply_message -; which sends the message pointed to by the DSA -; msgout_other table indirect field. -; -; DISCONNECT messages are handled by moving the command -; to the reconnect_dsa_queue. -; -; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg -; only) -; -; CALLS : NO. The TEMP register isn't backed up to allow nested calls. -; -; MODIFIES : SCRATCH, DSA on DISCONNECT -; -; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS, -; and normal return from message handlers running under -; Linux, control is returned to the caller. Receipt -; of DISCONNECT messages pass control to dsa_schedule. -; -ENTRY msg_in_restart -msg_in_restart: -; XXX - hackish -; -; Since it's easier to debug changes to the statically -; compiled code, rather than the dynamically generated -; stuff, such as -; -; MOVE x, y, WHEN data_phase -; CALL other_z, WHEN NOT data_phase -; MOVE x, y, WHEN data_phase -; -; I'd like to have certain routines (notably the message handler) -; restart on the conditional call rather than the next instruction. -; -; So, subtract 8 from the return address - - MOVE TEMP0 + 0xf8 TO TEMP0 - MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY - MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY - MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY - -ENTRY msg_in -msg_in: - MOVE 1, msg_buf, WHEN MSG_IN - -munge_msg: - JUMP munge_extended, IF 0x01 ; EXTENDED MESSAGE - JUMP munge_2, IF 0x20, AND MASK 0xdf ; two byte message -; -; XXX - I've seen a handful of broken SCSI devices which fail to issue -; a SAVE POINTERS message before disconnecting in the middle of -; a transfer, assuming that the DATA POINTER will be implicitly -; restored. -; -; Historically, I've often done an implicit save when the DISCONNECT -; message is processed. We may want to consider having the option of -; doing that here. -; - JUMP munge_save_data_pointer, IF 0x02 ; SAVE DATA POINTER - JUMP munge_restore_pointers, IF 0x03 ; RESTORE POINTERS - JUMP munge_disconnect, IF 0x04 ; DISCONNECT - INT int_msg_1, IF 0x07 ; MESSAGE REJECT - INT int_msg_1, IF 0x0f ; INITIATE RECOVERY -#ifdef EVENTS - INT int_EVENT_SELECT_FAILED -#endif - JUMP reject_message - -munge_2: - JUMP reject_message -; -; The SCSI standard allows targets to recover from transient -; error conditions by backing up the data pointer with a -; RESTORE POINTERS message. -; -; So, we must save and restore the _residual_ code as well as -; the current instruction pointer. Because of this messiness, -; it is simpler to put dynamic code in the dsa for this and to -; just do a simple jump down there. -; - -munge_save_data_pointer: - MOVE DSA0 + dsa_save_data_pointer TO SFBR - MOVE SFBR TO SCRATCH0 - MOVE DSA1 + 0xff TO SFBR WITH CARRY - MOVE SFBR TO SCRATCH1 - MOVE DSA2 + 0xff TO SFBR WITH CARRY - MOVE SFBR TO SCRATCH2 - MOVE DSA3 + 0xff TO SFBR WITH CARRY - MOVE SFBR TO SCRATCH3 - - MOVE dmode_ncr_to_memory TO DMODE - MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4 - MOVE dmode_memory_to_memory TO DMODE -jump_dsa_save: - JUMP 0 - -munge_restore_pointers: - MOVE DSA0 + dsa_restore_pointers TO SFBR - MOVE SFBR TO SCRATCH0 - MOVE DSA1 + 0xff TO SFBR WITH CARRY - MOVE SFBR TO SCRATCH1 - MOVE DSA2 + 0xff TO SFBR WITH CARRY - MOVE SFBR TO SCRATCH2 - MOVE DSA3 + 0xff TO SFBR WITH CARRY - MOVE SFBR TO SCRATCH3 - - MOVE dmode_ncr_to_memory TO DMODE - MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4 - MOVE dmode_memory_to_memory TO DMODE -jump_dsa_restore: - JUMP 0 - - -munge_disconnect: -#if 0 - INT int_debug_disconnect_msg -#endif - -/* - * Before, we overlapped processing with waiting for disconnect, but - * debugging was beginning to appear messy. Temporarily move things - * to just before the WAIT DISCONNECT. - */ - -#ifdef ORIGINAL - MOVE SCNTL2 & 0x7f TO SCNTL2 - CLEAR ACK -#endif - -#if (CHIP != 700) && (CHIP != 70066) - JUMP dsa_schedule -#else - WAIT DISCONNECT - INT int_norm_disconnected -#endif - -munge_extended: - CLEAR ACK - INT int_err_unexpected_phase, WHEN NOT MSG_IN - MOVE 1, msg_buf + 1, WHEN MSG_IN - JUMP munge_extended_2, IF 0x02 - JUMP munge_extended_3, IF 0x03 - JUMP reject_message - -munge_extended_2: - CLEAR ACK - MOVE 1, msg_buf + 2, WHEN MSG_IN - JUMP reject_message, IF NOT 0x02 ; Must be WDTR - CLEAR ACK - MOVE 1, msg_buf + 3, WHEN MSG_IN - INT int_msg_wdtr - -munge_extended_3: - CLEAR ACK - MOVE 1, msg_buf + 2, WHEN MSG_IN - JUMP reject_message, IF NOT 0x01 ; Must be SDTR - CLEAR ACK - MOVE 2, msg_buf + 3, WHEN MSG_IN - INT int_msg_sdtr - -ENTRY reject_message -reject_message: - SET ATN - CLEAR ACK - MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT - RETURN - -ENTRY accept_message -accept_message: - CLEAR ATN - CLEAR ACK - RETURN - -ENTRY respond_message -respond_message: - SET ATN - CLEAR ACK - MOVE FROM dsa_msgout_other, WHEN MSG_OUT - RETURN - -; -; command_complete -; -; PURPOSE : handle command termination when STATUS IN is detected by reading -; a status byte followed by a command termination message. -; -; Normal termination results in an INTFLY instruction, and -; the host system can pick out which command terminated by -; examining the MESSAGE and STATUS buffers of all currently -; executing commands; -; -; Abnormal (CHECK_CONDITION) termination results in an -; int_err_check_condition interrupt so that a REQUEST SENSE -; command can be issued out-of-order so that no other command -; clears the contingent allegiance condition. -; -; -; INPUTS : DSA - command -; -; CALLS : OK -; -; EXITS : On successful termination, control is passed to schedule. -; On abnormal termination, the user will usually modify the -; DSA fields and corresponding buffers and return control -; to select. -; - -ENTRY command_complete -command_complete: - MOVE FROM dsa_status, WHEN STATUS -#if (CHIP != 700) && (CHIP != 70066) - MOVE SFBR TO SCRATCH0 ; Save status -#endif /* (CHIP != 700) && (CHIP != 70066) */ -ENTRY command_complete_msgin -command_complete_msgin: - MOVE FROM dsa_msgin, WHEN MSG_IN -; Indicate that we should be expecting a disconnect - MOVE SCNTL2 & 0x7f TO SCNTL2 - CLEAR ACK -#if (CHIP != 700) && (CHIP != 70066) - WAIT DISCONNECT - -; -; The SCSI specification states that when a UNIT ATTENTION condition -; is pending, as indicated by a CHECK CONDITION status message, -; the target shall revert to asynchronous transfers. Since -; synchronous transfers parameters are maintained on a per INITIATOR/TARGET -; basis, and returning control to our scheduler could work on a command -; running on another lun on that target using the old parameters, we must -; interrupt the host processor to get them changed, or change them ourselves. -; -; Once SCSI-II tagged queueing is implemented, things will be even more -; hairy, since contingent allegiance conditions exist on a per-target/lun -; basis, and issuing a new command with a different tag would clear it. -; In these cases, we must interrupt the host processor to get a request -; added to the HEAD of the queue with the request sense command, or we -; must automatically issue the request sense command. - -#if 0 - MOVE SCRATCH0 TO SFBR - JUMP command_failed, IF 0x02 -#endif - INTFLY -#endif /* (CHIP != 700) && (CHIP != 70066) */ -#ifdef EVENTS - INT int_EVENT_COMPLETE -#endif -#if (CHIP != 700) && (CHIP != 70066) - JUMP schedule -command_failed: - INT int_err_check_condition -#else - INT int_norm_command_complete -#endif - -; -; wait_reselect -; -; PURPOSE : This is essentially the idle routine, where control lands -; when there are no new processes to schedule. wait_reselect -; waits for reselection, selection, and new commands. -; -; When a successful reselection occurs, with the aid -; of fixed up code in each DSA, wait_reselect walks the -; reconnect_dsa_queue, asking each dsa if the target ID -; and LUN match its. -; -; If a match is found, a call is made back to reselected_ok, -; which through the miracles of self modifying code, extracts -; the found DSA from the reconnect_dsa_queue and then -; returns control to the DSAs thread of execution. -; -; INPUTS : NONE -; -; CALLS : OK -; -; MODIFIES : DSA, -; -; EXITS : On successful reselection, control is returned to the -; DSA which called reselected_ok. If the WAIT RESELECT -; was interrupted by a new commands arrival signaled by -; SIG_P, control is passed to schedule. If the NCR is -; selected, the host system is interrupted with an -; int_err_selected which is usually responded to by -; setting DSP to the target_abort address. - -ENTRY wait_reselect -wait_reselect: -#ifdef EVENTS - int int_EVENT_IDLE -#endif -#if 0 - int int_debug_idle -#endif - WAIT RESELECT wait_reselect_failed - -reselected: -#ifdef EVENTS - int int_EVENT_RESELECT -#endif - CLEAR TARGET - MOVE dmode_memory_to_memory TO DMODE - ; Read all data needed to reestablish the nexus - - MOVE 1, reselected_identify, WHEN MSG_IN - ; We used to CLEAR ACK here. -#if (CHIP != 700) && (CHIP != 70066) -#if 0 - int int_debug_reselected -#endif - - ; Point DSA at the current head of the disconnected queue. - MOVE dmode_memory_to_ncr TO DMODE - MOVE MEMORY 4, reconnect_dsa_head, addr_scratch - MOVE dmode_memory_to_memory TO DMODE - CALL scratch_to_dsa - - ; Fix the update-next pointer so that the reconnect_dsa_head - ; pointer is the one that will be updated if this DSA is a hit - ; and we remove it from the queue. - - MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok + 8 - -ENTRY reselected_check_next -reselected_check_next: -#if 0 - INT int_debug_reselect_check -#endif - ; Check for a NULL pointer. - MOVE DSA0 TO SFBR - JUMP reselected_not_end, IF NOT 0 - MOVE DSA1 TO SFBR - JUMP reselected_not_end, IF NOT 0 - MOVE DSA2 TO SFBR - JUMP reselected_not_end, IF NOT 0 - MOVE DSA3 TO SFBR - JUMP reselected_not_end, IF NOT 0 - INT int_err_unexpected_reselect - -reselected_not_end: - ; - ; XXX the ALU is only eight bits wide, and the assembler - ; wont do the dirt work for us. As long as dsa_check_reselect - ; is negative, we need to sign extend with 1 bits to the full - ; 32 bit width of the address. - ; - ; A potential work around would be to have a known alignment - ; of the DSA structure such that the base address plus - ; dsa_check_reselect doesn't require carrying from bytes - ; higher than the LSB. - ; - - MOVE DSA0 TO SFBR - MOVE SFBR + dsa_check_reselect TO SCRATCH0 - MOVE DSA1 TO SFBR - MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY - MOVE DSA2 TO SFBR - MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY - MOVE DSA3 TO SFBR - MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY - - MOVE dmode_ncr_to_memory TO DMODE - MOVE MEMORY 4, addr_scratch, reselected_check + 4 - MOVE dmode_memory_to_memory TO DMODE -reselected_check: - JUMP 0 - - -; -; -ENTRY reselected_ok -reselected_ok: - MOVE MEMORY 4, 0, 0 ; Patched : first word - ; is address of - ; successful dsa_next - ; Second word is last - ; unsuccessful dsa_next, - ; starting with - ; dsa_reconnect_head - ; We used to CLEAR ACK here. -#if 0 - INT int_debug_reselected_ok -#endif -#ifdef DEBUG - INT int_debug_check_dsa -#endif - RETURN ; Return control to where -#else - INT int_norm_reselected -#endif /* (CHIP != 700) && (CHIP != 70066) */ - -selected: - INT int_err_selected; - -; -; A select or reselect failure can be caused by one of two conditions : -; 1. SIG_P was set. This will be the case if the user has written -; a new value to a previously NULL head of the issue queue. -; -; 2. The NCR53c810 was selected or reselected by another device. -; -; 3. The bus was already busy since we were selected or reselected -; before starting the command. - -wait_reselect_failed: -#ifdef EVENTS - INT int_EVENT_RESELECT_FAILED -#endif -; Check selected bit. - MOVE SIST0 & 0x20 TO SFBR - JUMP selected, IF 0x20 -; Reading CTEST2 clears the SIG_P bit in the ISTAT register. - MOVE CTEST2 & 0x40 TO SFBR - JUMP schedule, IF 0x40 -; Check connected bit. -; FIXME: this needs to change if we support target mode - MOVE ISTAT & 0x08 TO SFBR - JUMP reselected, IF 0x08 -; FIXME : Something bogus happened, and we shouldn't fail silently. -#if 0 - JUMP schedule -#else - INT int_debug_panic -#endif - - -select_failed: -#ifdef EVENTS - int int_EVENT_SELECT_FAILED -#endif -; Otherwise, mask the selected and reselected bits off SIST0 - MOVE SIST0 & 0x30 TO SFBR - JUMP selected, IF 0x20 - JUMP reselected, IF 0x10 -; If SIGP is set, the user just gave us another command, and -; we should restart or return to the scheduler. -; Reading CTEST2 clears the SIG_P bit in the ISTAT register. - MOVE CTEST2 & 0x40 TO SFBR - JUMP select, IF 0x40 -; Check connected bit. -; FIXME: this needs to change if we support target mode -; FIXME: is this really necessary? - MOVE ISTAT & 0x08 TO SFBR - JUMP reselected, IF 0x08 -; FIXME : Something bogus happened, and we shouldn't fail silently. -#if 0 - JUMP schedule -#else - INT int_debug_panic -#endif - -; -; test_1 -; test_2 -; -; PURPOSE : run some verification tests on the NCR. test_1 -; copies test_src to test_dest and interrupts the host -; processor, testing for cache coherency and interrupt -; problems in the processes. -; -; test_2 runs a command with offsets relative to the -; DSA on entry, and is useful for miscellaneous experimentation. -; - -; Verify that interrupts are working correctly and that we don't -; have a cache invalidation problem. - -ABSOLUTE test_src = 0, test_dest = 0 -ENTRY test_1 -test_1: - MOVE MEMORY 4, test_src, test_dest - INT int_test_1 - -; -; Run arbitrary commands, with test code establishing a DSA -; - -ENTRY test_2 -test_2: - CLEAR TARGET - SELECT ATN FROM 0, test_2_fail - JUMP test_2_msgout, WHEN MSG_OUT -ENTRY test_2_msgout -test_2_msgout: - MOVE FROM 8, WHEN MSG_OUT - MOVE FROM 16, WHEN CMD - MOVE FROM 24, WHEN DATA_IN - MOVE FROM 32, WHEN STATUS - MOVE FROM 40, WHEN MSG_IN - MOVE SCNTL2 & 0x7f TO SCNTL2 - CLEAR ACK - WAIT DISCONNECT -test_2_fail: - INT int_test_2 - -ENTRY debug_break -debug_break: - INT int_debug_break - -; -; initiator_abort -; target_abort -; -; PURPOSE : Abort the currently established nexus from with initiator -; or target mode. -; -; - -ENTRY target_abort -target_abort: - SET TARGET - DISCONNECT - CLEAR TARGET - JUMP schedule - -ENTRY initiator_abort -initiator_abort: - SET ATN -; -; The SCSI-I specification says that targets may go into MSG out at -; their leisure upon receipt of the ATN single. On all versions of the -; specification, we can't change phases until REQ transitions true->false, -; so we need to sink/source one byte of data to allow the transition. -; -; For the sake of safety, we'll only source one byte of data in all -; cases, but to accommodate the SCSI-I dain bramage, we'll sink an -; arbitrary number of bytes. - JUMP spew_cmd, WHEN CMD - JUMP eat_msgin, WHEN MSG_IN - JUMP eat_datain, WHEN DATA_IN - JUMP eat_status, WHEN STATUS - JUMP spew_dataout, WHEN DATA_OUT - JUMP sated -spew_cmd: - MOVE 1, NCR53c7xx_zero, WHEN CMD - JUMP sated -eat_msgin: - MOVE 1, NCR53c7xx_sink, WHEN MSG_IN - JUMP eat_msgin, WHEN MSG_IN - JUMP sated -eat_status: - MOVE 1, NCR53c7xx_sink, WHEN STATUS - JUMP eat_status, WHEN STATUS - JUMP sated -eat_datain: - MOVE 1, NCR53c7xx_sink, WHEN DATA_IN - JUMP eat_datain, WHEN DATA_IN - JUMP sated -spew_dataout: - MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT -sated: - MOVE SCNTL2 & 0x7f TO SCNTL2 - MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT - WAIT DISCONNECT - INT int_norm_aborted - -; -; dsa_to_scratch -; scratch_to_dsa -; -; PURPOSE : -; The NCR chips cannot do a move memory instruction with the DSA register -; as the source or destination. So, we provide a couple of subroutines -; that let us switch between the DSA register and scratch register. -; -; Memory moves to/from the DSPS register also don't work, but we -; don't use them. -; -; - - -dsa_to_scratch: - MOVE DSA0 TO SFBR - MOVE SFBR TO SCRATCH0 - MOVE DSA1 TO SFBR - MOVE SFBR TO SCRATCH1 - MOVE DSA2 TO SFBR - MOVE SFBR TO SCRATCH2 - MOVE DSA3 TO SFBR - MOVE SFBR TO SCRATCH3 - RETURN - -scratch_to_dsa: - MOVE SCRATCH0 TO SFBR - MOVE SFBR TO DSA0 - MOVE SCRATCH1 TO SFBR - MOVE SFBR TO DSA1 - MOVE SCRATCH2 TO SFBR - MOVE SFBR TO DSA2 - MOVE SCRATCH3 TO SFBR - MOVE SFBR TO DSA3 - RETURN - diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c --- a/drivers/scsi/53c700.c Sun Feb 9 21:13:29 2003 +++ b/drivers/scsi/53c700.c Sun Feb 9 21:13:29 2003 @@ -765,8 +765,8 @@ __u8 pun = 0xff, lun = 0xff; if(SCp != NULL) { - pun = SCp->target; - lun = SCp->lun; + pun = SCp->device->id; + lun = SCp->device->lun; } switch(hostdata->msgin[2]) { @@ -846,8 +846,8 @@ __u8 pun = 0xff, lun = 0xff; if(SCp != NULL) { - pun = SCp->target; - lun = SCp->lun; + pun = SCp->device->id; + lun = SCp->device->lun; } #ifdef NCR_700_DEBUG @@ -874,7 +874,7 @@ /* rejected our first simple tag message */ printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun); NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); - hostdata->tag_negotiated &= ~(1<target); + hostdata->tag_negotiated &= ~(1<device->id); SCp->device->tagged_supported = 0; scsi_deactivate_tcq(SCp->device, host->cmd_per_lun); } else { @@ -928,8 +928,8 @@ __u8 pun = 0xff, lun=0xff; if(SCp != NULL) { - pun = SCp->target; - lun = SCp->lun; + pun = SCp->device->id; + lun = SCp->device->lun; } if(dsps == A_GOOD_STATUS_AFTER_STATUS) { @@ -963,7 +963,7 @@ NCR_700_unmap(hostdata, SCp, slot); SCp->cmnd[0] = REQUEST_SENSE; - SCp->cmnd[1] = (SCp->lun & 0x7) << 5; + SCp->cmnd[1] = (SCp->device->lun & 0x7) << 5; SCp->cmnd[2] = 0; SCp->cmnd[3] = 0; SCp->cmnd[4] = sizeof(SCp->sense_buffer); @@ -1010,11 +1010,11 @@ // DMA_FROM_DEVICE); // if(((char *)SCp->request_buffer)[7] & 0x02) { // printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun); - // hostdata->tag_negotiated |= (1<target); + // hostdata->tag_negotiated |= (1<device->id); // NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); // } else { // NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); - // hostdata->tag_negotiated &= ~(1<target); + // hostdata->tag_negotiated &= ~(1<device->id); // } //} NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); @@ -1352,7 +1352,7 @@ struct NCR_700_command_slot *slot = (struct NCR_700_command_slot *)SCp->host_scribble; struct NCR_700_Host_Parameters *hostdata = - (struct NCR_700_Host_Parameters *)SCp->host->hostdata[0]; + (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0]; __u16 count = 1; /* for IDENTIFY message */ if(hostdata->state != NCR_700_HOST_FREE) { @@ -1362,7 +1362,7 @@ slot->state = NCR_700_SLOT_QUEUED; DEBUG(("scsi%d: host busy, queueing command %p, slot %p\n", - SCp->host->host_no, slot->cmnd, slot)); + SCp->device->host->host_no, slot->cmnd, slot)); return 0; } hostdata->state = NCR_700_HOST_BUSY; @@ -1372,7 +1372,7 @@ * set up so we cannot take a selection interrupt */ hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE, - SCp->lun); + SCp->device->lun); /* for INQUIRY or REQUEST_SENSE commands, we cannot be sure * if the negotiated transfer parameters still hold, so * always renegotiate them */ @@ -1384,7 +1384,7 @@ * If a contingent allegiance condition exists, the device * will refuse all tags, so send the request sense as untagged * */ - if((hostdata->tag_negotiated & (1<target)) + if((hostdata->tag_negotiated & (1<device->id)) && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) { count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]); } @@ -1401,7 +1401,7 @@ script_patch_ID(hostdata->script, - Device_ID, 1<target); + Device_ID, 1<device->id); script_patch_32_abs(hostdata->script, CommandAddress, slot->pCmd); @@ -1410,7 +1410,7 @@ * */ script_patch_32_abs(hostdata->script, SGScriptStartAddress, to32bit(&slot->pSG[0].ins)); - NCR_700_clear_fifo(SCp->host); + NCR_700_clear_fifo(SCp->device->host); if(slot->resume_offset == 0) slot->resume_offset = hostdata->pScript; @@ -1423,9 +1423,9 @@ /* set the synchronous period/offset */ NCR_700_writeb(NCR_700_get_SXFER(SCp->device), - SCp->host, SXFER_REG); - NCR_700_writel(slot->temp, SCp->host, TEMP_REG); - NCR_700_writel(slot->resume_offset, SCp->host, DSP_REG); + SCp->device->host, SXFER_REG); + NCR_700_writel(slot->temp, SCp->device->host, TEMP_REG); + NCR_700_writel(slot->resume_offset, SCp->device->host, DSP_REG); return 1; } @@ -1479,8 +1479,8 @@ dsp, dsps)); if(SCp != NULL) { - pun = SCp->target; - lun = SCp->lun; + pun = SCp->device->id; + lun = SCp->device->lun; } if(sstat0 & SCSI_RESET_DETECTED) { @@ -1718,10 +1718,10 @@ hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0]; len += sprintf(&buf[len], "Total commands outstanding: %d\n", hostdata->command_slot_count); len += sprintf(&buf[len],"\ -Target Depth Active Next Tag\n\ -====== ===== ====== ========\n"); +Target Active Next Tag\n\ +====== ====== ========\n"); list_for_each_entry(SDp, &host->my_devices, siblings) { - len += sprintf(&buf[len]," %2d:%2d %4d %4d %4d\n", SDp->id, SDp->lun, SDp->current_queue_depth, NCR_700_get_depth(SDp), SDp->current_tag); + len += sprintf(&buf[len]," %2d:%2d %4d %4d\n", SDp->id, SDp->lun, NCR_700_get_depth(SDp), SDp->current_tag); } if((len -= offset) <= 0) return 0; @@ -1735,7 +1735,7 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *)) { struct NCR_700_Host_Parameters *hostdata = - (struct NCR_700_Host_Parameters *)SCp->host->hostdata[0]; + (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0]; __u32 move_ins; enum dma_data_direction direction; struct NCR_700_command_slot *slot; @@ -1743,7 +1743,7 @@ if(hostdata->command_slot_count >= NCR_700_COMMAND_SLOTS_PER_HOST) { /* We're over our allocation, this should never happen * since we report the max allocation to the mid layer */ - printk(KERN_WARNING "scsi%d: Command depth has gone over queue depth\n", SCp->host->host_no); + printk(KERN_WARNING "scsi%d: Command depth has gone over queue depth\n", SCp->device->host->host_no); return 1; } /* check for untagged commands. We cannot have any outstanding @@ -1753,16 +1753,16 @@ * - The blk layer sent and untagged command */ if(NCR_700_get_depth(SCp->device) != 0 - && (!(hostdata->tag_negotiated & (1<target)) + && (!(hostdata->tag_negotiated & (1<device->id)) || !blk_rq_tagged(SCp->request))) { DEBUG((KERN_ERR "scsi%d (%d:%d) has non zero depth %d\n", - SCp->host->host_no, SCp->target, SCp->lun, + SCp->device->host->host_no, SCp->device->id, SCp->device->lun, NCR_700_get_depth(SCp->device))); return SCSI_MLQUEUE_DEVICE_BUSY; } if(NCR_700_get_depth(SCp->device) >= NCR_700_MAX_TAGS) { DEBUG((KERN_ERR "scsi%d (%d:%d) has max tag depth %d\n", - SCp->host->host_no, SCp->target, SCp->lun, + SCp->device->host->host_no, SCp->device->id, SCp->device->lun, NCR_700_get_depth(SCp->device))); return SCSI_MLQUEUE_DEVICE_BUSY; } @@ -1781,11 +1781,11 @@ SCp->SCp.buffer = NULL; #ifdef NCR_700_DEBUG - printk("53c700: scsi%d, command ", SCp->host->host_no); + printk("53c700: scsi%d, command ", SCp->device->host->host_no); print_command(SCp->cmnd); #endif if(SCp->device->tagged_supported && !SCp->device->tagged_queue - && (hostdata->tag_negotiated &(1<target)) == 0 + && (hostdata->tag_negotiated &(1<device->id)) == 0 && NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) { /* upper layer has indicated tags are supported. We don't * necessarily believe it yet. @@ -1797,9 +1797,9 @@ } if(blk_rq_tagged(SCp->request) - && (hostdata->tag_negotiated &(1<target)) == 0) { - printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->target, SCp->lun); - hostdata->tag_negotiated |= (1<target); + && (hostdata->tag_negotiated &(1<device->id)) == 0) { + printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun); + hostdata->tag_negotiated |= (1<device->id); NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING); } @@ -1810,15 +1810,15 @@ * FIXME: This will royally screw up on multiple LUN devices * */ if(!blk_rq_tagged(SCp->request) - && (hostdata->tag_negotiated &(1<target))) { - printk(KERN_INFO "scsi%d: (%d:%d) Disabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->target, SCp->lun); - hostdata->tag_negotiated &= ~(1<target); + && (hostdata->tag_negotiated &(1<device->id))) { + printk(KERN_INFO "scsi%d: (%d:%d) Disabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun); + hostdata->tag_negotiated &= ~(1<device->id); } - if((hostdata->tag_negotiated &(1<target))) { + if((hostdata->tag_negotiated &(1<device->id))) { slot->tag = SCp->request->tag; DEBUG(("53c700 %d:%d:%d, sending out tag %d, slot %p\n", - SCp->host->host_no, SCp->target, SCp->lun, slot->tag, + SCp->device->host->host_no, SCp->device->id, SCp->device->lun, slot->tag, slot)); } else { slot->tag = SCSI_NO_TAG; @@ -1920,7 +1920,7 @@ struct NCR_700_command_slot *slot; printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t", - SCp->host->host_no, SCp->target, SCp->lun); + SCp->device->host->host_no, SCp->device->id, SCp->device->lun); print_command(SCp->cmnd); slot = (struct NCR_700_command_slot *)SCp->host_scribble; @@ -1939,7 +1939,7 @@ * occupying a slot. Rather than allow this to * happen, we issue a bus reset to force all * outstanding commands to terminate here. */ - NCR_700_internal_bus_reset(SCp->host); + NCR_700_internal_bus_reset(SCp->device->host); /* still drop through and return failed */ } return FAILED; @@ -1950,9 +1950,9 @@ NCR_700_bus_reset(Scsi_Cmnd * SCp) { printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t", - SCp->host->host_no, SCp->target, SCp->lun, SCp); + SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp); print_command(SCp->cmnd); - NCR_700_internal_bus_reset(SCp->host); + NCR_700_internal_bus_reset(SCp->device->host); return SUCCESS; } @@ -1960,7 +1960,7 @@ NCR_700_dev_reset(Scsi_Cmnd * SCp) { printk(KERN_INFO "scsi%d (%d:%d) New error handler wants device reset\n\t", - SCp->host->host_no, SCp->target, SCp->lun); + SCp->device->host->host_no, SCp->device->id, SCp->device->lun); print_command(SCp->cmnd); return FAILED; @@ -1970,11 +1970,11 @@ NCR_700_host_reset(Scsi_Cmnd * SCp) { printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t", - SCp->host->host_no, SCp->target, SCp->lun); + SCp->device->host->host_no, SCp->device->id, SCp->device->lun); print_command(SCp->cmnd); - NCR_700_internal_bus_reset(SCp->host); - NCR_700_chip_reset(SCp->host); + NCR_700_internal_bus_reset(SCp->device->host); + NCR_700_chip_reset(SCp->device->host); return SUCCESS; } diff -Nru a/drivers/scsi/53c8xx_d.h_shipped b/drivers/scsi/53c8xx_d.h_shipped --- a/drivers/scsi/53c8xx_d.h_shipped Sun Feb 9 21:13:31 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2678 +0,0 @@ -/* DO NOT EDIT - Generated automatically by script_asm.pl */ -static u32 SCRIPT[] = { -/* - - -; NCR 53c810 driver, main script -; Sponsored by -; iX Multiuser Multitasking Magazine -; hm@ix.de -; -; Copyright 1993, 1994, 1995 Drew Eckhardt -; Visionary Computing -; (Unix and Linux consulting and custom programming) -; drew@PoohSticks.ORG -; +1 (303) 786-7975 -; -; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation. -; -; PRE-ALPHA -; -; For more information, please consult -; -; NCR 53C810 -; PCI-SCSI I/O Processor -; Data Manual -; -; NCR 53C710 -; SCSI I/O Processor -; Programmers Guide -; -; NCR Microelectronics -; 1635 Aeroplaza Drive -; Colorado Springs, CO 80916 -; 1+ (719) 578-3400 -; -; Toll free literature number -; +1 (800) 334-5454 -; -; IMPORTANT : This code is self modifying due to the limitations of -; the NCR53c7,8xx series chips. Persons debugging this code with -; the remote debugger should take this into account, and NOT set -; breakpoints in modified instructions. -; -; Design: -; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard -; microcontroller using a simple instruction set. -; -; So, to minimize the effects of interrupt latency, and to maximize -; throughput, this driver offloads the practical maximum amount -; of processing to the SCSI chip while still maintaining a common -; structure. -; -; Where tradeoffs were needed between efficiency on the older -; chips and the newer NCR53c800 series, the NCR53c800 series -; was chosen. -; -; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully -; automate SCSI transfers without host processor intervention, this -; isn't the case with the NCR53c710 and newer chips which allow -; -; - reads and writes to the internal registers from within the SCSI -; scripts, allowing the SCSI SCRIPTS(tm) code to save processor -; state so that multiple threads of execution are possible, and also -; provide an ALU for loop control, etc. -; -; - table indirect addressing for some instructions. This allows -; pointers to be located relative to the DSA ((Data Structure -; Address) register. -; -; These features make it possible to implement a mailbox style interface, -; where the same piece of code is run to handle I/O for multiple threads -; at once minimizing our need to relocate code. Since the NCR53c700/ -; NCR53c800 series have a unique combination of features, making a -; a standard ingoing/outgoing mailbox system, costly, I've modified it. -; -; - Mailboxes are a mixture of code and data. This lets us greatly -; simplify the NCR53c810 code and do things that would otherwise -; not be possible. -; -; The saved data pointer is now implemented as follows : -; -; Control flow has been architected such that if control reaches -; munge_save_data_pointer, on a restore pointers message or -; reconnection, a jump to the address formerly in the TEMP register -; will allow the SCSI command to resume execution. -; - -; -; Note : the DSA structures must be aligned on 32 bit boundaries, -; since the source and destination of MOVE MEMORY instructions -; must share the same alignment and this is the alignment of the -; NCR registers. -; - -ABSOLUTE dsa_temp_lun = 0 ; Patch to lun for current dsa -ABSOLUTE dsa_temp_next = 0 ; Patch to dsa next for current dsa -ABSOLUTE dsa_temp_addr_next = 0 ; Patch to address of dsa next address - ; for current dsa -ABSOLUTE dsa_temp_sync = 0 ; Patch to address of per-target - ; sync routine -ABSOLUTE dsa_temp_target = 0 ; Patch to id for current dsa -ABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command - ; saved data pointer -ABSOLUTE dsa_temp_addr_residual = 0 ; Patch to address of per-command - ; current residual code -ABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command - ; saved residual code -ABSOLUTE dsa_temp_addr_new_value = 0 ; Address of value for JUMP operand -ABSOLUTE dsa_temp_addr_array_value = 0 ; Address to copy to -ABSOLUTE dsa_temp_addr_dsa_value = 0 ; Address of this DSA value - -; -; Once a device has initiated reselection, we need to compare it -; against the singly linked list of commands which have disconnected -; and are pending reselection. These commands are maintained in -; an unordered singly linked list of DSA structures, through the -; DSA pointers at their 'centers' headed by the reconnect_dsa_head -; pointer. -; -; To avoid complications in removing commands from the list, -; I minimize the amount of expensive (at eight operations per -; addition @ 500-600ns each) pointer operations which must -; be done in the NCR driver by precomputing them on the -; host processor during dsa structure generation. -; -; The fixed-up per DSA code knows how to recognize the nexus -; associated with the corresponding SCSI command, and modifies -; the source and destination pointers for the MOVE MEMORY -; instruction which is executed when reselected_ok is called -; to remove the command from the list. Similarly, DSA is -; loaded with the address of the next DSA structure and -; reselected_check_next is called if a failure occurs. -; -; Perhaps more concisely, the net effect of the mess is -; -; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head, -; src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) { -; src = &dsa->next; -; if (target_id == dsa->id && target_lun == dsa->lun) { -; *dest = *src; -; break; -; } -; } -; -; if (!dsa) -; error (int_err_unexpected_reselect); -; else -; longjmp (dsa->jump_resume, 0); -; -; - - -; Define DSA structure used for mailboxes -ENTRY dsa_code_template -dsa_code_template: -ENTRY dsa_code_begin -dsa_code_begin: - MOVE dmode_memory_to_ncr TO DMODE - -at 0x00000000 : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch - -at 0x00000002 : */ 0xc0000004,0x00000000,0x00000000, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x00000005 : */ 0x78380000,0x00000000, -/* - CALL scratch_to_dsa - -at 0x00000007 : */ 0x88080000,0x00000980, -/* - CALL select - -at 0x00000009 : */ 0x88080000,0x000001fc, -/* -; Handle the phase mismatch which may have resulted from the -; MOVE FROM dsa_msgout if we returned here. The CLEAR ATN -; may or may not be necessary, and we should update script_asm.pl -; to handle multiple pieces. - CLEAR ATN - -at 0x0000000b : */ 0x60000008,0x00000000, -/* - CLEAR ACK - -at 0x0000000d : */ 0x60000040,0x00000000, -/* - -; Replace second operand with address of JUMP instruction dest operand -; in schedule table for this DSA. Becomes dsa_jump_dest in 53c7,8xx.c. -ENTRY dsa_code_fix_jump -dsa_code_fix_jump: - MOVE MEMORY 4, NOP_insn, 0 - -at 0x0000000f : */ 0xc0000004,0x00000000,0x00000000, -/* - JUMP select_done - -at 0x00000012 : */ 0x80080000,0x00000224, -/* - -; wrong_dsa loads the DSA register with the value of the dsa_next -; field. -; -wrong_dsa: -; Patch the MOVE MEMORY INSTRUCTION such that -; the destination address is the address of the OLD -; next pointer. -; - MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 8 - -at 0x00000014 : */ 0xc0000004,0x00000000,0x00000758, -/* - MOVE dmode_memory_to_ncr TO DMODE - -at 0x00000017 : */ 0x78380000,0x00000000, -/* -; -; Move the _contents_ of the next pointer into the DSA register as -; the next I_T_L or I_T_L_Q tupple to check against the established -; nexus. -; - MOVE MEMORY 4, dsa_temp_next, addr_scratch - -at 0x00000019 : */ 0xc0000004,0x00000000,0x00000000, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x0000001c : */ 0x78380000,0x00000000, -/* - CALL scratch_to_dsa - -at 0x0000001e : */ 0x88080000,0x00000980, -/* - JUMP reselected_check_next - -at 0x00000020 : */ 0x80080000,0x000006a4, -/* - -ABSOLUTE dsa_save_data_pointer = 0 -ENTRY dsa_code_save_data_pointer -dsa_code_save_data_pointer: - MOVE dmode_ncr_to_memory TO DMODE - -at 0x00000022 : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 4, addr_temp, dsa_temp_addr_saved_pointer - -at 0x00000024 : */ 0xc0000004,0x00000000,0x00000000, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x00000027 : */ 0x78380000,0x00000000, -/* -; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h - MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual - -at 0x00000029 : */ 0xc0000018,0x00000000,0x00000000, -/* - CLEAR ACK - -at 0x0000002c : */ 0x60000040,0x00000000, -/* - - - - RETURN - -at 0x0000002e : */ 0x90080000,0x00000000, -/* -ABSOLUTE dsa_restore_pointers = 0 -ENTRY dsa_code_restore_pointers -dsa_code_restore_pointers: - MOVE dmode_memory_to_ncr TO DMODE - -at 0x00000030 : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 4, dsa_temp_addr_saved_pointer, addr_temp - -at 0x00000032 : */ 0xc0000004,0x00000000,0x00000000, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x00000035 : */ 0x78380000,0x00000000, -/* -; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h - MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual - -at 0x00000037 : */ 0xc0000018,0x00000000,0x00000000, -/* - CLEAR ACK - -at 0x0000003a : */ 0x60000040,0x00000000, -/* - - - - RETURN - -at 0x0000003c : */ 0x90080000,0x00000000, -/* - -ABSOLUTE dsa_check_reselect = 0 -; dsa_check_reselect determines whether or not the current target and -; lun match the current DSA -ENTRY dsa_code_check_reselect -dsa_code_check_reselect: - MOVE SSID TO SFBR ; SSID contains 3 bit target ID - -at 0x0000003e : */ 0x720a0000,0x00000000, -/* -; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips - JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0xf8 - -at 0x00000040 : */ 0x8084f800,0x00ffff48, -/* -; -; Hack - move to scratch first, since SFBR is not writeable -; via the CPU and hence a MOVE MEMORY instruction. -; - MOVE dmode_memory_to_ncr TO DMODE - -at 0x00000042 : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 1, reselected_identify, addr_scratch - -at 0x00000044 : */ 0xc0000001,0x00000000,0x00000000, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x00000047 : */ 0x78380000,0x00000000, -/* - MOVE SCRATCH0 TO SFBR - -at 0x00000049 : */ 0x72340000,0x00000000, -/* -; FIXME : we need to accommodate bit fielded and binary here for '7xx/'8xx chips - JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8 - -at 0x0000004b : */ 0x8084f800,0x00ffff1c, -/* -; Patch the MOVE MEMORY INSTRUCTION such that -; the source address is the address of this dsa's -; next pointer. - MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 4 - -at 0x0000004d : */ 0xc0000004,0x00000000,0x00000754, -/* - CALL reselected_ok - -at 0x00000050 : */ 0x88080000,0x00000750, -/* - CALL dsa_temp_sync - -at 0x00000052 : */ 0x88080000,0x00000000, -/* -; Release ACK on the IDENTIFY message _after_ we've set the synchronous -; transfer parameters! - CLEAR ACK - -at 0x00000054 : */ 0x60000040,0x00000000, -/* -; Implicitly restore pointers on reselection, so a RETURN -; will transfer control back to the right spot. - CALL REL (dsa_code_restore_pointers) - -at 0x00000056 : */ 0x88880000,0x00ffff60, -/* - RETURN - -at 0x00000058 : */ 0x90080000,0x00000000, -/* -ENTRY dsa_zero -dsa_zero: -ENTRY dsa_code_template_end -dsa_code_template_end: - -; Perform sanity check for dsa_fields_start == dsa_code_template_end - -; dsa_zero, puke. - -ABSOLUTE dsa_fields_start = 0 ; Sanity marker - ; pad 48 bytes (fix this RSN) -ABSOLUTE dsa_next = 48 ; len 4 Next DSA - ; del 4 Previous DSA address -ABSOLUTE dsa_cmnd = 56 ; len 4 Scsi_Cmnd * for this thread. -ABSOLUTE dsa_select = 60 ; len 4 Device ID, Period, Offset for - ; table indirect select -ABSOLUTE dsa_msgout = 64 ; len 8 table indirect move parameter for - ; select message -ABSOLUTE dsa_cmdout = 72 ; len 8 table indirect move parameter for - ; command -ABSOLUTE dsa_dataout = 80 ; len 4 code pointer for dataout -ABSOLUTE dsa_datain = 84 ; len 4 code pointer for datain -ABSOLUTE dsa_msgin = 88 ; len 8 table indirect move for msgin -ABSOLUTE dsa_status = 96 ; len 8 table indirect move for status byte -ABSOLUTE dsa_msgout_other = 104 ; len 8 table indirect for normal message out - ; (Synchronous transfer negotiation, etc). -ABSOLUTE dsa_end = 112 - -ABSOLUTE schedule = 0 ; Array of JUMP dsa_begin or JUMP (next), - ; terminated by a call to JUMP wait_reselect - -; Linked lists of DSA structures -ABSOLUTE reconnect_dsa_head = 0 ; Link list of DSAs which can reconnect -ABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable containing - ; address of reconnect_dsa_head - -; These select the source and destination of a MOVE MEMORY instruction -ABSOLUTE dmode_memory_to_memory = 0x0 -ABSOLUTE dmode_memory_to_ncr = 0x0 -ABSOLUTE dmode_ncr_to_memory = 0x0 - -ABSOLUTE addr_scratch = 0x0 -ABSOLUTE addr_temp = 0x0 - - -; Interrupts - -; MSB indicates type -; 0 handle error condition -; 1 handle message -; 2 handle normal condition -; 3 debugging interrupt -; 4 testing interrupt -; Next byte indicates specific error - -; XXX not yet implemented, I'm not sure if I want to - -; Next byte indicates the routine the error occurred in -; The LSB indicates the specific place the error occurred - -ABSOLUTE int_err_unexpected_phase = 0x00000000 ; Unexpected phase encountered -ABSOLUTE int_err_selected = 0x00010000 ; SELECTED (nee RESELECTED) -ABSOLUTE int_err_unexpected_reselect = 0x00020000 -ABSOLUTE int_err_check_condition = 0x00030000 -ABSOLUTE int_err_no_phase = 0x00040000 -ABSOLUTE int_msg_wdtr = 0x01000000 ; WDTR message received -ABSOLUTE int_msg_sdtr = 0x01010000 ; SDTR received -ABSOLUTE int_msg_1 = 0x01020000 ; single byte special message - ; received - -ABSOLUTE int_norm_select_complete = 0x02000000 ; Select complete, reprogram - ; registers. -ABSOLUTE int_norm_reselect_complete = 0x02010000 ; Nexus established -ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete -ABSOLUTE int_norm_disconnected = 0x02030000 ; Disconnected -ABSOLUTE int_norm_aborted =0x02040000 ; Aborted *dsa -ABSOLUTE int_norm_reset = 0x02050000 ; Generated BUS reset. -ABSOLUTE int_debug_break = 0x03000000 ; Break point - -ABSOLUTE int_debug_panic = 0x030b0000 ; Panic driver - - -ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete -ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete -ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete - - -; These should start with 0x05000000, with low bits incrementing for -; each one. - - - -ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message -ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message -ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source -ABSOLUTE NCR53c7xx_sink = 0 ; long to dump worthless data in -ABSOLUTE NOP_insn = 0 ; NOP instruction - -; Pointer to message, potentially multi-byte -ABSOLUTE msg_buf = 0 - -; Pointer to holding area for reselection information -ABSOLUTE reselected_identify = 0 -ABSOLUTE reselected_tag = 0 - -; Request sense command pointer, it's a 6 byte command, should -; be constant for all commands since we always want 16 bytes of -; sense and we don't need to change any fields as we did under -; SCSI-I when we actually cared about the LUN field. -;EXTERNAL NCR53c7xx_sense ; Request sense command - - -; dsa_schedule -; PURPOSE : after a DISCONNECT message has been received, and pointers -; saved, insert the current DSA structure at the head of the -; disconnected queue and fall through to the scheduler. -; -; CALLS : OK -; -; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list -; of disconnected commands -; -; MODIFIES : SCRATCH, reconnect_dsa_head -; -; EXITS : always passes control to schedule - -ENTRY dsa_schedule -dsa_schedule: - - - - -; -; Calculate the address of the next pointer within the DSA -; structure of the command that is currently disconnecting -; - CALL dsa_to_scratch - -at 0x0000005a : */ 0x88080000,0x00000938, -/* - MOVE SCRATCH0 + dsa_next TO SCRATCH0 - -at 0x0000005c : */ 0x7e343000,0x00000000, -/* - MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY - -at 0x0000005e : */ 0x7f350000,0x00000000, -/* - MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY - -at 0x00000060 : */ 0x7f360000,0x00000000, -/* - MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY - -at 0x00000062 : */ 0x7f370000,0x00000000, -/* - -; Point the next field of this DSA structure at the current disconnected -; list - MOVE dmode_ncr_to_memory TO DMODE - -at 0x00000064 : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8 - -at 0x00000066 : */ 0xc0000004,0x00000000,0x000001b4, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x00000069 : */ 0x78380000,0x00000000, -/* -dsa_schedule_insert: - MOVE MEMORY 4, reconnect_dsa_head, 0 - -at 0x0000006b : */ 0xc0000004,0x00000000,0x00000000, -/* - -; And update the head pointer. - CALL dsa_to_scratch - -at 0x0000006e : */ 0x88080000,0x00000938, -/* - MOVE dmode_ncr_to_memory TO DMODE - -at 0x00000070 : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 4, addr_scratch, reconnect_dsa_head - -at 0x00000072 : */ 0xc0000004,0x00000000,0x00000000, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x00000075 : */ 0x78380000,0x00000000, -/* - - - MOVE SCNTL2 & 0x7f TO SCNTL2 - -at 0x00000077 : */ 0x7c027f00,0x00000000, -/* - CLEAR ACK - -at 0x00000079 : */ 0x60000040,0x00000000, -/* - - WAIT DISCONNECT - -at 0x0000007b : */ 0x48000000,0x00000000, -/* - - - - - - - JUMP schedule - -at 0x0000007d : */ 0x80080000,0x00000000, -/* - - -; -; select -; -; PURPOSE : establish a nexus for the SCSI command referenced by DSA. -; On success, the current DSA structure is removed from the issue -; queue. Usually, this is entered as a fall-through from schedule, -; although the contingent allegiance handling code will write -; the select entry address to the DSP to restart a command as a -; REQUEST SENSE. A message is sent (usually IDENTIFY, although -; additional SDTR or WDTR messages may be sent). COMMAND OUT -; is handled. -; -; INPUTS : DSA - SCSI command, issue_dsa_head -; -; CALLS : NOT OK -; -; MODIFIES : SCRATCH, issue_dsa_head -; -; EXITS : on reselection or selection, go to select_failed -; otherwise, RETURN so control is passed back to -; dsa_begin. -; - -ENTRY select -select: - - - - - - - - - - - - - CLEAR TARGET - -at 0x0000007f : */ 0x60000200,0x00000000, -/* - -; XXX -; -; In effect, SELECTION operations are backgrounded, with execution -; continuing until code which waits for REQ or a fatal interrupt is -; encountered. -; -; So, for more performance, we could overlap the code which removes -; the command from the NCRs issue queue with the selection, but -; at this point I don't want to deal with the error recovery. -; - - - SELECT ATN FROM dsa_select, select_failed - -at 0x00000081 : */ 0x4300003c,0x000007a4, -/* - JUMP select_msgout, WHEN MSG_OUT - -at 0x00000083 : */ 0x860b0000,0x00000214, -/* -ENTRY select_msgout -select_msgout: - MOVE FROM dsa_msgout, WHEN MSG_OUT - -at 0x00000085 : */ 0x1e000000,0x00000040, -/* - - - - - - - - - - - RETURN - -at 0x00000087 : */ 0x90080000,0x00000000, -/* - -; -; select_done -; -; PURPOSE: continue on to normal data transfer; called as the exit -; point from dsa_begin. -; -; INPUTS: dsa -; -; CALLS: OK -; -; - -select_done: - - - - - - - -; After a successful selection, we should get either a CMD phase or -; some transfer request negotiation message. - - JUMP cmdout, WHEN CMD - -at 0x00000089 : */ 0x820b0000,0x00000244, -/* - INT int_err_unexpected_phase, WHEN NOT MSG_IN - -at 0x0000008b : */ 0x9f030000,0x00000000, -/* - -select_msg_in: - CALL msg_in, WHEN MSG_IN - -at 0x0000008d : */ 0x8f0b0000,0x00000404, -/* - JUMP select_msg_in, WHEN MSG_IN - -at 0x0000008f : */ 0x870b0000,0x00000234, -/* - -cmdout: - INT int_err_unexpected_phase, WHEN NOT CMD - -at 0x00000091 : */ 0x9a030000,0x00000000, -/* - - - -ENTRY cmdout_cmdout -cmdout_cmdout: - - MOVE FROM dsa_cmdout, WHEN CMD - -at 0x00000093 : */ 0x1a000000,0x00000048, -/* - - - - -; -; data_transfer -; other_out -; other_in -; other_transfer -; -; PURPOSE : handle the main data transfer for a SCSI command in -; several parts. In the first part, data_transfer, DATA_IN -; and DATA_OUT phases are allowed, with the user provided -; code (usually dynamically generated based on the scatter/gather -; list associated with a SCSI command) called to handle these -; phases. -; -; After control has passed to one of the user provided -; DATA_IN or DATA_OUT routines, back calls are made to -; other_transfer_in or other_transfer_out to handle non-DATA IN -; and DATA OUT phases respectively, with the state of the active -; data pointer being preserved in TEMP. -; -; On completion, the user code passes control to other_transfer -; which causes DATA_IN and DATA_OUT to result in unexpected_phase -; interrupts so that data overruns may be trapped. -; -; INPUTS : DSA - SCSI command -; -; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in -; other_transfer -; -; MODIFIES : SCRATCH -; -; EXITS : if STATUS IN is detected, signifying command completion, -; the NCR jumps to command_complete. If MSG IN occurs, a -; CALL is made to msg_in. Otherwise, other_transfer runs in -; an infinite loop. -; - -ENTRY data_transfer -data_transfer: - JUMP cmdout_cmdout, WHEN CMD - -at 0x00000095 : */ 0x820b0000,0x0000024c, -/* - CALL msg_in, WHEN MSG_IN - -at 0x00000097 : */ 0x8f0b0000,0x00000404, -/* - INT int_err_unexpected_phase, WHEN MSG_OUT - -at 0x00000099 : */ 0x9e0b0000,0x00000000, -/* - JUMP do_dataout, WHEN DATA_OUT - -at 0x0000009b : */ 0x800b0000,0x0000028c, -/* - JUMP do_datain, WHEN DATA_IN - -at 0x0000009d : */ 0x810b0000,0x000002e4, -/* - JUMP command_complete, WHEN STATUS - -at 0x0000009f : */ 0x830b0000,0x0000060c, -/* - JUMP data_transfer - -at 0x000000a1 : */ 0x80080000,0x00000254, -/* -ENTRY end_data_transfer -end_data_transfer: - -; -; FIXME: On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain -; should be fixed up whenever the nexus changes so it can point to the -; correct routine for that command. -; - - -; Nasty jump to dsa->dataout -do_dataout: - CALL dsa_to_scratch - -at 0x000000a3 : */ 0x88080000,0x00000938, -/* - MOVE SCRATCH0 + dsa_dataout TO SCRATCH0 - -at 0x000000a5 : */ 0x7e345000,0x00000000, -/* - MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY - -at 0x000000a7 : */ 0x7f350000,0x00000000, -/* - MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY - -at 0x000000a9 : */ 0x7f360000,0x00000000, -/* - MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY - -at 0x000000ab : */ 0x7f370000,0x00000000, -/* - MOVE dmode_ncr_to_memory TO DMODE - -at 0x000000ad : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4 - -at 0x000000af : */ 0xc0000004,0x00000000,0x000002d4, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x000000b2 : */ 0x78380000,0x00000000, -/* -dataout_to_jump: - MOVE MEMORY 4, 0, dataout_jump + 4 - -at 0x000000b4 : */ 0xc0000004,0x00000000,0x000002e0, -/* -dataout_jump: - JUMP 0 - -at 0x000000b7 : */ 0x80080000,0x00000000, -/* - -; Nasty jump to dsa->dsain -do_datain: - CALL dsa_to_scratch - -at 0x000000b9 : */ 0x88080000,0x00000938, -/* - MOVE SCRATCH0 + dsa_datain TO SCRATCH0 - -at 0x000000bb : */ 0x7e345400,0x00000000, -/* - MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY - -at 0x000000bd : */ 0x7f350000,0x00000000, -/* - MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY - -at 0x000000bf : */ 0x7f360000,0x00000000, -/* - MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY - -at 0x000000c1 : */ 0x7f370000,0x00000000, -/* - MOVE dmode_ncr_to_memory TO DMODE - -at 0x000000c3 : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 4, addr_scratch, datain_to_jump + 4 - -at 0x000000c5 : */ 0xc0000004,0x00000000,0x0000032c, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x000000c8 : */ 0x78380000,0x00000000, -/* -ENTRY datain_to_jump -datain_to_jump: - MOVE MEMORY 4, 0, datain_jump + 4 - -at 0x000000ca : */ 0xc0000004,0x00000000,0x00000338, -/* - - - -datain_jump: - JUMP 0 - -at 0x000000cd : */ 0x80080000,0x00000000, -/* - - - -; Note that other_out and other_in loop until a non-data phase -; is discovered, so we only execute return statements when we -; can go on to the next data phase block move statement. - -ENTRY other_out -other_out: - - - - INT int_err_unexpected_phase, WHEN CMD - -at 0x000000cf : */ 0x9a0b0000,0x00000000, -/* - JUMP msg_in_restart, WHEN MSG_IN - -at 0x000000d1 : */ 0x870b0000,0x000003e4, -/* - INT int_err_unexpected_phase, WHEN MSG_OUT - -at 0x000000d3 : */ 0x9e0b0000,0x00000000, -/* - INT int_err_unexpected_phase, WHEN DATA_IN - -at 0x000000d5 : */ 0x990b0000,0x00000000, -/* - JUMP command_complete, WHEN STATUS - -at 0x000000d7 : */ 0x830b0000,0x0000060c, -/* - JUMP other_out, WHEN NOT DATA_OUT - -at 0x000000d9 : */ 0x80030000,0x0000033c, -/* - RETURN - -at 0x000000db : */ 0x90080000,0x00000000, -/* - -ENTRY other_in -other_in: - - - - INT int_err_unexpected_phase, WHEN CMD - -at 0x000000dd : */ 0x9a0b0000,0x00000000, -/* - JUMP msg_in_restart, WHEN MSG_IN - -at 0x000000df : */ 0x870b0000,0x000003e4, -/* - INT int_err_unexpected_phase, WHEN MSG_OUT - -at 0x000000e1 : */ 0x9e0b0000,0x00000000, -/* - INT int_err_unexpected_phase, WHEN DATA_OUT - -at 0x000000e3 : */ 0x980b0000,0x00000000, -/* - JUMP command_complete, WHEN STATUS - -at 0x000000e5 : */ 0x830b0000,0x0000060c, -/* - JUMP other_in, WHEN NOT DATA_IN - -at 0x000000e7 : */ 0x81030000,0x00000374, -/* - RETURN - -at 0x000000e9 : */ 0x90080000,0x00000000, -/* - - -ENTRY other_transfer -other_transfer: - INT int_err_unexpected_phase, WHEN CMD - -at 0x000000eb : */ 0x9a0b0000,0x00000000, -/* - CALL msg_in, WHEN MSG_IN - -at 0x000000ed : */ 0x8f0b0000,0x00000404, -/* - INT int_err_unexpected_phase, WHEN MSG_OUT - -at 0x000000ef : */ 0x9e0b0000,0x00000000, -/* - INT int_err_unexpected_phase, WHEN DATA_OUT - -at 0x000000f1 : */ 0x980b0000,0x00000000, -/* - INT int_err_unexpected_phase, WHEN DATA_IN - -at 0x000000f3 : */ 0x990b0000,0x00000000, -/* - JUMP command_complete, WHEN STATUS - -at 0x000000f5 : */ 0x830b0000,0x0000060c, -/* - JUMP other_transfer - -at 0x000000f7 : */ 0x80080000,0x000003ac, -/* - -; -; msg_in_restart -; msg_in -; munge_msg -; -; PURPOSE : process messages from a target. msg_in is called when the -; caller hasn't read the first byte of the message. munge_message -; is called when the caller has read the first byte of the message, -; and left it in SFBR. msg_in_restart is called when the caller -; hasn't read the first byte of the message, and wishes RETURN -; to transfer control back to the address of the conditional -; CALL instruction rather than to the instruction after it. -; -; Various int_* interrupts are generated when the host system -; needs to intervene, as is the case with SDTR, WDTR, and -; INITIATE RECOVERY messages. -; -; When the host system handles one of these interrupts, -; it can respond by reentering at reject_message, -; which rejects the message and returns control to -; the caller of msg_in or munge_msg, accept_message -; which clears ACK and returns control, or reply_message -; which sends the message pointed to by the DSA -; msgout_other table indirect field. -; -; DISCONNECT messages are handled by moving the command -; to the reconnect_dsa_queue. -; -; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg -; only) -; -; CALLS : NO. The TEMP register isn't backed up to allow nested calls. -; -; MODIFIES : SCRATCH, DSA on DISCONNECT -; -; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS, -; and normal return from message handlers running under -; Linux, control is returned to the caller. Receipt -; of DISCONNECT messages pass control to dsa_schedule. -; -ENTRY msg_in_restart -msg_in_restart: -; XXX - hackish -; -; Since it's easier to debug changes to the statically -; compiled code, rather than the dynamically generated -; stuff, such as -; -; MOVE x, y, WHEN data_phase -; CALL other_z, WHEN NOT data_phase -; MOVE x, y, WHEN data_phase -; -; I'd like to have certain routines (notably the message handler) -; restart on the conditional call rather than the next instruction. -; -; So, subtract 8 from the return address - - MOVE TEMP0 + 0xf8 TO TEMP0 - -at 0x000000f9 : */ 0x7e1cf800,0x00000000, -/* - MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY - -at 0x000000fb : */ 0x7f1dff00,0x00000000, -/* - MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY - -at 0x000000fd : */ 0x7f1eff00,0x00000000, -/* - MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY - -at 0x000000ff : */ 0x7f1fff00,0x00000000, -/* - -ENTRY msg_in -msg_in: - MOVE 1, msg_buf, WHEN MSG_IN - -at 0x00000101 : */ 0x0f000001,0x00000000, -/* - -munge_msg: - JUMP munge_extended, IF 0x01 ; EXTENDED MESSAGE - -at 0x00000103 : */ 0x800c0001,0x00000524, -/* - JUMP munge_2, IF 0x20, AND MASK 0xdf ; two byte message - -at 0x00000105 : */ 0x800cdf20,0x0000044c, -/* -; -; XXX - I've seen a handful of broken SCSI devices which fail to issue -; a SAVE POINTERS message before disconnecting in the middle of -; a transfer, assuming that the DATA POINTER will be implicitly -; restored. -; -; Historically, I've often done an implicit save when the DISCONNECT -; message is processed. We may want to consider having the option of -; doing that here. -; - JUMP munge_save_data_pointer, IF 0x02 ; SAVE DATA POINTER - -at 0x00000107 : */ 0x800c0002,0x00000454, -/* - JUMP munge_restore_pointers, IF 0x03 ; RESTORE POINTERS - -at 0x00000109 : */ 0x800c0003,0x000004b8, -/* - JUMP munge_disconnect, IF 0x04 ; DISCONNECT - -at 0x0000010b : */ 0x800c0004,0x0000051c, -/* - INT int_msg_1, IF 0x07 ; MESSAGE REJECT - -at 0x0000010d : */ 0x980c0007,0x01020000, -/* - INT int_msg_1, IF 0x0f ; INITIATE RECOVERY - -at 0x0000010f : */ 0x980c000f,0x01020000, -/* - - - - JUMP reject_message - -at 0x00000111 : */ 0x80080000,0x000005b4, -/* - -munge_2: - JUMP reject_message - -at 0x00000113 : */ 0x80080000,0x000005b4, -/* -; -; The SCSI standard allows targets to recover from transient -; error conditions by backing up the data pointer with a -; RESTORE POINTERS message. -; -; So, we must save and restore the _residual_ code as well as -; the current instruction pointer. Because of this messiness, -; it is simpler to put dynamic code in the dsa for this and to -; just do a simple jump down there. -; - -munge_save_data_pointer: - MOVE DSA0 + dsa_save_data_pointer TO SFBR - -at 0x00000115 : */ 0x76100000,0x00000000, -/* - MOVE SFBR TO SCRATCH0 - -at 0x00000117 : */ 0x6a340000,0x00000000, -/* - MOVE DSA1 + 0xff TO SFBR WITH CARRY - -at 0x00000119 : */ 0x7711ff00,0x00000000, -/* - MOVE SFBR TO SCRATCH1 - -at 0x0000011b : */ 0x6a350000,0x00000000, -/* - MOVE DSA2 + 0xff TO SFBR WITH CARRY - -at 0x0000011d : */ 0x7712ff00,0x00000000, -/* - MOVE SFBR TO SCRATCH2 - -at 0x0000011f : */ 0x6a360000,0x00000000, -/* - MOVE DSA3 + 0xff TO SFBR WITH CARRY - -at 0x00000121 : */ 0x7713ff00,0x00000000, -/* - MOVE SFBR TO SCRATCH3 - -at 0x00000123 : */ 0x6a370000,0x00000000, -/* - - MOVE dmode_ncr_to_memory TO DMODE - -at 0x00000125 : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4 - -at 0x00000127 : */ 0xc0000004,0x00000000,0x000004b4, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x0000012a : */ 0x78380000,0x00000000, -/* -jump_dsa_save: - JUMP 0 - -at 0x0000012c : */ 0x80080000,0x00000000, -/* - -munge_restore_pointers: - MOVE DSA0 + dsa_restore_pointers TO SFBR - -at 0x0000012e : */ 0x76100000,0x00000000, -/* - MOVE SFBR TO SCRATCH0 - -at 0x00000130 : */ 0x6a340000,0x00000000, -/* - MOVE DSA1 + 0xff TO SFBR WITH CARRY - -at 0x00000132 : */ 0x7711ff00,0x00000000, -/* - MOVE SFBR TO SCRATCH1 - -at 0x00000134 : */ 0x6a350000,0x00000000, -/* - MOVE DSA2 + 0xff TO SFBR WITH CARRY - -at 0x00000136 : */ 0x7712ff00,0x00000000, -/* - MOVE SFBR TO SCRATCH2 - -at 0x00000138 : */ 0x6a360000,0x00000000, -/* - MOVE DSA3 + 0xff TO SFBR WITH CARRY - -at 0x0000013a : */ 0x7713ff00,0x00000000, -/* - MOVE SFBR TO SCRATCH3 - -at 0x0000013c : */ 0x6a370000,0x00000000, -/* - - MOVE dmode_ncr_to_memory TO DMODE - -at 0x0000013e : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4 - -at 0x00000140 : */ 0xc0000004,0x00000000,0x00000518, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x00000143 : */ 0x78380000,0x00000000, -/* -jump_dsa_restore: - JUMP 0 - -at 0x00000145 : */ 0x80080000,0x00000000, -/* - - -munge_disconnect: - - - - - - - - - - - - - - - - - JUMP dsa_schedule - -at 0x00000147 : */ 0x80080000,0x00000168, -/* - - - - - -munge_extended: - CLEAR ACK - -at 0x00000149 : */ 0x60000040,0x00000000, -/* - INT int_err_unexpected_phase, WHEN NOT MSG_IN - -at 0x0000014b : */ 0x9f030000,0x00000000, -/* - MOVE 1, msg_buf + 1, WHEN MSG_IN - -at 0x0000014d : */ 0x0f000001,0x00000001, -/* - JUMP munge_extended_2, IF 0x02 - -at 0x0000014f : */ 0x800c0002,0x00000554, -/* - JUMP munge_extended_3, IF 0x03 - -at 0x00000151 : */ 0x800c0003,0x00000584, -/* - JUMP reject_message - -at 0x00000153 : */ 0x80080000,0x000005b4, -/* - -munge_extended_2: - CLEAR ACK - -at 0x00000155 : */ 0x60000040,0x00000000, -/* - MOVE 1, msg_buf + 2, WHEN MSG_IN - -at 0x00000157 : */ 0x0f000001,0x00000002, -/* - JUMP reject_message, IF NOT 0x02 ; Must be WDTR - -at 0x00000159 : */ 0x80040002,0x000005b4, -/* - CLEAR ACK - -at 0x0000015b : */ 0x60000040,0x00000000, -/* - MOVE 1, msg_buf + 3, WHEN MSG_IN - -at 0x0000015d : */ 0x0f000001,0x00000003, -/* - INT int_msg_wdtr - -at 0x0000015f : */ 0x98080000,0x01000000, -/* - -munge_extended_3: - CLEAR ACK - -at 0x00000161 : */ 0x60000040,0x00000000, -/* - MOVE 1, msg_buf + 2, WHEN MSG_IN - -at 0x00000163 : */ 0x0f000001,0x00000002, -/* - JUMP reject_message, IF NOT 0x01 ; Must be SDTR - -at 0x00000165 : */ 0x80040001,0x000005b4, -/* - CLEAR ACK - -at 0x00000167 : */ 0x60000040,0x00000000, -/* - MOVE 2, msg_buf + 3, WHEN MSG_IN - -at 0x00000169 : */ 0x0f000002,0x00000003, -/* - INT int_msg_sdtr - -at 0x0000016b : */ 0x98080000,0x01010000, -/* - -ENTRY reject_message -reject_message: - SET ATN - -at 0x0000016d : */ 0x58000008,0x00000000, -/* - CLEAR ACK - -at 0x0000016f : */ 0x60000040,0x00000000, -/* - MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT - -at 0x00000171 : */ 0x0e000001,0x00000000, -/* - RETURN - -at 0x00000173 : */ 0x90080000,0x00000000, -/* - -ENTRY accept_message -accept_message: - CLEAR ATN - -at 0x00000175 : */ 0x60000008,0x00000000, -/* - CLEAR ACK - -at 0x00000177 : */ 0x60000040,0x00000000, -/* - RETURN - -at 0x00000179 : */ 0x90080000,0x00000000, -/* - -ENTRY respond_message -respond_message: - SET ATN - -at 0x0000017b : */ 0x58000008,0x00000000, -/* - CLEAR ACK - -at 0x0000017d : */ 0x60000040,0x00000000, -/* - MOVE FROM dsa_msgout_other, WHEN MSG_OUT - -at 0x0000017f : */ 0x1e000000,0x00000068, -/* - RETURN - -at 0x00000181 : */ 0x90080000,0x00000000, -/* - -; -; command_complete -; -; PURPOSE : handle command termination when STATUS IN is detected by reading -; a status byte followed by a command termination message. -; -; Normal termination results in an INTFLY instruction, and -; the host system can pick out which command terminated by -; examining the MESSAGE and STATUS buffers of all currently -; executing commands; -; -; Abnormal (CHECK_CONDITION) termination results in an -; int_err_check_condition interrupt so that a REQUEST SENSE -; command can be issued out-of-order so that no other command -; clears the contingent allegiance condition. -; -; -; INPUTS : DSA - command -; -; CALLS : OK -; -; EXITS : On successful termination, control is passed to schedule. -; On abnormal termination, the user will usually modify the -; DSA fields and corresponding buffers and return control -; to select. -; - -ENTRY command_complete -command_complete: - MOVE FROM dsa_status, WHEN STATUS - -at 0x00000183 : */ 0x1b000000,0x00000060, -/* - - MOVE SFBR TO SCRATCH0 ; Save status - -at 0x00000185 : */ 0x6a340000,0x00000000, -/* - -ENTRY command_complete_msgin -command_complete_msgin: - MOVE FROM dsa_msgin, WHEN MSG_IN - -at 0x00000187 : */ 0x1f000000,0x00000058, -/* -; Indicate that we should be expecting a disconnect - MOVE SCNTL2 & 0x7f TO SCNTL2 - -at 0x00000189 : */ 0x7c027f00,0x00000000, -/* - CLEAR ACK - -at 0x0000018b : */ 0x60000040,0x00000000, -/* - - WAIT DISCONNECT - -at 0x0000018d : */ 0x48000000,0x00000000, -/* - -; -; The SCSI specification states that when a UNIT ATTENTION condition -; is pending, as indicated by a CHECK CONDITION status message, -; the target shall revert to asynchronous transfers. Since -; synchronous transfers parameters are maintained on a per INITIATOR/TARGET -; basis, and returning control to our scheduler could work on a command -; running on another lun on that target using the old parameters, we must -; interrupt the host processor to get them changed, or change them ourselves. -; -; Once SCSI-II tagged queueing is implemented, things will be even more -; hairy, since contingent allegiance conditions exist on a per-target/lun -; basis, and issuing a new command with a different tag would clear it. -; In these cases, we must interrupt the host processor to get a request -; added to the HEAD of the queue with the request sense command, or we -; must automatically issue the request sense command. - - - - - - INTFLY - -at 0x0000018f : */ 0x98180000,0x00000000, -/* - - - - - - JUMP schedule - -at 0x00000191 : */ 0x80080000,0x00000000, -/* -command_failed: - INT int_err_check_condition - -at 0x00000193 : */ 0x98080000,0x00030000, -/* - - - - -; -; wait_reselect -; -; PURPOSE : This is essentially the idle routine, where control lands -; when there are no new processes to schedule. wait_reselect -; waits for reselection, selection, and new commands. -; -; When a successful reselection occurs, with the aid -; of fixed up code in each DSA, wait_reselect walks the -; reconnect_dsa_queue, asking each dsa if the target ID -; and LUN match its. -; -; If a match is found, a call is made back to reselected_ok, -; which through the miracles of self modifying code, extracts -; the found DSA from the reconnect_dsa_queue and then -; returns control to the DSAs thread of execution. -; -; INPUTS : NONE -; -; CALLS : OK -; -; MODIFIES : DSA, -; -; EXITS : On successful reselection, control is returned to the -; DSA which called reselected_ok. If the WAIT RESELECT -; was interrupted by a new commands arrival signaled by -; SIG_P, control is passed to schedule. If the NCR is -; selected, the host system is interrupted with an -; int_err_selected which is usually responded to by -; setting DSP to the target_abort address. - -ENTRY wait_reselect -wait_reselect: - - - - - - - WAIT RESELECT wait_reselect_failed - -at 0x00000195 : */ 0x50000000,0x0000076c, -/* - -reselected: - - - - CLEAR TARGET - -at 0x00000197 : */ 0x60000200,0x00000000, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x00000199 : */ 0x78380000,0x00000000, -/* - ; Read all data needed to reestablish the nexus - - MOVE 1, reselected_identify, WHEN MSG_IN - -at 0x0000019b : */ 0x0f000001,0x00000000, -/* - ; We used to CLEAR ACK here. - - - - - - ; Point DSA at the current head of the disconnected queue. - MOVE dmode_memory_to_ncr TO DMODE - -at 0x0000019d : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 4, reconnect_dsa_head, addr_scratch - -at 0x0000019f : */ 0xc0000004,0x00000000,0x00000000, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x000001a2 : */ 0x78380000,0x00000000, -/* - CALL scratch_to_dsa - -at 0x000001a4 : */ 0x88080000,0x00000980, -/* - - ; Fix the update-next pointer so that the reconnect_dsa_head - ; pointer is the one that will be updated if this DSA is a hit - ; and we remove it from the queue. - - MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok + 8 - -at 0x000001a6 : */ 0xc0000004,0x00000000,0x00000758, -/* - -ENTRY reselected_check_next -reselected_check_next: - - - - ; Check for a NULL pointer. - MOVE DSA0 TO SFBR - -at 0x000001a9 : */ 0x72100000,0x00000000, -/* - JUMP reselected_not_end, IF NOT 0 - -at 0x000001ab : */ 0x80040000,0x000006ec, -/* - MOVE DSA1 TO SFBR - -at 0x000001ad : */ 0x72110000,0x00000000, -/* - JUMP reselected_not_end, IF NOT 0 - -at 0x000001af : */ 0x80040000,0x000006ec, -/* - MOVE DSA2 TO SFBR - -at 0x000001b1 : */ 0x72120000,0x00000000, -/* - JUMP reselected_not_end, IF NOT 0 - -at 0x000001b3 : */ 0x80040000,0x000006ec, -/* - MOVE DSA3 TO SFBR - -at 0x000001b5 : */ 0x72130000,0x00000000, -/* - JUMP reselected_not_end, IF NOT 0 - -at 0x000001b7 : */ 0x80040000,0x000006ec, -/* - INT int_err_unexpected_reselect - -at 0x000001b9 : */ 0x98080000,0x00020000, -/* - -reselected_not_end: - ; - ; XXX the ALU is only eight bits wide, and the assembler - ; wont do the dirt work for us. As long as dsa_check_reselect - ; is negative, we need to sign extend with 1 bits to the full - ; 32 bit width of the address. - ; - ; A potential work around would be to have a known alignment - ; of the DSA structure such that the base address plus - ; dsa_check_reselect doesn't require carrying from bytes - ; higher than the LSB. - ; - - MOVE DSA0 TO SFBR - -at 0x000001bb : */ 0x72100000,0x00000000, -/* - MOVE SFBR + dsa_check_reselect TO SCRATCH0 - -at 0x000001bd : */ 0x6e340000,0x00000000, -/* - MOVE DSA1 TO SFBR - -at 0x000001bf : */ 0x72110000,0x00000000, -/* - MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY - -at 0x000001c1 : */ 0x6f35ff00,0x00000000, -/* - MOVE DSA2 TO SFBR - -at 0x000001c3 : */ 0x72120000,0x00000000, -/* - MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY - -at 0x000001c5 : */ 0x6f36ff00,0x00000000, -/* - MOVE DSA3 TO SFBR - -at 0x000001c7 : */ 0x72130000,0x00000000, -/* - MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY - -at 0x000001c9 : */ 0x6f37ff00,0x00000000, -/* - - MOVE dmode_ncr_to_memory TO DMODE - -at 0x000001cb : */ 0x78380000,0x00000000, -/* - MOVE MEMORY 4, addr_scratch, reselected_check + 4 - -at 0x000001cd : */ 0xc0000004,0x00000000,0x0000074c, -/* - MOVE dmode_memory_to_memory TO DMODE - -at 0x000001d0 : */ 0x78380000,0x00000000, -/* -reselected_check: - JUMP 0 - -at 0x000001d2 : */ 0x80080000,0x00000000, -/* - - -; -; -ENTRY reselected_ok -reselected_ok: - MOVE MEMORY 4, 0, 0 ; Patched : first word - -at 0x000001d4 : */ 0xc0000004,0x00000000,0x00000000, -/* - ; is address of - ; successful dsa_next - ; Second word is last - ; unsuccessful dsa_next, - ; starting with - ; dsa_reconnect_head - ; We used to CLEAR ACK here. - - - - - - - RETURN ; Return control to where - -at 0x000001d7 : */ 0x90080000,0x00000000, -/* - - - - -selected: - INT int_err_selected; - -at 0x000001d9 : */ 0x98080000,0x00010000, -/* - -; -; A select or reselect failure can be caused by one of two conditions : -; 1. SIG_P was set. This will be the case if the user has written -; a new value to a previously NULL head of the issue queue. -; -; 2. The NCR53c810 was selected or reselected by another device. -; -; 3. The bus was already busy since we were selected or reselected -; before starting the command. - -wait_reselect_failed: - - - -; Check selected bit. - MOVE SIST0 & 0x20 TO SFBR - -at 0x000001db : */ 0x74422000,0x00000000, -/* - JUMP selected, IF 0x20 - -at 0x000001dd : */ 0x800c0020,0x00000764, -/* -; Reading CTEST2 clears the SIG_P bit in the ISTAT register. - MOVE CTEST2 & 0x40 TO SFBR - -at 0x000001df : */ 0x741a4000,0x00000000, -/* - JUMP schedule, IF 0x40 - -at 0x000001e1 : */ 0x800c0040,0x00000000, -/* -; Check connected bit. -; FIXME: this needs to change if we support target mode - MOVE ISTAT & 0x08 TO SFBR - -at 0x000001e3 : */ 0x74140800,0x00000000, -/* - JUMP reselected, IF 0x08 - -at 0x000001e5 : */ 0x800c0008,0x0000065c, -/* -; FIXME : Something bogus happened, and we shouldn't fail silently. - - - - INT int_debug_panic - -at 0x000001e7 : */ 0x98080000,0x030b0000, -/* - - - -select_failed: - - - -; Otherwise, mask the selected and reselected bits off SIST0 - MOVE SIST0 & 0x30 TO SFBR - -at 0x000001e9 : */ 0x74423000,0x00000000, -/* - JUMP selected, IF 0x20 - -at 0x000001eb : */ 0x800c0020,0x00000764, -/* - JUMP reselected, IF 0x10 - -at 0x000001ed : */ 0x800c0010,0x0000065c, -/* -; If SIGP is set, the user just gave us another command, and -; we should restart or return to the scheduler. -; Reading CTEST2 clears the SIG_P bit in the ISTAT register. - MOVE CTEST2 & 0x40 TO SFBR - -at 0x000001ef : */ 0x741a4000,0x00000000, -/* - JUMP select, IF 0x40 - -at 0x000001f1 : */ 0x800c0040,0x000001fc, -/* -; Check connected bit. -; FIXME: this needs to change if we support target mode -; FIXME: is this really necessary? - MOVE ISTAT & 0x08 TO SFBR - -at 0x000001f3 : */ 0x74140800,0x00000000, -/* - JUMP reselected, IF 0x08 - -at 0x000001f5 : */ 0x800c0008,0x0000065c, -/* -; FIXME : Something bogus happened, and we shouldn't fail silently. - - - - INT int_debug_panic - -at 0x000001f7 : */ 0x98080000,0x030b0000, -/* - - -; -; test_1 -; test_2 -; -; PURPOSE : run some verification tests on the NCR. test_1 -; copies test_src to test_dest and interrupts the host -; processor, testing for cache coherency and interrupt -; problems in the processes. -; -; test_2 runs a command with offsets relative to the -; DSA on entry, and is useful for miscellaneous experimentation. -; - -; Verify that interrupts are working correctly and that we don't -; have a cache invalidation problem. - -ABSOLUTE test_src = 0, test_dest = 0 -ENTRY test_1 -test_1: - MOVE MEMORY 4, test_src, test_dest - -at 0x000001f9 : */ 0xc0000004,0x00000000,0x00000000, -/* - INT int_test_1 - -at 0x000001fc : */ 0x98080000,0x04000000, -/* - -; -; Run arbitrary commands, with test code establishing a DSA -; - -ENTRY test_2 -test_2: - CLEAR TARGET - -at 0x000001fe : */ 0x60000200,0x00000000, -/* - SELECT ATN FROM 0, test_2_fail - -at 0x00000200 : */ 0x43000000,0x00000850, -/* - JUMP test_2_msgout, WHEN MSG_OUT - -at 0x00000202 : */ 0x860b0000,0x00000810, -/* -ENTRY test_2_msgout -test_2_msgout: - MOVE FROM 8, WHEN MSG_OUT - -at 0x00000204 : */ 0x1e000000,0x00000008, -/* - MOVE FROM 16, WHEN CMD - -at 0x00000206 : */ 0x1a000000,0x00000010, -/* - MOVE FROM 24, WHEN DATA_IN - -at 0x00000208 : */ 0x19000000,0x00000018, -/* - MOVE FROM 32, WHEN STATUS - -at 0x0000020a : */ 0x1b000000,0x00000020, -/* - MOVE FROM 40, WHEN MSG_IN - -at 0x0000020c : */ 0x1f000000,0x00000028, -/* - MOVE SCNTL2 & 0x7f TO SCNTL2 - -at 0x0000020e : */ 0x7c027f00,0x00000000, -/* - CLEAR ACK - -at 0x00000210 : */ 0x60000040,0x00000000, -/* - WAIT DISCONNECT - -at 0x00000212 : */ 0x48000000,0x00000000, -/* -test_2_fail: - INT int_test_2 - -at 0x00000214 : */ 0x98080000,0x04010000, -/* - -ENTRY debug_break -debug_break: - INT int_debug_break - -at 0x00000216 : */ 0x98080000,0x03000000, -/* - -; -; initiator_abort -; target_abort -; -; PURPOSE : Abort the currently established nexus from with initiator -; or target mode. -; -; - -ENTRY target_abort -target_abort: - SET TARGET - -at 0x00000218 : */ 0x58000200,0x00000000, -/* - DISCONNECT - -at 0x0000021a : */ 0x48000000,0x00000000, -/* - CLEAR TARGET - -at 0x0000021c : */ 0x60000200,0x00000000, -/* - JUMP schedule - -at 0x0000021e : */ 0x80080000,0x00000000, -/* - -ENTRY initiator_abort -initiator_abort: - SET ATN - -at 0x00000220 : */ 0x58000008,0x00000000, -/* -; -; The SCSI-I specification says that targets may go into MSG out at -; their leisure upon receipt of the ATN single. On all versions of the -; specification, we can't change phases until REQ transitions true->false, -; so we need to sink/source one byte of data to allow the transition. -; -; For the sake of safety, we'll only source one byte of data in all -; cases, but to accommodate the SCSI-I dain bramage, we'll sink an -; arbitrary number of bytes. - JUMP spew_cmd, WHEN CMD - -at 0x00000222 : */ 0x820b0000,0x000008b8, -/* - JUMP eat_msgin, WHEN MSG_IN - -at 0x00000224 : */ 0x870b0000,0x000008c8, -/* - JUMP eat_datain, WHEN DATA_IN - -at 0x00000226 : */ 0x810b0000,0x000008f8, -/* - JUMP eat_status, WHEN STATUS - -at 0x00000228 : */ 0x830b0000,0x000008e0, -/* - JUMP spew_dataout, WHEN DATA_OUT - -at 0x0000022a : */ 0x800b0000,0x00000910, -/* - JUMP sated - -at 0x0000022c : */ 0x80080000,0x00000918, -/* -spew_cmd: - MOVE 1, NCR53c7xx_zero, WHEN CMD - -at 0x0000022e : */ 0x0a000001,0x00000000, -/* - JUMP sated - -at 0x00000230 : */ 0x80080000,0x00000918, -/* -eat_msgin: - MOVE 1, NCR53c7xx_sink, WHEN MSG_IN - -at 0x00000232 : */ 0x0f000001,0x00000000, -/* - JUMP eat_msgin, WHEN MSG_IN - -at 0x00000234 : */ 0x870b0000,0x000008c8, -/* - JUMP sated - -at 0x00000236 : */ 0x80080000,0x00000918, -/* -eat_status: - MOVE 1, NCR53c7xx_sink, WHEN STATUS - -at 0x00000238 : */ 0x0b000001,0x00000000, -/* - JUMP eat_status, WHEN STATUS - -at 0x0000023a : */ 0x830b0000,0x000008e0, -/* - JUMP sated - -at 0x0000023c : */ 0x80080000,0x00000918, -/* -eat_datain: - MOVE 1, NCR53c7xx_sink, WHEN DATA_IN - -at 0x0000023e : */ 0x09000001,0x00000000, -/* - JUMP eat_datain, WHEN DATA_IN - -at 0x00000240 : */ 0x810b0000,0x000008f8, -/* - JUMP sated - -at 0x00000242 : */ 0x80080000,0x00000918, -/* -spew_dataout: - MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT - -at 0x00000244 : */ 0x08000001,0x00000000, -/* -sated: - MOVE SCNTL2 & 0x7f TO SCNTL2 - -at 0x00000246 : */ 0x7c027f00,0x00000000, -/* - MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT - -at 0x00000248 : */ 0x0e000001,0x00000000, -/* - WAIT DISCONNECT - -at 0x0000024a : */ 0x48000000,0x00000000, -/* - INT int_norm_aborted - -at 0x0000024c : */ 0x98080000,0x02040000, -/* - -; -; dsa_to_scratch -; scratch_to_dsa -; -; PURPOSE : -; The NCR chips cannot do a move memory instruction with the DSA register -; as the source or destination. So, we provide a couple of subroutines -; that let us switch between the DSA register and scratch register. -; -; Memory moves to/from the DSPS register also don't work, but we -; don't use them. -; -; - - -dsa_to_scratch: - MOVE DSA0 TO SFBR - -at 0x0000024e : */ 0x72100000,0x00000000, -/* - MOVE SFBR TO SCRATCH0 - -at 0x00000250 : */ 0x6a340000,0x00000000, -/* - MOVE DSA1 TO SFBR - -at 0x00000252 : */ 0x72110000,0x00000000, -/* - MOVE SFBR TO SCRATCH1 - -at 0x00000254 : */ 0x6a350000,0x00000000, -/* - MOVE DSA2 TO SFBR - -at 0x00000256 : */ 0x72120000,0x00000000, -/* - MOVE SFBR TO SCRATCH2 - -at 0x00000258 : */ 0x6a360000,0x00000000, -/* - MOVE DSA3 TO SFBR - -at 0x0000025a : */ 0x72130000,0x00000000, -/* - MOVE SFBR TO SCRATCH3 - -at 0x0000025c : */ 0x6a370000,0x00000000, -/* - RETURN - -at 0x0000025e : */ 0x90080000,0x00000000, -/* - -scratch_to_dsa: - MOVE SCRATCH0 TO SFBR - -at 0x00000260 : */ 0x72340000,0x00000000, -/* - MOVE SFBR TO DSA0 - -at 0x00000262 : */ 0x6a100000,0x00000000, -/* - MOVE SCRATCH1 TO SFBR - -at 0x00000264 : */ 0x72350000,0x00000000, -/* - MOVE SFBR TO DSA1 - -at 0x00000266 : */ 0x6a110000,0x00000000, -/* - MOVE SCRATCH2 TO SFBR - -at 0x00000268 : */ 0x72360000,0x00000000, -/* - MOVE SFBR TO DSA2 - -at 0x0000026a : */ 0x6a120000,0x00000000, -/* - MOVE SCRATCH3 TO SFBR - -at 0x0000026c : */ 0x72370000,0x00000000, -/* - MOVE SFBR TO DSA3 - -at 0x0000026e : */ 0x6a130000,0x00000000, -/* - RETURN - -at 0x00000270 : */ 0x90080000,0x00000000, -}; - -#define A_NCR53c7xx_msg_abort 0x00000000 -static u32 A_NCR53c7xx_msg_abort_used[] __attribute((unused)) = { - 0x00000249, -}; - -#define A_NCR53c7xx_msg_reject 0x00000000 -static u32 A_NCR53c7xx_msg_reject_used[] __attribute((unused)) = { - 0x00000172, -}; - -#define A_NCR53c7xx_sink 0x00000000 -static u32 A_NCR53c7xx_sink_used[] __attribute((unused)) = { - 0x00000233, - 0x00000239, - 0x0000023f, -}; - -#define A_NCR53c7xx_zero 0x00000000 -static u32 A_NCR53c7xx_zero_used[] __attribute((unused)) = { - 0x0000022f, - 0x00000245, -}; - -#define A_NOP_insn 0x00000000 -static u32 A_NOP_insn_used[] __attribute((unused)) = { - 0x00000010, -}; - -#define A_addr_reconnect_dsa_head 0x00000000 -static u32 A_addr_reconnect_dsa_head_used[] __attribute((unused)) = { - 0x000001a7, -}; - -#define A_addr_scratch 0x00000000 -static u32 A_addr_scratch_used[] __attribute((unused)) = { - 0x00000004, - 0x0000001b, - 0x00000046, - 0x00000067, - 0x00000073, - 0x000000b0, - 0x000000c6, - 0x00000128, - 0x00000141, - 0x000001a1, - 0x000001ce, -}; - -#define A_addr_temp 0x00000000 -static u32 A_addr_temp_used[] __attribute((unused)) = { - 0x00000025, - 0x00000034, -}; - -#define A_dmode_memory_to_memory 0x00000000 -static u32 A_dmode_memory_to_memory_used[] __attribute((unused)) = { - 0x00000005, - 0x0000001c, - 0x00000027, - 0x00000035, - 0x00000047, - 0x00000069, - 0x00000075, - 0x000000b2, - 0x000000c8, - 0x0000012a, - 0x00000143, - 0x00000199, - 0x000001a2, - 0x000001d0, -}; - -#define A_dmode_memory_to_ncr 0x00000000 -static u32 A_dmode_memory_to_ncr_used[] __attribute((unused)) = { - 0x00000000, - 0x00000017, - 0x00000030, - 0x00000042, - 0x0000019d, -}; - -#define A_dmode_ncr_to_memory 0x00000000 -static u32 A_dmode_ncr_to_memory_used[] __attribute((unused)) = { - 0x00000022, - 0x00000064, - 0x00000070, - 0x000000ad, - 0x000000c3, - 0x00000125, - 0x0000013e, - 0x000001cb, -}; - -#define A_dsa_check_reselect 0x00000000 -static u32 A_dsa_check_reselect_used[] __attribute((unused)) = { - 0x000001bd, -}; - -#define A_dsa_cmdout 0x00000048 -static u32 A_dsa_cmdout_used[] __attribute((unused)) = { - 0x00000094, -}; - -#define A_dsa_cmnd 0x00000038 -static u32 A_dsa_cmnd_used[] __attribute((unused)) = { -}; - -#define A_dsa_datain 0x00000054 -static u32 A_dsa_datain_used[] __attribute((unused)) = { - 0x000000bb, -}; - -#define A_dsa_dataout 0x00000050 -static u32 A_dsa_dataout_used[] __attribute((unused)) = { - 0x000000a5, -}; - -#define A_dsa_end 0x00000070 -static u32 A_dsa_end_used[] __attribute((unused)) = { -}; - -#define A_dsa_fields_start 0x00000000 -static u32 A_dsa_fields_start_used[] __attribute((unused)) = { -}; - -#define A_dsa_msgin 0x00000058 -static u32 A_dsa_msgin_used[] __attribute((unused)) = { - 0x00000188, -}; - -#define A_dsa_msgout 0x00000040 -static u32 A_dsa_msgout_used[] __attribute((unused)) = { - 0x00000086, -}; - -#define A_dsa_msgout_other 0x00000068 -static u32 A_dsa_msgout_other_used[] __attribute((unused)) = { - 0x00000180, -}; - -#define A_dsa_next 0x00000030 -static u32 A_dsa_next_used[] __attribute((unused)) = { - 0x0000005c, -}; - -#define A_dsa_restore_pointers 0x00000000 -static u32 A_dsa_restore_pointers_used[] __attribute((unused)) = { - 0x0000012e, -}; - -#define A_dsa_save_data_pointer 0x00000000 -static u32 A_dsa_save_data_pointer_used[] __attribute((unused)) = { - 0x00000115, -}; - -#define A_dsa_select 0x0000003c -static u32 A_dsa_select_used[] __attribute((unused)) = { - 0x00000081, -}; - -#define A_dsa_status 0x00000060 -static u32 A_dsa_status_used[] __attribute((unused)) = { - 0x00000184, -}; - -#define A_dsa_temp_addr_array_value 0x00000000 -static u32 A_dsa_temp_addr_array_value_used[] __attribute((unused)) = { -}; - -#define A_dsa_temp_addr_dsa_value 0x00000000 -static u32 A_dsa_temp_addr_dsa_value_used[] __attribute((unused)) = { - 0x00000003, -}; - -#define A_dsa_temp_addr_new_value 0x00000000 -static u32 A_dsa_temp_addr_new_value_used[] __attribute((unused)) = { -}; - -#define A_dsa_temp_addr_next 0x00000000 -static u32 A_dsa_temp_addr_next_used[] __attribute((unused)) = { - 0x00000015, - 0x0000004e, -}; - -#define A_dsa_temp_addr_residual 0x00000000 -static u32 A_dsa_temp_addr_residual_used[] __attribute((unused)) = { - 0x0000002a, - 0x00000039, -}; - -#define A_dsa_temp_addr_saved_pointer 0x00000000 -static u32 A_dsa_temp_addr_saved_pointer_used[] __attribute((unused)) = { - 0x00000026, - 0x00000033, -}; - -#define A_dsa_temp_addr_saved_residual 0x00000000 -static u32 A_dsa_temp_addr_saved_residual_used[] __attribute((unused)) = { - 0x0000002b, - 0x00000038, -}; - -#define A_dsa_temp_lun 0x00000000 -static u32 A_dsa_temp_lun_used[] __attribute((unused)) = { - 0x0000004b, -}; - -#define A_dsa_temp_next 0x00000000 -static u32 A_dsa_temp_next_used[] __attribute((unused)) = { - 0x0000001a, -}; - -#define A_dsa_temp_sync 0x00000000 -static u32 A_dsa_temp_sync_used[] __attribute((unused)) = { - 0x00000053, -}; - -#define A_dsa_temp_target 0x00000000 -static u32 A_dsa_temp_target_used[] __attribute((unused)) = { - 0x00000040, -}; - -#define A_int_debug_break 0x03000000 -static u32 A_int_debug_break_used[] __attribute((unused)) = { - 0x00000217, -}; - -#define A_int_debug_panic 0x030b0000 -static u32 A_int_debug_panic_used[] __attribute((unused)) = { - 0x000001e8, - 0x000001f8, -}; - -#define A_int_err_check_condition 0x00030000 -static u32 A_int_err_check_condition_used[] __attribute((unused)) = { - 0x00000194, -}; - -#define A_int_err_no_phase 0x00040000 -static u32 A_int_err_no_phase_used[] __attribute((unused)) = { -}; - -#define A_int_err_selected 0x00010000 -static u32 A_int_err_selected_used[] __attribute((unused)) = { - 0x000001da, -}; - -#define A_int_err_unexpected_phase 0x00000000 -static u32 A_int_err_unexpected_phase_used[] __attribute((unused)) = { - 0x0000008c, - 0x00000092, - 0x0000009a, - 0x000000d0, - 0x000000d4, - 0x000000d6, - 0x000000de, - 0x000000e2, - 0x000000e4, - 0x000000ec, - 0x000000f0, - 0x000000f2, - 0x000000f4, - 0x0000014c, -}; - -#define A_int_err_unexpected_reselect 0x00020000 -static u32 A_int_err_unexpected_reselect_used[] __attribute((unused)) = { - 0x000001ba, -}; - -#define A_int_msg_1 0x01020000 -static u32 A_int_msg_1_used[] __attribute((unused)) = { - 0x0000010e, - 0x00000110, -}; - -#define A_int_msg_sdtr 0x01010000 -static u32 A_int_msg_sdtr_used[] __attribute((unused)) = { - 0x0000016c, -}; - -#define A_int_msg_wdtr 0x01000000 -static u32 A_int_msg_wdtr_used[] __attribute((unused)) = { - 0x00000160, -}; - -#define A_int_norm_aborted 0x02040000 -static u32 A_int_norm_aborted_used[] __attribute((unused)) = { - 0x0000024d, -}; - -#define A_int_norm_command_complete 0x02020000 -static u32 A_int_norm_command_complete_used[] __attribute((unused)) = { -}; - -#define A_int_norm_disconnected 0x02030000 -static u32 A_int_norm_disconnected_used[] __attribute((unused)) = { -}; - -#define A_int_norm_reselect_complete 0x02010000 -static u32 A_int_norm_reselect_complete_used[] __attribute((unused)) = { -}; - -#define A_int_norm_reset 0x02050000 -static u32 A_int_norm_reset_used[] __attribute((unused)) = { -}; - -#define A_int_norm_select_complete 0x02000000 -static u32 A_int_norm_select_complete_used[] __attribute((unused)) = { -}; - -#define A_int_test_1 0x04000000 -static u32 A_int_test_1_used[] __attribute((unused)) = { - 0x000001fd, -}; - -#define A_int_test_2 0x04010000 -static u32 A_int_test_2_used[] __attribute((unused)) = { - 0x00000215, -}; - -#define A_int_test_3 0x04020000 -static u32 A_int_test_3_used[] __attribute((unused)) = { -}; - -#define A_msg_buf 0x00000000 -static u32 A_msg_buf_used[] __attribute((unused)) = { - 0x00000102, - 0x0000014e, - 0x00000158, - 0x0000015e, - 0x00000164, - 0x0000016a, -}; - -#define A_reconnect_dsa_head 0x00000000 -static u32 A_reconnect_dsa_head_used[] __attribute((unused)) = { - 0x0000006c, - 0x00000074, - 0x000001a0, -}; - -#define A_reselected_identify 0x00000000 -static u32 A_reselected_identify_used[] __attribute((unused)) = { - 0x00000045, - 0x0000019c, -}; - -#define A_reselected_tag 0x00000000 -static u32 A_reselected_tag_used[] __attribute((unused)) = { -}; - -#define A_schedule 0x00000000 -static u32 A_schedule_used[] __attribute((unused)) = { - 0x0000007e, - 0x00000192, - 0x000001e2, - 0x0000021f, -}; - -#define A_test_dest 0x00000000 -static u32 A_test_dest_used[] __attribute((unused)) = { - 0x000001fb, -}; - -#define A_test_src 0x00000000 -static u32 A_test_src_used[] __attribute((unused)) = { - 0x000001fa, -}; - -#define Ent_accept_message 0x000005d4 -#define Ent_cmdout_cmdout 0x0000024c -#define Ent_command_complete 0x0000060c -#define Ent_command_complete_msgin 0x0000061c -#define Ent_data_transfer 0x00000254 -#define Ent_datain_to_jump 0x00000328 -#define Ent_debug_break 0x00000858 -#define Ent_dsa_code_begin 0x00000000 -#define Ent_dsa_code_check_reselect 0x000000f8 -#define Ent_dsa_code_fix_jump 0x0000003c -#define Ent_dsa_code_restore_pointers 0x000000c0 -#define Ent_dsa_code_save_data_pointer 0x00000088 -#define Ent_dsa_code_template 0x00000000 -#define Ent_dsa_code_template_end 0x00000168 -#define Ent_dsa_schedule 0x00000168 -#define Ent_dsa_zero 0x00000168 -#define Ent_end_data_transfer 0x0000028c -#define Ent_initiator_abort 0x00000880 -#define Ent_msg_in 0x00000404 -#define Ent_msg_in_restart 0x000003e4 -#define Ent_other_in 0x00000374 -#define Ent_other_out 0x0000033c -#define Ent_other_transfer 0x000003ac -#define Ent_reject_message 0x000005b4 -#define Ent_reselected_check_next 0x000006a4 -#define Ent_reselected_ok 0x00000750 -#define Ent_respond_message 0x000005ec -#define Ent_select 0x000001fc -#define Ent_select_msgout 0x00000214 -#define Ent_target_abort 0x00000860 -#define Ent_test_1 0x000007e4 -#define Ent_test_2 0x000007f8 -#define Ent_test_2_msgout 0x00000810 -#define Ent_wait_reselect 0x00000654 -static u32 LABELPATCHES[] __attribute((unused)) = { - 0x00000008, - 0x0000000a, - 0x00000013, - 0x00000016, - 0x0000001f, - 0x00000021, - 0x0000004f, - 0x00000051, - 0x0000005b, - 0x00000068, - 0x0000006f, - 0x00000082, - 0x00000084, - 0x0000008a, - 0x0000008e, - 0x00000090, - 0x00000096, - 0x00000098, - 0x0000009c, - 0x0000009e, - 0x000000a0, - 0x000000a2, - 0x000000a4, - 0x000000b1, - 0x000000b6, - 0x000000ba, - 0x000000c7, - 0x000000cc, - 0x000000d2, - 0x000000d8, - 0x000000da, - 0x000000e0, - 0x000000e6, - 0x000000e8, - 0x000000ee, - 0x000000f6, - 0x000000f8, - 0x00000104, - 0x00000106, - 0x00000108, - 0x0000010a, - 0x0000010c, - 0x00000112, - 0x00000114, - 0x00000129, - 0x00000142, - 0x00000148, - 0x00000150, - 0x00000152, - 0x00000154, - 0x0000015a, - 0x00000166, - 0x00000196, - 0x000001a5, - 0x000001a8, - 0x000001ac, - 0x000001b0, - 0x000001b4, - 0x000001b8, - 0x000001cf, - 0x000001de, - 0x000001e6, - 0x000001ec, - 0x000001ee, - 0x000001f2, - 0x000001f6, - 0x00000201, - 0x00000203, - 0x00000223, - 0x00000225, - 0x00000227, - 0x00000229, - 0x0000022b, - 0x0000022d, - 0x00000231, - 0x00000235, - 0x00000237, - 0x0000023b, - 0x0000023d, - 0x00000241, - 0x00000243, -}; - -static struct { - u32 offset; - void *address; -} EXTERNAL_PATCHES[] __attribute((unused)) = { -}; - -static u32 INSTRUCTIONS __attribute((unused)) = 301; -static u32 PATCHES __attribute((unused)) = 81; -static u32 EXTERNAL_PATCHES_LEN __attribute((unused)) = 0; diff -Nru a/drivers/scsi/53c8xx_u.h_shipped b/drivers/scsi/53c8xx_u.h_shipped --- a/drivers/scsi/53c8xx_u.h_shipped Sun Feb 9 21:13:33 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,97 +0,0 @@ -#undef A_NCR53c7xx_msg_abort -#undef A_NCR53c7xx_msg_reject -#undef A_NCR53c7xx_sink -#undef A_NCR53c7xx_zero -#undef A_NOP_insn -#undef A_addr_reconnect_dsa_head -#undef A_addr_scratch -#undef A_addr_temp -#undef A_dmode_memory_to_memory -#undef A_dmode_memory_to_ncr -#undef A_dmode_ncr_to_memory -#undef A_dsa_check_reselect -#undef A_dsa_cmdout -#undef A_dsa_cmnd -#undef A_dsa_datain -#undef A_dsa_dataout -#undef A_dsa_end -#undef A_dsa_fields_start -#undef A_dsa_msgin -#undef A_dsa_msgout -#undef A_dsa_msgout_other -#undef A_dsa_next -#undef A_dsa_restore_pointers -#undef A_dsa_save_data_pointer -#undef A_dsa_select -#undef A_dsa_status -#undef A_dsa_temp_addr_array_value -#undef A_dsa_temp_addr_dsa_value -#undef A_dsa_temp_addr_new_value -#undef A_dsa_temp_addr_next -#undef A_dsa_temp_addr_residual -#undef A_dsa_temp_addr_saved_pointer -#undef A_dsa_temp_addr_saved_residual -#undef A_dsa_temp_lun -#undef A_dsa_temp_next -#undef A_dsa_temp_sync -#undef A_dsa_temp_target -#undef A_int_debug_break -#undef A_int_debug_panic -#undef A_int_err_check_condition -#undef A_int_err_no_phase -#undef A_int_err_selected -#undef A_int_err_unexpected_phase -#undef A_int_err_unexpected_reselect -#undef A_int_msg_1 -#undef A_int_msg_sdtr -#undef A_int_msg_wdtr -#undef A_int_norm_aborted -#undef A_int_norm_command_complete -#undef A_int_norm_disconnected -#undef A_int_norm_reselect_complete -#undef A_int_norm_reset -#undef A_int_norm_select_complete -#undef A_int_test_1 -#undef A_int_test_2 -#undef A_int_test_3 -#undef A_msg_buf -#undef A_reconnect_dsa_head -#undef A_reselected_identify -#undef A_reselected_tag -#undef A_schedule -#undef A_test_dest -#undef A_test_src -#undef Ent_accept_message -#undef Ent_cmdout_cmdout -#undef Ent_command_complete -#undef Ent_command_complete_msgin -#undef Ent_data_transfer -#undef Ent_datain_to_jump -#undef Ent_debug_break -#undef Ent_dsa_code_begin -#undef Ent_dsa_code_check_reselect -#undef Ent_dsa_code_fix_jump -#undef Ent_dsa_code_restore_pointers -#undef Ent_dsa_code_save_data_pointer -#undef Ent_dsa_code_template -#undef Ent_dsa_code_template_end -#undef Ent_dsa_schedule -#undef Ent_dsa_zero -#undef Ent_end_data_transfer -#undef Ent_initiator_abort -#undef Ent_msg_in -#undef Ent_msg_in_restart -#undef Ent_other_in -#undef Ent_other_out -#undef Ent_other_transfer -#undef Ent_reject_message -#undef Ent_reselected_check_next -#undef Ent_reselected_ok -#undef Ent_respond_message -#undef Ent_select -#undef Ent_select_msgout -#undef Ent_target_abort -#undef Ent_test_1 -#undef Ent_test_2 -#undef Ent_test_2_msgout -#undef Ent_wait_reselect diff -Nru a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c --- a/drivers/scsi/AM53C974.c Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/AM53C974.c Sun Feb 9 21:13:32 2003 @@ -897,7 +897,7 @@ static int AM53C974_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) { unsigned long flags; - struct Scsi_Host *instance = cmd->host; + struct Scsi_Host *instance = cmd->device->host; struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata; Scsi_Cmnd *tmp; @@ -906,7 +906,7 @@ DEB_QUEUE(printk(SEPARATOR_LINE)); DEB_QUEUE(printk("scsi%d: AM53C974_queue_command called\n", instance->host_no)); DEB_QUEUE(printk("cmd=%02x target=%02x lun=%02x bufflen=%d use_sg = %02x\n", - cmd->cmnd[0], cmd->target, cmd->lun, cmd->request_bufflen, cmd->use_sg)); + cmd->cmnd[0], cmd->target, cmd->device->lun, cmd->request_bufflen, cmd->use_sg)); /* We use the host_scribble field as a pointer to the next command in a queue */ cmd->host_scribble = NULL; @@ -978,7 +978,7 @@ for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble) { /* When we find one, remove it from the issue queue. */ - if (!(hostdata->busy[tmp->target] & (1 << tmp->lun))) { + if (!(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))) { if (prev) { REMOVE(prev, (Scsi_Cmnd *) (prev->host_scribble), tmp, (Scsi_Cmnd *) (tmp->host_scribble)); @@ -1127,7 +1127,7 @@ #endif printk("scsi%d : PARITY error\n", instance->host_no); if (hostdata->connected) - hostdata->sync_off[hostdata->connected->target] = 0; /* setup asynchronous transfer */ + hostdata->sync_off[hostdata->connected->device->id] = 0; /* setup asynchronous transfer */ hostdata->aborted = 1; } if (statreg & STATREG_IOE) { @@ -1209,7 +1209,7 @@ (hostdata->sel_cmd->cmnd[0] == REQUEST_SENSE) ? TAG_NONE : TAG_NEXT); hostdata->selecting = 0; - AM53C974_set_sync(instance, hostdata->sel_cmd->target); + AM53C974_set_sync(instance, hostdata->sel_cmd->device->id); restore_flags(flags); return; } @@ -1243,7 +1243,7 @@ #ifdef SCSI2 if (!hostdata->connected->device->tagged_queue) #endif - hostdata->busy[hostdata->connected->target] |= (1 << hostdata->connected->lun); + hostdata->busy[hostdata->connected->device->id] |= (1 << hostdata->connected->device->lun); /* very strange -- use_sg is sometimes nonzero for request sense commands !! */ if ((hostdata->connected->cmnd[0] == REQUEST_SENSE) && hostdata->connected->use_sg) { DEB(printk("scsi%d: REQUEST_SENSE command with nonzero use_sg\n", instance->host_no)); @@ -1318,9 +1318,9 @@ if (hostdata->disconnecting) { /* target sent disconnect message, so we are prepared */ cmd = (Scsi_Cmnd *) hostdata->connected; - AM53C974_set_async(instance, cmd->target); + AM53C974_set_async(instance, cmd->device->id); DEB_INTR(printk("scsi%d : disc. from cmnd %d for ta %d, lun %d\n", - instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun)); + instance->host_no, cmd->cmnd[0], cmd->target, cmd->device->lun)); if (cmd->device->disconnect) { /* target wants to reselect later */ DEB_INTR(printk("ok, re-enabling selection\n")); @@ -1329,7 +1329,7 @@ hostdata->disconnected_queue = cmd; DEB_QUEUE(printk("scsi%d : command for target %d lun %d this %d was moved from connected to" " the disconnected_queue\n", instance->host_no, cmd->target, - cmd->lun, hostdata->disconnected_queue->SCp.this_residual)); + cmd->device->lun, hostdata->disconnected_queue->SCp.this_residual)); DEB_QUEUE(AM53C974_print_queues(instance)); goto EXIT_UNFINISHED; } else { @@ -1355,9 +1355,9 @@ #ifdef AM53C974_DEBUG deb_stop = 1; #endif - AM53C974_set_async(instance, cmd->target); + AM53C974_set_async(instance, cmd->device->id); printk("scsi%d: Unexpected disconnect; phase: %d; target: %d; this_residual: %d; buffers_residual: %d; message: %d\n", - instance->host_no, cmd->SCp.phase, cmd->target, cmd->SCp.this_residual, cmd->SCp.buffers_residual, + instance->host_no, cmd->SCp.phase, cmd->device->id, cmd->SCp.this_residual, cmd->SCp.buffers_residual, cmd->SCp.Message); printk("cmdreg: 0x%02x; statreg: 0x%02x; isreg: 0x%02x; cfifo: 0x%02x\n", AM53C974_read_8(CMDREG), AM53C974_read_8(STATREG), AM53C974_read_8(ISREG), @@ -1366,7 +1366,7 @@ if ((hostdata->last_message[0] == EXTENDED_MESSAGE) && (hostdata->last_message[2] == EXTENDED_SDTR)) { /* sync. negotiation was aborted, setup asynchronous transfer with target */ - hostdata->sync_off[cmd->target] = 0; + hostdata->sync_off[cmd->device->id] = 0; } if (hostdata->aborted || hostdata->msgout[0] == ABORT) cmd->result = DID_ABORT << 16; @@ -1382,14 +1382,14 @@ hostdata->selecting = 0; hostdata->disconnecting = 0; hostdata->dma_busy = 0; - hostdata->busy[cmd->target] &= ~(1 << cmd->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); AM53C974_write_8(CMDREG, CMDREG_CFIFO); DEB(printk("disconnect; issue_queue: 0x%lx, disconnected_queue: 0x%lx\n", (long) hostdata->issue_queue, (long) hostdata->disconnected_queue)); cmd->scsi_done(cmd); if (!hostdata->selecting) { - AM53C974_set_async(instance, cmd->target); + AM53C974_set_async(instance, cmd->device->id); AM53C974_write_8(CMDREG, CMDREG_ESR); } /* allow reselect */ return; @@ -1405,7 +1405,7 @@ DEB(printk("disconnect; issue_queue: 0x%lx, disconnected_queue: 0x%lx\n", (long) hostdata->issue_queue, (long) hostdata->disconnected_queue)); if (!hostdata->selecting) { - AM53C974_set_async(instance, cmd->target); + AM53C974_set_async(instance, cmd->device->id); AM53C974_write_8(CMDREG, CMDREG_ESR); } /* allow reselect */ return; @@ -1573,7 +1573,7 @@ case PHASE_MSGIN: DEB_INFO(printk("Message-In phase; cmd=0x%lx, sel_cmd=0x%lx\n", (long) hostdata->connected, (long) hostdata->sel_cmd)); - AM53C974_set_async(instance, cmd->target); + AM53C974_set_async(instance, cmd->device->id); if (cmd->SCp.phase == PHASE_DATAIN) AM53C974_dma_blast(instance, dmastatus, statreg); if ((cmd->SCp.phase == PHASE_DATAOUT) && (AM53C974_read_8(DMACMD) & DMACMD_START)) { @@ -1603,13 +1603,13 @@ ret = AM53C974_message(instance, cmd, cmd->SCp.Message); } cmd->SCp.phase = PHASE_MSGIN; - AM53C974_set_sync(instance, cmd->target); + AM53C974_set_sync(instance, cmd->device->id); break; case PHASE_MSGOUT: DEB_INFO(printk("Message-Out phase; cfifo=%d; msgout[0]=0x%02x\n", AM53C974_read_8(CFIREG) & CFIREG_CF, hostdata->msgout[0])); AM53C974_write_8(DMACMD, DMACMD_IDLE); - AM53C974_set_async(instance, cmd->target); + AM53C974_set_async(instance, cmd->device->id); for (i = 0; i < sizeof(hostdata->last_message); i++) hostdata->last_message[i] = hostdata->msgout[i]; if ((hostdata->msgout[0] == 0) || INSIDE(hostdata->msgout[0], 0x02, 0x1F) || @@ -1635,24 +1635,24 @@ AM53C974_write_8(CMDREG, CMDREG_IT); cmd->SCp.phase = PHASE_MSGOUT; hostdata->msgout[0] = NOP; - AM53C974_set_sync(instance, cmd->target); + AM53C974_set_sync(instance, cmd->device->id); break; case PHASE_CMDOUT: DEB_INFO(printk("Command-Out phase\n")); - AM53C974_set_async(instance, cmd->target); + AM53C974_set_async(instance, cmd->device->id); for (i = 0; i < cmd->cmd_len; i++) AM53C974_write_8(FFREG, cmd->cmnd[i]); AM53C974_write_8(CMDREG, CMDREG_IT); cmd->SCp.phase = PHASE_CMDOUT; - AM53C974_set_sync(instance, cmd->target); + AM53C974_set_sync(instance, cmd->device->id); break; case PHASE_STATIN: DEB_INFO(printk("Status phase\n")); if (cmd->SCp.phase == PHASE_DATAIN) AM53C974_dma_blast(instance, dmastatus, statreg); - AM53C974_set_async(instance, cmd->target); + AM53C974_set_async(instance, cmd->device->id); if (cmd->SCp.phase == PHASE_DATAOUT) { unsigned long residual; @@ -1724,12 +1724,12 @@ case LINKED_FLG_CMD_COMPLETE: /* Accept message by releasing ACK */ DEB_LINKED(printk("scsi%d : target %d lun %d linked command complete.\n", - instance->host_no, cmd->target, cmd->lun)); + instance->host_no, cmd->device->id, cmd->device->lun)); /* Sanity check : A linked command should only terminate with * one of these messages if there are more linked commands available. */ if (!cmd->next_link) { printk("scsi%d : target %d lun %d linked command complete, no next_link\n" - instance->host_no, cmd->target, cmd->lun); + instance->host_no, cmd->device->id, cmd->device->lun); hostdata->aborted = 1; AM53C974_write_8(CMDREG, CMDREG_SATN); AM53C974_write_8(CMDREG, CMDREG_MA); @@ -1747,7 +1747,7 @@ cmd->next_link->tag = cmd->tag; cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); DEB_LINKED(printk("scsi%d : target %d lun %d linked request done, calling scsi_done().\n", - instance->host_no, cmd->target, cmd->lun)); + instance->host_no, cmd->device->id, cmd->device->lun)); cmd->scsi_done(cmd); cmd = hostdata->connected; break; @@ -1757,7 +1757,7 @@ case ABORT: case COMMAND_COMPLETE: DEB_MSG(printk("scsi%d: command complete message received; cmd %d for target %d, lun %d\n", - instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun)); + instance->host_no, cmd->cmnd[0], cmd->device->id, cmd->device->lun)); hostdata->disconnecting = 1; cmd->device->disconnect = 0; @@ -1807,22 +1807,22 @@ case MESSAGE_REJECT: DEB_MSG(printk("scsi%d: reject message received; cmd %d for target %d, lun %d\n", - instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun)); + instance->host_no, cmd->cmnd[0], cmd->device->id, cmd->device->lun)); switch (hostdata->last_message[0]) { case EXTENDED_MESSAGE: if (hostdata->last_message[2] == EXTENDED_SDTR) { /* sync. negotiation was rejected, setup asynchronous transfer with target */ printk("\ntarget %d: rate=%d Mhz, asynchronous (sync. negotiation rejected)\n", - cmd->target, DEF_CLK / DEF_STP); - hostdata->sync_off[cmd->target] = 0; - hostdata->sync_per[cmd->target] = DEF_STP; + cmd->device->id, DEF_CLK / DEF_STP); + hostdata->sync_off[cmd->device->id] = 0; + hostdata->sync_per[cmd->device->id] = DEF_STP; } break; case HEAD_OF_QUEUE_TAG: case ORDERED_QUEUE_TAG: case SIMPLE_QUEUE_TAG: cmd->device->tagged_queue = 0; - hostdata->busy[cmd->target] |= (1 << cmd->lun); + hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); break; default: break; @@ -1834,7 +1834,7 @@ case DISCONNECT: DEB_MSG(printk("scsi%d: disconnect message received; cmd %d for target %d, lun %d\n", - instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun)); + instance->host_no, cmd->cmnd[0], cmd->device->id, cmd->device->lun)); cmd->device->disconnect = 1; hostdata->disconnecting = 1; AM53C974_write_8(CMDREG, CMDREG_MA); /* Accept message by clearing ACK */ @@ -1843,7 +1843,7 @@ case SAVE_POINTERS: case RESTORE_POINTERS: DEB_MSG(printk("scsi%d: save/restore pointers message received; cmd %d for target %d, lun %d\n", - instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun)); + instance->host_no, cmd->cmnd[0], cmd->device->id, cmd->device->lun)); /* The SCSI data pointer is *IMPLICITLY* saved on a disconnect * operation, in violation of the SCSI spec so we can safely * ignore SAVE/RESTORE pointers calls. @@ -1862,7 +1862,7 @@ case EXTENDED_MESSAGE: DEB_MSG(printk("scsi%d: extended message received; cmd %d for target %d, lun %d\n", - instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun)); + instance->host_no, cmd->cmnd[0], cmd->device->id, cmd->device->lun)); /* Extended messages are sent in the following format : * Byte * 0 EXTENDED_MESSAGE == 1 @@ -1907,7 +1907,7 @@ /* check message */ if (extended_msg[2] == EXTENDED_SDTR) - ret = AM53C974_sync_neg(instance, cmd->target, extended_msg); + ret = AM53C974_sync_neg(instance, cmd->device->id, extended_msg); if (ret || hostdata->aborted) AM53C974_write_8(CMDREG, CMDREG_SATN); @@ -1962,9 +1962,9 @@ AM53C974_write_8(CMDREG, CMDREG_CFIFO); /* clear FIFO */ } #ifdef AM53C974_PROHIBIT_DISCONNECT - tmp[0] = IDENTIFY(0, cmd->lun); + tmp[0] = IDENTIFY(0, cmd->device->lun); #else - tmp[0] = IDENTIFY(1, cmd->lun); + tmp[0] = IDENTIFY(1, cmd->device->lun); #endif #ifdef SCSI2 @@ -1995,16 +1995,16 @@ /* in case of an inquiry or req. sense command with no sync. neg performed yet, we start sync negotiation via start stops and transfer the command in cmdout phase */ if (((cmd->cmnd[0] == INQUIRY) || (cmd->cmnd[0] == REQUEST_SENSE)) && - !(hostdata->sync_neg[cmd->target]) && hostdata->sync_en[cmd->target]) { - hostdata->sync_neg[cmd->target] = 1; + !(hostdata->sync_neg[cmd->device->id]) && hostdata->sync_en[cmd->device->id]) { + hostdata->sync_neg[cmd->device->id] = 1; hostdata->msgout[0] = EXTENDED_MESSAGE; hostdata->msgout[1] = 3; hostdata->msgout[2] = EXTENDED_SDTR; - hostdata->msgout[3] = 250 / (int) hostdata->max_rate[cmd->target]; - hostdata->msgout[4] = hostdata->max_offset[cmd->target]; + hostdata->msgout[3] = 250 / (int) hostdata->max_rate[cmd->device->id]; + hostdata->msgout[4] = hostdata->max_offset[cmd->device->id]; len += 5; } - AM53C974_write_8(SDIDREG, SDIREG_MASK & cmd->target); /* setup dest. id */ + AM53C974_write_8(SDIDREG, SDIREG_MASK & cmd->device->id); /* setup dest. id */ AM53C974_write_8(STIMREG, DEF_SCSI_TIMEOUT); /* setup timeout reg */ switch (len) { case 1: @@ -2110,7 +2110,7 @@ * just reestablished, and remove it from the disconnected queue. */ for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble) - if ((target == tmp->target) && (lun == tmp->lun) + if ((target == tmp->device->id) && (lun == tmp->device->lun) #ifdef SCSI2 && (tag == tmp->tag) #endif @@ -2279,7 +2279,7 @@ { AM53C974_local_declare(); unsigned long flags; - struct Scsi_Host *instance = cmd->host; + struct Scsi_Host *instance = cmd->device->host; struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata; Scsi_Cmnd *tmp, **prev; @@ -2388,7 +2388,7 @@ AM53C974_local_declare(); unsigned long flags; int i; - struct Scsi_Host *instance = cmd->host; + struct Scsi_Host *instance = cmd->device->host; struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *) instance->hostdata; AM53C974_setio(instance); diff -Nru a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c --- a/drivers/scsi/BusLogic.c Sun Feb 9 21:13:36 2003 +++ b/drivers/scsi/BusLogic.c Sun Feb 9 21:13:36 2003 @@ -3471,15 +3471,15 @@ void (*CompletionRoutine)(SCSI_Command_T *)) { BusLogic_HostAdapter_T *HostAdapter = - (BusLogic_HostAdapter_T *) Command->host->hostdata; + (BusLogic_HostAdapter_T *) Command->device->host->hostdata; BusLogic_TargetFlags_T *TargetFlags = - &HostAdapter->TargetFlags[Command->target]; + &HostAdapter->TargetFlags[Command->device->id]; BusLogic_TargetStatistics_T *TargetStatistics = HostAdapter->TargetStatistics; unsigned char *CDB = Command->cmnd; int CDB_Length = Command->cmd_len; - int TargetID = Command->target; - int LogicalUnit = Command->lun; + int TargetID = Command->device->id; + int LogicalUnit = Command->device->lun; void *BufferPointer = Command->request_buffer; int BufferLength = Command->request_bufflen; int SegmentCount = Command->use_sg; @@ -3708,8 +3708,9 @@ int BusLogic_AbortCommand(SCSI_Command_T *Command) { BusLogic_HostAdapter_T *HostAdapter = - (BusLogic_HostAdapter_T *) Command->host->hostdata; - int TargetID = Command->target; + (BusLogic_HostAdapter_T *) Command->device->host->hostdata; + + int TargetID = Command->device->id; BusLogic_CCB_T *CCB; int Result; BusLogic_IncrementErrorCounter( @@ -3835,7 +3836,7 @@ else { BusLogic_IncrementErrorCounter( - &HostAdapter->TargetStatistics[Command->target] + &HostAdapter->TargetStatistics[Command->device->id] .HostAdapterResetsRequested); HardReset = true; } @@ -3845,7 +3846,7 @@ */ if (ResetFlags & SCSI_RESET_ASYNCHRONOUS) { - TargetID = Command->target; + TargetID = Command->device->id; if (Command->serial_number != Command->serial_number_at_timeout) { BusLogic_Warning("Unable to Reset Command to Target %d - " @@ -3890,9 +3891,9 @@ else { BusLogic_Warning("Resetting %s due to Target %d\n", HostAdapter, - HostAdapter->FullModelName, Command->target); + HostAdapter->FullModelName, Command->device->id); BusLogic_IncrementErrorCounter( - &HostAdapter->TargetStatistics[Command->target] + &HostAdapter->TargetStatistics[Command->device->id] .HostAdapterResetsAttempted); } /* @@ -3908,7 +3909,7 @@ } if (Command != NULL) BusLogic_IncrementErrorCounter( - &HostAdapter->TargetStatistics[Command->target] + &HostAdapter->TargetStatistics[Command->device->id] .HostAdapterResetsCompleted); /* Mark all currently executing CCBs as having been Reset. @@ -3975,7 +3976,7 @@ SCSI_Command_T *Command, unsigned int ResetFlags) { - int TargetID = Command->target; + int TargetID = Command->device->id; BusLogic_CCB_T *CCB, *XCCB; int Result = -1; BusLogic_IncrementErrorCounter( @@ -4152,8 +4153,8 @@ int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags) { BusLogic_HostAdapter_T *HostAdapter = - (BusLogic_HostAdapter_T *) Command->host->hostdata; - int TargetID = Command->target; + (BusLogic_HostAdapter_T *) Command->device->host->hostdata; + int TargetID = Command->device->id; BusLogic_ErrorRecoveryStrategy_T ErrorRecoveryStrategy = HostAdapter->ErrorRecoveryStrategy[TargetID]; /* diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig --- a/drivers/scsi/Kconfig Sun Feb 9 21:13:36 2003 +++ b/drivers/scsi/Kconfig Sun Feb 9 21:13:36 2003 @@ -13,7 +13,7 @@ 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 will be called sd_mod.o. If you want to compile it as a + The module will be called sd_mod. If you want to compile it as a module, say M here and read and . Do not compile this driver as a module if your root file system (the one containing the directory /) @@ -32,7 +32,7 @@ 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 will be called st.o. If you want to compile it as a + The module will be called st. If you want to compile it as a module, say M here and read and . @@ -57,7 +57,7 @@ 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 will be called osst.o. If you want to compile it as a + The module will be called osst. If you want to compile it as a module, say M here and read and . @@ -72,7 +72,7 @@ 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 will be called sr_mod.o. If you want to compile it as a + The module will be called sr_mod. If you want to compile it as a module, say M here and read and . @@ -108,7 +108,7 @@ 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 and - . The module will be called sg.o. + . The module will be called sg. If unsure, say N. comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs" @@ -176,6 +176,9 @@ config SGIWD93_SCSI tristate "SGI WD93C93 SCSI Driver" depends on SGI_IP22 && SCSI + help + If you have a Western Digital WD93 SCSI controller on + an SGI MIPS system, say Y. Otherwise, say N. config SCSI_DECNCR tristate "DEC NCR53C94 Scsi Driver" @@ -211,7 +214,7 @@ 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 will be called wd7000.o. If you want to compile it as a + The module will be called wd7000. If you want to compile it as a module, say M here and read . config SCSI_ACARD @@ -222,7 +225,7 @@ 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 will be called atp870u.o. If you want to compile it as a + The module will be called atp870u. If you want to compile it as a module, say M here and read . config SCSI_AHA152X @@ -239,7 +242,7 @@ 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 will be called aha152x.o. If you want to compile it as a + The module will be called aha152x. If you want to compile it as a module, say M here and read . config SCSI_AHA1542 @@ -256,7 +259,7 @@ 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 aha1542.o. + will be called aha1542. config SCSI_AHA1740 tristate "Adaptec AHA1740 support" @@ -270,7 +273,7 @@ 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 will be called aha1740.o. If you want to compile it as a + The module will be called aha1740. If you want to compile it as a module, say M here and read . config SCSI_AACRAID @@ -318,7 +321,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called aic7xxx_old.o. + will be called aic7xxx_old. source "drivers/scsi/aic7xxx/Kconfig.aic79xx" @@ -335,7 +338,7 @@ inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . The module will be called - dpt_i2o.o. + dpt_i2o. config SCSI_ADVANSYS tristate "AdvanSys SCSI support" @@ -349,7 +352,7 @@ inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . The module will be called - advansys.o. + advansys. config SCSI_IN2000 tristate "Always IN2000 SCSI support" @@ -363,7 +366,7 @@ 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 in2000.o. + will be called in2000. # does not use pci dma and seems to be isa/onboard only for old machines config SCSI_AM53C974 @@ -382,7 +385,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called AM53C974.o. + will be called AM53C974. config SCSI_MEGARAID tristate "AMI MegaRAID support" @@ -394,7 +397,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called megaraid.o. + will be called megaraid. config SCSI_BUSLOGIC tristate "BusLogic SCSI support" @@ -412,7 +415,7 @@ inserted in and removed from the running kernel whenever you want), but only a single instance may be loaded. If you want to compile it as a module, say M here and read . - The module will be called BusLogic.o. + The module will be called BusLogic. config SCSI_OMIT_FLASHPOINT bool "Omit FlashPoint support" @@ -438,7 +441,7 @@ 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 will be called dmx3191d.o. If you want to compile it as + The module will be called dmx3191d. If you want to compile it as a module, say M here and read . config SCSI_DTC3280 @@ -452,7 +455,7 @@ 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 will be called dtc.o. If you want to compile it as a + The module will be called dtc. If you want to compile it as a module, say M here and read . config SCSI_EATA @@ -475,7 +478,7 @@ 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 eata.o. + will be called eata. config SCSI_EATA_TAGGED_QUEUE bool "enable tagged command queueing" @@ -524,7 +527,7 @@ 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 will be called eata_dma.o. If you want to compile it as + The module will be called eata_dma. If you want to compile it as a module, say M here and read . config SCSI_EATA_PIO @@ -541,7 +544,7 @@ 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 eata_pio.o. + will be called eata_pio. config SCSI_FUTURE_DOMAIN tristate "Future Domain 16xx SCSI/AHA-2920A support" @@ -561,7 +564,7 @@ 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 will be called fdomain.o. If you want to compile it as a + The module will be called fdomain. If you want to compile it as a module, say M here and read . config SCSI_FD_MCS @@ -576,7 +579,7 @@ 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 will be called fd_mcs.o. If you want to compile it as a + The module will be called fd_mcs. If you want to compile it as a module, say M here and read . config SCSI_GDTH @@ -613,7 +616,7 @@ 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 will be called g_NCR5380.o. If you want to compile it as + The module will be called g_NCR5380. If you want to compile it as a module, say M here and read . config SCSI_GENERIC_NCR5380_MMIO @@ -629,7 +632,7 @@ 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 will be called g_NCR5380.o. If you want to compile it as + The module will be called g_NCR5380. If you want to compile it as a module, say M here and read . config SCSI_GENERIC_NCR53C400 @@ -665,7 +668,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called ibmmca.o. + will be called ibmmca. config IBMMCA_SCSI_ORDER_STANDARD bool "Standard SCSI-order" @@ -729,7 +732,7 @@ inserted in and removed from the running kernel whenever you want), but only a single instance may be loaded. If you want to compile it as a module, say M here and read . - The module will be called ips.o. + The module will be called ips. config SCSI_INITIO tristate "Initio 9100U(W) support" @@ -742,7 +745,7 @@ 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 initio.o. + will be called initio. config SCSI_INIA100 tristate "Initio INI-A100U2W support" @@ -755,7 +758,7 @@ 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 a100u2w.o. + will be called a100u2w. config SCSI_PPA tristate "IOMEGA parallel port (ppa - older drives)" @@ -784,7 +787,7 @@ This driver is also available as a module which can be inserted in and removed from the running kernel whenever you want. To compile this driver as a module, say M here and read - . The module will be called ppa.o. + . The module will be called ppa. config SCSI_IMM tristate "IOMEGA parallel port (imm - newer drives)" @@ -813,7 +816,7 @@ This driver is also available as a module which can be inserted in and removed from the running kernel whenever you want. To compile this driver as a module, say M here and read - . The module will be called imm.o. + . The module will be called imm. config SCSI_IZIP_EPP16 bool "ppa/imm option - Use slow (but safe) EPP-16" @@ -856,7 +859,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called NCR53c406.o. + will be called NCR53c406. config SCSI_NCR_D700 tristate "NCR Dual 700 MCA SCSI support" @@ -915,7 +918,7 @@ 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 will be called 53c7,8xx.o. If you want to compile it as + The module will be called 53c7,8xx. If you want to compile it as a module, say M here and read . config SCSI_NCR53C7xx_sync @@ -1230,7 +1233,7 @@ If you want to compile this as a module (= code which can be inserted and removed from the running kernel whenever you want), say M here and read . The module will - be called mca_53c9x.o. + be called mca_53c9x. config SCSI_PAS16 tristate "PAS16 SCSI support" @@ -1244,7 +1247,7 @@ 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 will be called pas16.o. If you want to compile it as a + The module will be called pas16. If you want to compile it as a module, say M here and read . config SCSI_PCI2000 @@ -1255,7 +1258,7 @@ SCSI host adapter. Please read the SCSI-HOWTO, available from . - This driver is also available as a module called pci2000.o ( = code + This driver is also available as a module called pci2000 ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -1268,7 +1271,7 @@ SCSI host adapter. Please read the SCSI-HOWTO, available from . - This driver is also available as a module called pci2220i.o ( = code + This driver is also available as a module called pci2220i ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -1281,7 +1284,7 @@ SCSI host adapter. Please read the SCSI-HOWTO, available from . - This driver is also available as a module called psi240i.o ( = code + This driver is also available as a module called psi240i ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -1305,7 +1308,7 @@ 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 will be called qlogicfas.o. If you want to compile it as + The module will be called qlogicfas. If you want to compile it as a module, say M here and read . config SCSI_QLOGIC_ISP @@ -1325,7 +1328,7 @@ 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 will be called qlogicisp.o. If you want to compile it as + The module will be called qlogicisp. If you want to compile it as a module, say M here and read . config SCSI_QLOGIC_FC @@ -1336,12 +1339,16 @@ 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 will be called qlogicfc.o. If you want to compile it as + The module will be called qlogicfc. If you want to compile it as a module, say M here and read . config SCSI_QLOGIC_FC_FIRMWARE bool "Include loadable firmware in driver" depends on SCSI_QLOGIC_FC + help + Say Y to include ISP2100 Fabric Initiator/Target Firmware, with + expanded LUN addressing and FcTape (FCP-2) support, in the + Qlogic QLA 1280 driver. This is required on some platforms. config SCSI_QLOGIC_1280 tristate "Qlogic QLA 1280 SCSI support" @@ -1351,7 +1358,7 @@ 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 will be called qla1280.o. If you want to compile it as + The module will be called qla1280. If you want to compile it as a module, say M here and read . config SCSI_SEAGATE @@ -1366,30 +1373,22 @@ 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 will be called seagate.o. If you want to compile it as a + The module will be called seagate. If you want to compile it as a module, say M here and read . # definitely looks note 64bit safe: config SCSI_SIM710 tristate "Simple 53c710 SCSI support (Compaq, NCR machines)" - depends on (ISA || MCA && !X86_64) && SCSI + depends on (EISA || MCA && !X86_64) && SCSI ---help--- - This is a simple driver for NCR53c710 based SCSI host adapters. + This driver for NCR53c710 based SCSI host adapters. - More complex drivers for this chip are available ("NCR53c7,8xx SCSI - support", above), but they require that the scsi chip be able to do - DMA block moves between memory and on-chip registers, which can - cause problems under certain conditions. This driver is designed to - avoid these problems and is intended to work with any Intel machines - using 53c710 chips, including various Compaq and NCR machines. + It currently supports Compaq EISA cards and NCR MCA cards - Please read the comments at the top of the file - for more information. - - If you want to compile this driver as a module ( = code which can be - inserted in and removed from the running kernel whenever you want), - say M here and read . The module - will be called sim710.o. +config 53C700_IO_MAPPED + bool + depends on SCSI_SIM710 + default y config SCSI_SYM53C416 tristate "Symbios 53c416 SCSI support" @@ -1410,7 +1409,7 @@ this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module will be called - sym53c416.o. + sym53c416. config SCSI_DC390T tristate "Tekram DC390(T) and Am53/79C974 SCSI support" @@ -1430,7 +1429,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called tmscsim.o. + will be called tmscsim. config SCSI_DC390T_NOGENSUPP bool "_omit_ support for non-DC390 adapters" @@ -1463,7 +1462,7 @@ 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 will be called t128.o. If you want to compile it as a + The module will be called t128. If you want to compile it as a module, say M here and read . config SCSI_U14_34F @@ -1482,7 +1481,7 @@ 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 will be called u14-34f.o. If you want to compile it as a + The module will be called u14-34f. If you want to compile it as a module, say M here and read . config SCSI_U14_34F_TAGGED_QUEUE @@ -1534,7 +1533,7 @@ 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 ultrastor.o. + will be called ultrastor. config SCSI_NSP32 tristate "Workbit NinjaSCSI-32Bi/UDE support" @@ -1547,7 +1546,7 @@ 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 nsp32.o. + will be called nsp32. config SCSI_DEBUG tristate "SCSI debugging host simulator" @@ -1569,7 +1568,7 @@ Many Power Macintoshes and clones have a MESH (Macintosh Enhanced SCSI Hardware) SCSI bus adaptor (the 7200 doesn't, but all of the other Power Macintoshes do). Say Y to include support for this SCSI - adaptor. This driver is also available as a module called mesh.o + adaptor. This driver is also available as a module called mesh ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -1602,7 +1601,7 @@ machines which only have one SCSI bus, such as the 7200, also use the 53C94. Say Y to include support for the 53C94. - This driver is also available as a module called mac53c94.o ( = code + This driver is also available as a module called mac53c94 ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -1625,7 +1624,7 @@ built-in SCSI controller, say Y. Otherwise, say N. 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 wd33c93.o. If you want to compile it as a module, say M here + called wd33c93. If you want to compile it as a module, say M here and read . config A4000T_SCSI @@ -1641,7 +1640,7 @@ If you have a Commodore A2091 SCSI controller, say Y. Otherwise, say N. 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 wd33c93.o. If you want to compile it as + want). The module is called wd33c93. If you want to compile it as a module, say M here and read . config GVP11_SCSI @@ -1656,7 +1655,7 @@ 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 will be called gvp11.o. If you want to compile it + want). The module will be called gvp11. If you want to compile it as a module, say M here and read . config CYBERSTORM_SCSI diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile --- a/drivers/scsi/Makefile Sun Feb 9 21:13:35 2003 +++ b/drivers/scsi/Makefile Sun Feb 9 21:13:35 2003 @@ -18,8 +18,6 @@ CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM -export-objs := scsi_syms.o scsi_proc.o 53c700.o - subdir-$(CONFIG_PCMCIA) += pcmcia obj-$(CONFIG_SCSI) += scsi_mod.o @@ -45,7 +43,7 @@ obj-$(CONFIG_SUN3_SCSI) += sun3_scsi.o sun3_scsi_vme.o obj-$(CONFIG_MVME16x_SCSI) += mvme16x.o 53c7xx.o obj-$(CONFIG_BVME6000_SCSI) += bvme6000.o 53c7xx.o -obj-$(CONFIG_SCSI_SIM710) += sim710.o +obj-$(CONFIG_SCSI_SIM710) += sim710.o 53c700.o obj-$(CONFIG_SCSI_ADVANSYS) += advansys.o obj-$(CONFIG_SCSI_PCI2000) += pci2000.o obj-$(CONFIG_SCSI_PCI2220I) += pci2220i.o @@ -80,7 +78,6 @@ obj-$(CONFIG_SCSI_T128) += t128.o obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o obj-$(CONFIG_SCSI_DTC3280) += dtc.o -obj-$(CONFIG_SCSI_NCR53C7xx) += 53c7,8xx.o obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/ obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o obj-$(CONFIG_SCSI_NCR53C8XX) += ncr53c8xx.o @@ -141,12 +138,10 @@ cpqfcTSworker.o cpqfcTStrigger.o # Files generated that shall be removed upon make clean -clean-files := 53c8xx_d.h 53c7xx_d.h sim710_d.h 53c700_d.h \ - 53c8xx_u.h 53c7xx_u.h sim710_u.h 53c700_u.h +clean-files := 53c7xx_d.h 53c700_d.h \ + 53c7xx_u.h 53c700_u.h -$(obj)/53c7,8xx.o: $(obj)/53c8xx_d.h $(obj)/53c8xx_u.h $(obj)/53c7xx.o: $(obj)/53c7xx_d.h $(obj)/53c7xx_u.h -$(obj)/sim710.o: $(obj)/sim710_d.h $(obj)/53c700.o $(MODVERDIR)/$(obj)/53c700.ver: $(obj)/53c700_d.h # If you want to play with the firmware, uncomment @@ -154,20 +149,10 @@ ifdef GENERATE_FIRMWARE -$(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl - $(CPP) -traditional -DCHIP=810 - < $< | grep -v '^#' | $(PERL) $(src)/script_asm.pl $@ $(@:_d.h=_u.h) - -$(obj)/53c8xx_u.h: $(obj)/53c8xx_d.h - $(obj)/53c7xx_d.h: $(src)/53c7xx.scr $(src)/script_asm.pl $(CPP) -traditional -DCHIP=710 - < $< | grep -v '^#' | $(PERL) -s $(src)/script_asm.pl -ncr7x0_family $@ $(@:_d.h=_u.h) $(obj)/53c7xx_u.h: $(obj)/53c7xx_d.h - -$(obj)/sim710_d.h: $(src)/sim710.scr $(src)/script_asm.pl - $(CPP) -traditional -DCHIP=710 - < $< | grep -v '^#' | $(PERL) -s $(src)/script_asm.pl -ncr7x0_family $@ $(@:_d.h=_u.h) - -$(obj)/sim710_u.h: $(obj)/sim710_d.h $(obj)/53c700_d.h: $(src)/53c700.scr $(src)/script_asm.pl $(PERL) -s $(src)/script_asm.pl -ncr7x0_family $@ $(@:_d.h=_u.h) < $< diff -Nru a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c --- a/drivers/scsi/NCR5380.c Sun Feb 9 21:13:29 2003 +++ b/drivers/scsi/NCR5380.c Sun Feb 9 21:13:29 2003 @@ -929,7 +929,7 @@ static char *lprint_Scsi_Cmnd(Scsi_Cmnd * cmd, char *pos, char *buffer, int length) { - SPRINTF("scsi%d : destination target %d, lun %d\n", cmd->host->host_no, cmd->target, cmd->lun); + SPRINTF("scsi%d : destination target %d, lun %d\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun); SPRINTF(" command = "); pos = lprint_command(cmd->cmnd, pos, buffer, length); return (pos); @@ -1106,7 +1106,7 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) { - struct Scsi_Host *instance = cmd->host; + struct Scsi_Host *instance = cmd->device->host; struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; Scsi_Cmnd *tmp; @@ -1126,15 +1126,15 @@ case WRITE: case WRITE_6: case WRITE_10: - hostdata->time_write[cmd->target] -= (jiffies - hostdata->timebase); - hostdata->bytes_write[cmd->target] += cmd->request_bufflen; + hostdata->time_write[cmd->device->id] -= (jiffies - hostdata->timebase); + hostdata->bytes_write[cmd->device->id] += cmd->request_bufflen; hostdata->pendingw++; break; case READ: case READ_6: case READ_10: - hostdata->time_read[cmd->target] -= (jiffies - hostdata->timebase); - hostdata->bytes_read[cmd->target] += cmd->request_bufflen; + hostdata->time_read[cmd->device->id] -= (jiffies - hostdata->timebase); + hostdata->bytes_read[cmd->device->id] += cmd->request_bufflen; hostdata->pendingr++; break; } @@ -1224,7 +1224,7 @@ if (prev != tmp) dprintk(NDEBUG_LISTS, ("MAIN tmp=%p target=%d busy=%d lun=%d\n", tmp, tmp->target, hostdata->busy[tmp->target], tmp->lun)); /* When we find one, remove it from the issue queue. */ - if (!(hostdata->busy[tmp->target] & (1 << tmp->lun))) { + if (!(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))) { if (prev) { REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble); prev->host_scribble = tmp->host_scribble; @@ -1286,7 +1286,7 @@ this is needed for Mustek scanners, that do not respond to commands immediately after a scan */ - printk(KERN_DEBUG "scsi%d: device %d did not respond in time\n", instance->host_no, tmp->target); + printk(KERN_DEBUG "scsi%d: device %d did not respond in time\n", instance->host_no, tmp->device->id); LIST(tmp, hostdata->issue_queue); tmp->host_scribble = (unsigned char *) hostdata->issue_queue; hostdata->issue_queue = tmp; @@ -1421,13 +1421,13 @@ case WRITE: case WRITE_6: case WRITE_10: - hostdata->time_write[cmd->target] += (jiffies - hostdata->timebase); + hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase); hostdata->pendingw--; break; case READ: case READ_6: case READ_10: - hostdata->time_read[cmd->target] += (jiffies - hostdata->timebase); + hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase); hostdata->pendingr--; break; } @@ -1567,7 +1567,7 @@ * the host and target ID's on the SCSI bus. */ - NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->target))); + NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id))); /* * Raise ATN while SEL is true before BSY goes false from arbitration, @@ -1612,7 +1612,7 @@ udelay(1); - dprintk(NDEBUG_SELECTION, ("scsi%d : selecting target %d\n", instance->host_no, cmd->target)); + dprintk(NDEBUG_SELECTION, ("scsi%d : selecting target %d\n", instance->host_no, cmd->device->id)); /* * The SCSI specification calls for a 250 ms timeout for the actual @@ -1668,7 +1668,7 @@ if (!(NCR5380_read(STATUS_REG) & SR_BSY)) { NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - if (hostdata->targets_present & (1 << cmd->target)) { + if (hostdata->targets_present & (1 << cmd->device->id)) { printk(KERN_DEBUG "scsi%d : weirdness\n", instance->host_no); if (hostdata->restart_select) printk(KERN_DEBUG "\trestart select\n"); @@ -1686,7 +1686,7 @@ NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); return 0; } - hostdata->targets_present |= (1 << cmd->target); + hostdata->targets_present |= (1 << cmd->device->id); /* * Since we followed the SCSI spec, and raised ATN while SEL @@ -1713,8 +1713,8 @@ goto failed; } - dprintk(NDEBUG_SELECTION, ("scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->target)); - tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->lun); + dprintk(NDEBUG_SELECTION, ("scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id)); + tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->device->lun); if(instance->irq != IRQ_NONE) spin_lock_irq(instance->host_lock); @@ -1729,7 +1729,7 @@ dprintk(NDEBUG_SELECTION, ("scsi%d : nexus established.\n", instance->host_no)); /* XXX need to handle errors here */ hostdata->connected = cmd; - hostdata->busy[cmd->target] |= (1 << cmd->lun); + hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); initialize_SCp(cmd); @@ -2380,7 +2380,7 @@ * If the watchdog timer fires, all future accesses to this * device will use the polled-IO. */ - printk("scsi%d : switching target %d lun %d to slow handshake\n", instance->host_no, cmd->target, cmd->lun); + printk("scsi%d : switching target %d lun %d to slow handshake\n", instance->host_no, cmd->device->id, cmd->device->lun); cmd->device->borken = 1; NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); sink = 1; @@ -2417,14 +2417,14 @@ case LINKED_FLG_CMD_COMPLETE: /* Accept message by clearing ACK */ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked command complete.\n", instance->host_no, cmd->target, cmd->lun)); + dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked command complete.\n", instance->host_no, cmd->device->id, cmd->device->lun)); /* * Sanity check : A linked command should only terminate with * one of these messages if there are more linked commands * available. */ if (!cmd->next_link) { - printk("scsi%d : target %d lun %d linked command complete, no next_link\n" instance->host_no, cmd->target, cmd->lun); + printk("scsi%d : target %d lun %d linked command complete, no next_link\n" instance->host_no, cmd->device->id, cmd->device->lun); sink = 1; do_abort(instance); return; @@ -2433,7 +2433,7 @@ /* The next command is still part of this process */ cmd->next_link->tag = cmd->tag; cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); - dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked request done, calling scsi_done().\n", instance->host_no, cmd->target, cmd->lun)); + dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun)); collect_stats(hostdata, cmd); cmd->scsi_done(cmd); cmd = hostdata->connected; @@ -2445,8 +2445,8 @@ sink = 1; NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); hostdata->connected = NULL; - dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d, lun %d completed\n", instance->host_no, cmd->target, cmd->lun)); - hostdata->busy[cmd->target] &= ~(1 << cmd->lun); + dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d, lun %d completed\n", instance->host_no, cmd->device->id, cmd->device->lun)); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); /* * I'm not sure what the correct thing to do here is : @@ -2514,7 +2514,7 @@ case ORDERED_QUEUE_TAG: case SIMPLE_QUEUE_TAG: cmd->device->tagged_queue = 0; - hostdata->busy[cmd->target] |= (1 << cmd->lun); + hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); break; default: break; @@ -2528,7 +2528,7 @@ hostdata->disconnected_queue; hostdata->connected = NULL; hostdata->disconnected_queue = cmd; - dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d lun %d was moved from connected to" " the disconnected_queue\n", instance->host_no, cmd->target, cmd->lun)); + dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d lun %d was moved from connected to" " the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun)); /* * Restore phase bits to 0 so an interrupted selection, * arbitration can resume. @@ -2619,9 +2619,9 @@ print_msg(extended_msg); printk("\n"); } else if (tmp != EXTENDED_MESSAGE) - printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n", instance->host_no, tmp, cmd->target, cmd->lun); + printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n", instance->host_no, tmp, cmd->device->id, cmd->device->lun); else - printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n", instance->host_no, extended_msg[1], extended_msg[0], cmd->target, cmd->lun); + printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n", instance->host_no, extended_msg[1], extended_msg[0], cmd->device->id, cmd->device->lun); msgout = MESSAGE_REJECT; NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); @@ -2634,7 +2634,7 @@ hostdata->last_message = msgout; NCR5380_transfer_pio(instance, &phase, &len, &data); if (msgout == ABORT) { - hostdata->busy[cmd->target] &= ~(1 << cmd->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); hostdata->connected = NULL; cmd->result = DID_ERROR << 16; collect_stats(hostdata, cmd); @@ -2772,7 +2772,7 @@ for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble) - if ((target_mask == (1 << tmp->target)) && (lun == tmp->lun) + if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun) ) { if (prev) { REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble); @@ -2872,7 +2872,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) { NCR5380_local_declare(); - struct Scsi_Host *instance = cmd->host; + struct Scsi_Host *instance = cmd->device->host; struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; Scsi_Cmnd *tmp, **prev; @@ -3031,10 +3031,10 @@ static int NCR5380_bus_reset(Scsi_Cmnd * cmd) { NCR5380_local_declare(); - NCR5380_setup(cmd->host); + NCR5380_setup(cmd->device->host); - NCR5380_print_status(cmd->host); - do_reset(cmd->host); + NCR5380_print_status(cmd->device->host); + do_reset(cmd->device->host); return SUCCESS; } diff -Nru a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c --- a/drivers/scsi/aacraid/aachba.c Sun Feb 9 21:13:31 2003 +++ b/drivers/scsi/aacraid/aachba.c Sun Feb 9 21:13:31 2003 @@ -392,8 +392,8 @@ * Arguments: [1] pointer to void [1] int * * Purpose: Sets SCSI inquiry data strings for vendor, product - * and revision level. Allows strings to be set in platform dependant - * files instead of in OS dependant driver source. + * and revision level. Allows strings to be set in platform dependent + * files instead of in OS dependent driver source. */ static void setinqstr(int devtype, void *data, int tindex) @@ -463,9 +463,9 @@ static void aac_io_done(Scsi_Cmnd * scsicmd) { unsigned long cpu_flags; - spin_lock_irqsave(scsicmd->host->host_lock, cpu_flags); + spin_lock_irqsave(scsicmd->device->host->host_lock, cpu_flags); scsicmd->scsi_done(scsicmd); - spin_unlock_irqrestore(scsicmd->host->host_lock, cpu_flags); + spin_unlock_irqrestore(scsicmd->device->host->host_lock, cpu_flags); } static void __aac_io_done(Scsi_Cmnd * scsicmd) @@ -546,8 +546,8 @@ scsicmd = (Scsi_Cmnd *) context; - dev = (struct aac_dev *)scsicmd->host->hostdata; - cid =TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun); + dev = (struct aac_dev *)scsicmd->device->host->hostdata; + cid =TARGET_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %d, t = %ld.\n", smp_processor_id(), lba, jiffies)); @@ -591,8 +591,8 @@ u32 cid; scsicmd = (Scsi_Cmnd *) context; - dev = (struct aac_dev *)scsicmd->host->hostdata; - cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun); + dev = (struct aac_dev *)scsicmd->device->host->hostdata; + cid = TARGET_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %d, t = %ld.\n", smp_processor_id(), lba, jiffies)); @@ -637,7 +637,7 @@ struct aac_dev *dev; struct fib * cmd_fibcontext; - dev = (struct aac_dev *)scsicmd->host->hostdata; + dev = (struct aac_dev *)scsicmd->device->host->hostdata; /* * Get block address and transfer length */ @@ -746,7 +746,7 @@ struct aac_dev *dev; struct fib * cmd_fibcontext; - dev = (struct aac_dev *)scsicmd->host->hostdata; + dev = (struct aac_dev *)scsicmd->device->host->hostdata; /* * Get block address and transfer length */ @@ -861,25 +861,25 @@ struct fsa_scsi_hba *fsa_dev_ptr; int cardtype; int ret; - struct aac_dev *dev = (struct aac_dev *)scsicmd->host->hostdata; + struct aac_dev *dev = (struct aac_dev *)scsicmd->device->host->hostdata; cardtype = dev->cardtype; - fsa_dev_ptr = fsa_dev[scsicmd->host->unique_id]; + fsa_dev_ptr = fsa_dev[scsicmd->device->host->unique_id]; /* * If the bus, target or lun is out of range, return fail * Test does not apply to ID 16, the pseudo id for the controller * itself. */ - if (scsicmd->target != scsicmd->host->this_id) { - if ((scsicmd->channel == 0) ){ - if( (scsicmd->target >= AAC_MAX_TARGET) || (scsicmd->lun != 0)){ + if (scsicmd->device->id != scsicmd->device->host->this_id) { + if ((scsicmd->device->channel == 0) ){ + if( (scsicmd->device->id >= AAC_MAX_TARGET) || (scsicmd->device->lun != 0)){ scsicmd->result = DID_NO_CONNECT << 16; __aac_io_done(scsicmd); return 0; } - cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun); + cid = TARGET_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); /* * If the target container doesn't exist, it may have @@ -890,9 +890,9 @@ case SS_INQUIR: case SS_RDCAP: case SS_TEST: - spin_unlock_irq(scsicmd->host->host_lock); + spin_unlock_irq(scsicmd->device->host->host_lock); probe_container(dev, cid); - spin_lock_irq(scsicmd->host->host_lock); + spin_lock_irq(scsicmd->device->host->host_lock); if (fsa_dev_ptr->valid[cid] == 0) { scsicmd->result = DID_NO_CONNECT << 16; __aac_io_done(scsicmd); @@ -944,7 +944,7 @@ { struct inquiry_data *inq_data_ptr; - dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->target)); + dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id)); inq_data_ptr = (struct inquiry_data *)scsicmd->request_buffer; memset(inq_data_ptr, 0, sizeof (struct inquiry_data)); @@ -959,7 +959,7 @@ * see: .c i.e. aac.c */ setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr->type[cid]); - if (scsicmd->target == scsicmd->host->this_id) + if (scsicmd->device->id == scsicmd->device->host->this_id) inq_data_ptr->inqd_pdt = INQD_PDT_PROC; /* Processor device */ else inq_data_ptr->inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ @@ -1053,20 +1053,20 @@ * containers to /dev/sd device names */ - spin_unlock_irq(scsicmd->host->host_lock); + spin_unlock_irq(scsicmd->device->host->host_lock); if (scsicmd->request->rq_disk) memcpy(fsa_dev_ptr->devname[cid], scsicmd->request->rq_disk->disk_name, 8); ret = aac_read(scsicmd, cid); - spin_lock_irq(scsicmd->host->host_lock); + spin_lock_irq(scsicmd->device->host->host_lock); return ret; case SS_WRITE: case SM_WRITE: - spin_unlock_irq(scsicmd->host->host_lock); + spin_unlock_irq(scsicmd->device->host->host_lock); ret = aac_write(scsicmd, cid); - spin_lock_irq(scsicmd->host->host_lock); + spin_lock_irq(scsicmd->device->host->host_lock); return ret; default: /* @@ -1202,7 +1202,7 @@ Scsi_Cmnd *scsicmd; scsicmd = (Scsi_Cmnd *) context; - dev = (struct aac_dev *)scsicmd->host->hostdata; + dev = (struct aac_dev *)scsicmd->device->host->hostdata; if (fibptr == NULL) BUG(); @@ -1366,13 +1366,13 @@ u16 fibsize; u32 flag; - if( scsicmd->target > 15 || scsicmd->lun > 7) { + if( scsicmd->device->id > 15 || scsicmd->device->lun > 7) { scsicmd->result = DID_NO_CONNECT << 16; __aac_io_done(scsicmd); return 0; } - dev = (struct aac_dev *)scsicmd->host->hostdata; + dev = (struct aac_dev *)scsicmd->device->host->hostdata; switch(scsicmd->sc_data_direction){ case SCSI_DATA_WRITE: flag = SRB_DataOut; @@ -1402,9 +1402,9 @@ srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext); srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); - srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scsicmd->channel)); - srbcmd->target = cpu_to_le32(scsicmd->target); - srbcmd->lun = cpu_to_le32(scsicmd->lun); + srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scsicmd->device->channel)); + srbcmd->target = cpu_to_le32(scsicmd->device->id); + srbcmd->lun = cpu_to_le32(scsicmd->device->lun); srbcmd->flags = cpu_to_le32(flag); srbcmd->timeout = cpu_to_le32(0); // timeout not used srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter @@ -1468,7 +1468,7 @@ struct aac_dev *dev; unsigned long byte_count = 0; - dev = (struct aac_dev *)scsicmd->host->hostdata; + dev = (struct aac_dev *)scsicmd->device->host->hostdata; // Get rid of old data psg->count = cpu_to_le32(0); psg->sg[0].addr = cpu_to_le32(NULL); @@ -1524,7 +1524,7 @@ unsigned long byte_count = 0; u64 le_addr; - dev = (struct aac_dev *)scsicmd->host->hostdata; + dev = (struct aac_dev *)scsicmd->device->host->hostdata; // Get rid of old data psg->count = cpu_to_le32(0); psg->sg[0].addr[0] = cpu_to_le32(NULL); diff -Nru a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h --- a/drivers/scsi/aacraid/aacraid.h Sun Feb 9 21:13:29 2003 +++ b/drivers/scsi/aacraid/aacraid.h Sun Feb 9 21:13:29 2003 @@ -79,7 +79,7 @@ /* * Host side memory scatter gather list * Used by the adapter for read, write, and readdirplus operations - * We have seperate 32 and 64 bit version because even + * We have separate 32 and 64 bit version because even * on 64 bit systems not all cards support the 64 bit version */ struct sgentry { @@ -443,7 +443,7 @@ /* * The adapter interface specs all queues to be located in the same * physically contigous block. The host structure that defines the - * commuication queues will assume they are each a seperate physically + * commuication queues will assume they are each a separate physically * contigous memory region that will support them all being one big * contigous block. * There is a command and response queue for each level and direction of diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c --- a/drivers/scsi/aacraid/linit.c Sun Feb 9 21:13:31 2003 +++ b/drivers/scsi/aacraid/linit.c Sun Feb 9 21:13:31 2003 @@ -536,7 +536,7 @@ dprintk((KERN_DEBUG "(scsi%d:%d:%d:%d) Tagged Queue depth %2d, " "%s\n", dev->host->host_no, dev->channel, - dev->id, dev->lun, dev->new_queue_depth, + dev->id, dev->lun, dev->queue_depth, dev->online ? "OnLine" : "OffLine")); return 0; } diff -Nru a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c --- a/drivers/scsi/advansys.c Sun Feb 9 21:13:30 2003 +++ b/drivers/scsi/advansys.c Sun Feb 9 21:13:30 2003 @@ -3641,7 +3641,7 @@ typedef Scsi_Cmnd REQ, *REQP; #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble)) #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble)) -#define REQPTID(reqp) ((reqp)->target) +#define REQPTID(reqp) ((reqp)->device->id) #define REQPTIME(reqp) ((reqp)->SCp.this_residual) #define REQTIMESTAMP() (jiffies) @@ -5845,7 +5845,7 @@ ulong flags; Scsi_Cmnd *done_scp; - shp = scp->host; + shp = scp->device->host; boardp = ASC_BOARDP(shp); ASC_STATS(shp, queuecommand); @@ -5941,12 +5941,12 @@ ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp); #ifdef ADVANSYS_STATS - if (scp->host != NULL) { - ASC_STATS(scp->host, reset); + if (scp->device->host != NULL) { + ASC_STATS(scp->device->host, reset); } #endif /* ADVANSYS_STATS */ - if ((shp = scp->host) == NULL) { + if ((shp = scp->device->host) == NULL) { scp->result = HOST_BYTE(DID_ERROR); return FAILED; } @@ -6390,13 +6390,13 @@ ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp); tscp = REQPNEXT(scp); REQPNEXT(scp) = NULL; - ASC_STATS(scp->host, done); + ASC_STATS(scp->device->host, done); ASC_ASSERT(scp->scsi_done != NULL); if (from_isr) - spin_lock_irqsave(scp->host->host_lock, flags); + spin_lock_irqsave(scp->device->host->host_lock, flags); scp->scsi_done(scp); if (from_isr) - spin_unlock_irqrestore(scp->host->host_lock, flags); + spin_unlock_irqrestore(scp->device->host->host_lock, flags); scp = tscp; } ASC_DBG(2, "asc_scsi_done_list: done\n"); @@ -6462,8 +6462,8 @@ ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n", (ulong) scp, (ulong) scp->scsi_done); - boardp = ASC_BOARDP(scp->host); - device = boardp->device[scp->target]; + boardp = ASC_BOARDP(scp->device->host); + device = boardp->device[scp->device->id]; if (ASC_NARROW_BOARD(boardp)) { /* @@ -6483,7 +6483,7 @@ * asc_build_req() can not return ASC_BUSY. */ if (asc_build_req(boardp, scp) == ASC_ERROR) { - ASC_STATS(scp->host, build_error); + ASC_STATS(scp->device->host, build_error); return ASC_ERROR; } @@ -6493,12 +6493,12 @@ */ switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) { case ASC_NOERROR: - ASC_STATS(scp->host, exe_noerror); + ASC_STATS(scp->device->host, exe_noerror); /* * Increment monotonically increasing per device successful * request counter. Wrapping doesn't matter. */ - boardp->reqcnt[scp->target]++; + boardp->reqcnt[scp->device->id]++; asc_enqueue(&boardp->active, scp, ASC_BACK); ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n"); @@ -6508,13 +6508,13 @@ * Caller will enqueue request on the target's waiting queue * and retry later. */ - ASC_STATS(scp->host, exe_busy); + ASC_STATS(scp->device->host, exe_busy); break; case ASC_ERROR: ASC_PRINT2( "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n", boardp->id, asc_dvc_varp->err_code); - ASC_STATS(scp->host, exe_error); + ASC_STATS(scp->device->host, exe_error); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); break; @@ -6522,7 +6522,7 @@ ASC_PRINT2( "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n", boardp->id, asc_dvc_varp->err_code); - ASC_STATS(scp->host, exe_unknown); + ASC_STATS(scp->device->host, exe_unknown); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); break; @@ -6563,7 +6563,7 @@ */ default: ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n"); - ASC_STATS(scp->host, build_error); + ASC_STATS(scp->device->host, build_error); return ASC_ERROR; } @@ -6573,12 +6573,12 @@ */ switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) { case ASC_NOERROR: - ASC_STATS(scp->host, exe_noerror); + ASC_STATS(scp->device->host, exe_noerror); /* * Increment monotonically increasing per device successful * request counter. Wrapping doesn't matter. */ - boardp->reqcnt[scp->target]++; + boardp->reqcnt[scp->device->id]++; asc_enqueue(&boardp->active, scp, ASC_BACK); ASC_DBG(1, "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n"); @@ -6588,13 +6588,13 @@ * Caller will enqueue request on the target's waiting queue * and retry later. */ - ASC_STATS(scp->host, exe_busy); + ASC_STATS(scp->device->host, exe_busy); break; case ASC_ERROR: ASC_PRINT2( "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n", boardp->id, adv_dvc_varp->err_code); - ASC_STATS(scp->host, exe_error); + ASC_STATS(scp->device->host, exe_error); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); break; @@ -6602,7 +6602,7 @@ ASC_PRINT2( "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n", boardp->id, adv_dvc_varp->err_code); - ASC_STATS(scp->host, exe_unknown); + ASC_STATS(scp->device->host, exe_unknown); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); break; @@ -6652,9 +6652,9 @@ } asc_scsi_q.cdbptr = &scp->cmnd[0]; asc_scsi_q.q2.cdb_len = scp->cmd_len; - asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target); - asc_scsi_q.q1.target_lun = scp->lun; - asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun); + asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id); + asc_scsi_q.q1.target_lun = scp->device->lun; + asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun); asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer); @@ -6669,8 +6669,8 @@ * started request. * */ - if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) && - (boardp->reqcnt[scp->target] % 255) == 0) { + if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) && + (boardp->reqcnt[scp->device->id] % 255) == 0) { asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED; } else { asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE; @@ -6684,11 +6684,11 @@ /* * CDB request of single contiguous buffer. */ - ASC_STATS(scp->host, cont_cnt); + ASC_STATS(scp->device->host, cont_cnt); asc_scsi_q.q1.data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer)); asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen); - ASC_STATS_ADD(scp->host, cont_xfer, + ASC_STATS_ADD(scp->device->host, cont_xfer, ASC_CEILING(scp->request_bufflen, 512)); asc_scsi_q.q1.sg_queue_cnt = 0; asc_scsi_q.sg_head = NULL; @@ -6699,16 +6699,16 @@ int sgcnt; struct scatterlist *slp; - if (scp->use_sg > scp->host->sg_tablesize) { + if (scp->use_sg > scp->device->host->sg_tablesize) { ASC_PRINT3( "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n", - boardp->id, scp->use_sg, scp->host->sg_tablesize); + boardp->id, scp->use_sg, scp->device->host->sg_tablesize); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); return ASC_ERROR; } - ASC_STATS(scp->host, sg_cnt); + ASC_STATS(scp->device->host, sg_cnt); /* * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q @@ -6722,7 +6722,7 @@ asc_scsi_q.q1.data_addr = 0; /* This is a byte value, otherwise it would need to be swapped. */ asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg; - ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt); + ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt); /* * Convert scatter-gather list into ASC_SG_HEAD list. @@ -6733,7 +6733,7 @@ cpu_to_le32(virt_to_bus( (unsigned char *)page_address(slp->page) + slp->offset)); asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length); - ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512)); + ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512)); } } @@ -6768,7 +6768,7 @@ */ if (boardp->adv_reqp == NULL) { ASC_DBG(1, "adv_build_req: no free adv_req_t\n"); - ASC_STATS(scp->host, adv_build_noreq); + ASC_STATS(scp->device->host, adv_build_noreq); return ASC_BUSY; } else { reqp = boardp->adv_reqp; @@ -6823,8 +6823,8 @@ scsiqp->cdb16[i - 12] = scp->cmnd[i]; } - scsiqp->target_id = scp->target; - scsiqp->target_lun = scp->lun; + scsiqp->target_id = scp->device->id; + scsiqp->target_lun = scp->device->lun; scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); scsiqp->sense_len = sizeof(scp->sense_buffer); @@ -6844,8 +6844,8 @@ reqp->sgblkp = NULL; scsiqp->sg_list_ptr = NULL; scsiqp->sg_real_addr = 0; - ASC_STATS(scp->host, cont_cnt); - ASC_STATS_ADD(scp->host, cont_xfer, + ASC_STATS(scp->device->host, cont_cnt); + ASC_STATS_ADD(scp->device->host, cont_xfer, ASC_CEILING(scp->request_bufflen, 512)); } else { /* @@ -6854,7 +6854,7 @@ if (scp->use_sg > ADV_MAX_SG_LIST) { ASC_PRINT3( "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n", - boardp->id, scp->use_sg, scp->host->sg_tablesize); + boardp->id, scp->use_sg, scp->device->host->sg_tablesize); scp->result = HOST_BYTE(DID_ERROR); asc_enqueue(&boardp->done, scp, ASC_BACK); @@ -6879,8 +6879,8 @@ return ret; } - ASC_STATS(scp->host, sg_cnt); - ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg); + ASC_STATS(scp->device->host, sg_cnt); + ASC_STATS_ADD(scp->device->host, sg_elem, scp->use_sg); } ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); @@ -6929,7 +6929,7 @@ */ if ((sgblkp = boardp->adv_sgblkp) == NULL) { ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n"); - ASC_STATS(scp->host, adv_build_nosg); + ASC_STATS(scp->device->host, adv_build_nosg); /* * Allocation failed. Free 'adv_sgblk_t' structures already @@ -6992,7 +6992,7 @@ cpu_to_le32(virt_to_bus( (unsigned char *)page_address(slp->page) + slp->offset)); sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length); - ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512)); + ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512)); if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */ @@ -7043,7 +7043,7 @@ * If the request's host pointer is not valid, display a * message and return. */ - shp = scp->host; + shp = scp->device->host; for (i = 0; i < asc_board_count; i++) { if (asc_host[i] == shp) { break; @@ -7085,10 +7085,10 @@ * If an INQUIRY command completed successfully, then call * the AscInquiryHandling() function to set-up the device. */ - if (scp->cmnd[0] == SCSICMD_Inquiry && scp->lun == 0 && + if (scp->cmnd[0] == SCSICMD_Inquiry && scp->device->lun == 0 && (scp->request_bufflen - qdonep->remain_bytes) >= 8) { - AscInquiryHandling(asc_dvc_varp, scp->target & 0x7, + AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7, (ASC_SCSI_INQUIRY *) scp->request_buffer); } @@ -7160,10 +7160,10 @@ * current request finished normally, then set the bit for the target * to indicate that a device is present. */ - if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 && + if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && qdonep->d3.done_stat == QD_NO_ERROR && qdonep->d3.host_stat == QHSTA_NO_ERROR) { - boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target); + boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); } /* @@ -7232,7 +7232,7 @@ * If the request's host pointer is not valid, display a message * and return. */ - shp = scp->host; + shp = scp->device->host; for (i = 0; i < asc_board_count; i++) { if (asc_host[i] == shp) { break; @@ -7343,10 +7343,10 @@ * current request finished normally, then set the bit for the target * to indicate that a device is present. */ - if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 && + if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && scsiqp->done_status == QD_NO_ERROR && scsiqp->host_status == QHSTA_NO_ERROR) { - boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target); + boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); } /* @@ -7586,7 +7586,7 @@ { REQP reqp; for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) { - REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->target); + REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->device->id); } } #endif /* ADVANSYS_STATS */ @@ -8415,25 +8415,6 @@ chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; } else { chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; - } - - if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) { - len = asc_prt_line(cp, leftlen, " queue_depth:"); - ASC_PRT_NEXT(); - for (i = 0; i <= ADV_MAX_TID; i++) { - if ((chip_scsi_id == i) || - ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) { - continue; - } - if (boardp->device[i] == NULL) { - continue; - } - len = asc_prt_line(cp, leftlen, " %X:%d", - i, boardp->device[i]->current_queue_depth); - ASC_PRT_NEXT(); - } - len = asc_prt_line(cp, leftlen, "\n"); - ASC_PRT_NEXT(); } return totlen; diff -Nru a/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/drivers/scsi/aic7xxx/Kconfig.aic7xxx --- a/drivers/scsi/aic7xxx/Kconfig.aic7xxx Sun Feb 9 21:13:30 2003 +++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx Sun Feb 9 21:13:30 2003 @@ -13,7 +13,7 @@ If you want to compile the driver 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 aic7xxx.o. + will be called aic7xxx. config AIC7XXX_CMDS_PER_DEVICE int "Maximum number of TCQ commands per device" diff -Nru a/drivers/scsi/aic7xxx/aic79xx.reg b/drivers/scsi/aic7xxx/aic79xx.reg --- a/drivers/scsi/aic7xxx/aic79xx.reg Sun Feb 9 21:13:36 2003 +++ b/drivers/scsi/aic7xxx/aic79xx.reg Sun Feb 9 21:13:36 2003 @@ -39,7 +39,7 @@ * * $FreeBSD$ */ -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#59 $" +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $" /* * This file is processed by the aic7xxx_asm utility for use in assembling @@ -173,6 +173,23 @@ STATUS_OVERRUN, CFG4OVERRUN, ENTERING_NONPACK, + TASKMGMT_FUNC_COMPLETE, /* + * Task management function + * request completed with + * an expected busfree. + */ + TASKMGMT_CMD_CMPLT_OKAY, /* + * A command with a non-zero + * task management function + * has completed via the normal + * command completion method + * for commands with a zero + * task management function. + * This happens when an attempt + * to abort a command loses + * the race for the command to + * complete normally. + */ TRACEPOINT0, TRACEPOINT1, TRACEPOINT2, diff -Nru a/drivers/scsi/aic7xxx/aic79xx.seq b/drivers/scsi/aic7xxx/aic79xx.seq --- a/drivers/scsi/aic7xxx/aic79xx.seq Sun Feb 9 21:13:35 2003 +++ b/drivers/scsi/aic7xxx/aic79xx.seq Sun Feb 9 21:13:35 2003 @@ -40,7 +40,7 @@ * $FreeBSD$ */ -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#77 $" +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $" PATCH_ARG_LIST = "struct ahd_softc *ahd" PREFIX = "ahd_" @@ -107,6 +107,16 @@ good_status_IU_done: bmov SCBPTR, GSFIFO, 2; clr SCB_SCSI_STATUS; + /* + * If a command completed before an attempted task management + * function completed, notify the host after disabling any + * pending select-outs. + */ + test SCB_TASK_MANAGEMENT, 0xFF jz gsfifo_complete_normally; + test SSTAT0, SELDO|SELINGO jnz . + 2; + and SCSISEQ0, ~ENSELO; + SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY) +gsfifo_complete_normally: or SCB_CONTROL, STATUS_RCVD; /* @@ -471,7 +481,7 @@ /* * This exposes a window whereby a * busfree just after a selection will - * be missed, but there is not other safe + * be missed, but there is no other safe * way to enable busfree detection if * the busfreerev function is broken. */ @@ -597,7 +607,6 @@ cmp WAITING_TID_HEAD[1], SCB_LIST_NULL jne . + 2; mvi WAITING_TID_TAIL[1], SCB_LIST_NULL; bmov SCBPTR, CURRSCB, 2; -END_CRITICAL; mvi CLRSINT0, CLRSELDO; test LQOSTAT2, LQOPHACHGOUTPKT jnz unexpected_nonpkt_phase; test LQOSTAT1, LQOPHACHGINPKT jnz unexpected_nonpkt_phase; @@ -606,17 +615,23 @@ * If this is a packetized connection, return to our * idle_loop and let our interrupt handler deal with * any connection setup/teardown issues. The only - * exception is the case of MK_MESSAGE SCBs. In the - * A, the LQO manager transitions to LQOSTOP0 even if - * we have selected out with ATN asserted and the target - * REQs in a non-packet phase. + * exceptions are the case of MK_MESSAGE and task management + * SCBs. */ if ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0) { + /* + * In the A, the LQO manager transitions to LQOSTOP0 even if + * we have selected out with ATN asserted and the target + * REQs in a non-packet phase. + */ test SCB_CONTROL, MK_MESSAGE jz select_out_no_message; test SCSISIGO, ATNO jnz select_out_non_packetized; select_out_no_message: } - test LQOSTAT2, LQOSTOP0 jnz idle_loop; + test LQOSTAT2, LQOSTOP0 jz select_out_non_packetized; + test SCB_TASK_MANAGEMENT, 0xFF jz idle_loop; + SET_SEQINTCODE(TASKMGMT_FUNC_COMPLETE) + jmp idle_loop; select_out_non_packetized: /* Non packetized request. */ @@ -625,7 +640,7 @@ /* * This exposes a window whereby a * busfree just after a selection will - * be missed, but there is not other safe + * be missed, but there is no other safe * way to enable busfree detection if * the busfreerev function is broken. */ @@ -634,6 +649,8 @@ } mov SAVED_SCSIID, SCB_SCSIID; mov SAVED_LUN, SCB_LUN; + mvi SEQ_FLAGS, NO_CDB_SENT; +END_CRITICAL; or SXFRCTL0, SPIOEN; /* @@ -642,7 +659,6 @@ * asserted. */ mvi MSG_OUT, MSG_IDENTIFYFLAG; - mvi SEQ_FLAGS, NO_CDB_SENT; /* * Main loop for information transfer phases. Wait for the @@ -1608,7 +1624,12 @@ /* * Status pkt is transferring to host. * Wait in idle loop for transfer to complete. + * If a command completed before an attempted + * task management function completed, notify the host. */ + test SCB_TASK_MANAGEMENT, 0xFF jz cfg4istat_no_taskmgmt_func; + SET_SEQINTCODE(TASKMGMT_CMD_CMPLT_OKAY) +cfg4istat_no_taskmgmt_func: call pkt_handle_status; or SEQINTCTL, IRET ret; diff -Nru a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c --- a/drivers/scsi/aic7xxx/aic79xx_core.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_core.c Sun Feb 9 21:13:28 2003 @@ -2,7 +2,7 @@ * Core routines and tables shareable across OS platforms. * * Copyright (c) 1994-2002 Justin T. Gibbs. - * Copyright (c) 2000-2002 Adaptec Inc. + * Copyright (c) 2000-2003 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,7 +37,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#150 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#156 $ * * $FreeBSD$ */ @@ -171,8 +171,8 @@ static void ahd_reinitialize_dataptrs(struct ahd_softc *ahd); static void ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - cam_status status, char *message, - int verbose_level); + u_int lun, cam_status status, + char *message, int verbose_level); #if AHD_TARGET_MODE static void ahd_setup_target_msgin(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, @@ -438,11 +438,27 @@ scbid = next_scbid; } ahd_outw(ahd, COMPLETE_SCB_HEAD, SCB_LIST_NULL); + ahd_set_scbptr(ahd, saved_scbptr); + + /* + * Flush the good status FIFO for compelted packetized commands. + */ + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + while ((ahd_inb(ahd, LQISTAT2) & LQIGSAVAIL) != 0) { + scbid = (ahd_inb(ahd, GSFIFO+1) << 8) + | ahd_inb(ahd, GSFIFO); + scb = ahd_lookup_scb(ahd, scbid); + if (scb == NULL) { + printf("%s: Warning - GSFIFO SCB %d invalid\n", + ahd_name(ahd), scbid); + continue; + } + ahd_complete_scb(ahd, scb); + } /* * Restore state. */ - ahd_set_scbptr(ahd, saved_scbptr); ahd_restore_modes(ahd, saved_modes); ahd->flags |= AHD_UPDATE_PEND_CMDS; } @@ -672,8 +688,7 @@ &tstate); tinfo = &targ_info->curr; ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, - AHD_TRANS_ACTIVE|AHD_TRANS_GOAL, - /*paused*/TRUE); + AHD_TRANS_ACTIVE, /*paused*/TRUE); ahd_set_syncrate(ahd, &devinfo, /*period*/0, /*offset*/0, /*ppr_options*/0, AHD_TRANS_ACTIVE, /*paused*/TRUE); @@ -988,6 +1003,96 @@ ahd_inb(ahd, SCB_CONTROL) & ~MK_MESSAGE); break; } + case TASKMGMT_FUNC_COMPLETE: + { + u_int scbid; + struct scb *scb; + + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL) { + u_int lun; + u_int tag; + cam_status error; + + ahd_print_path(ahd, scb); + printf("Task Management Func 0x%x Complete\n", + scb->hscb->task_management); + lun = CAM_LUN_WILDCARD; + tag = SCB_LIST_NULL; + + switch (scb->hscb->task_management) { + case SIU_TASKMGMT_ABORT_TASK: + tag = scb->hscb->tag; + case SIU_TASKMGMT_ABORT_TASK_SET: + case SIU_TASKMGMT_CLEAR_TASK_SET: + lun = scb->hscb->lun; + error = CAM_REQ_ABORTED; + ahd_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb), + 'A', lun, tag, ROLE_INITIATOR, + error); + break; + case SIU_TASKMGMT_LUN_RESET: + lun = scb->hscb->lun; + case SIU_TASKMGMT_TARGET_RESET: + { + struct ahd_devinfo devinfo; + + ahd_scb_devinfo(ahd, &devinfo, scb); + error = CAM_BDR_SENT; + ahd_handle_devreset(ahd, &devinfo, lun, + CAM_BDR_SENT, + lun != CAM_LUN_WILDCARD + ? "Lun Reset" + : "Target Reset", + /*verbose_level*/0); + break; + } + default: + panic("Unexpected TaskMgmt Func\n"); + break; + } + } + break; + } + case TASKMGMT_CMD_CMPLT_OKAY: + { + u_int scbid; + struct scb *scb; + + /* + * An ABORT TASK TMF failed to be delivered before + * the targeted command completed normally. + */ + scbid = ahd_get_scbptr(ahd); + scb = ahd_lookup_scb(ahd, scbid); + if (scb != NULL) { + /* + * Remove the second instance of this SCB from + * the QINFIFO if it is still there. + */ + ahd_print_path(ahd, scb); + printf("SCB completes before TMF\n"); + /* + * Handle losing the race. Wait until any + * current selection completes. We will then + * set the TMF back to zero in this SCB so that + * the sequencer doesn't bother to issue another + * sequencer interrupt for its completion. + */ + while ((ahd_inb(ahd, SCSISEQ0) & ENSELO) != 0 + && (ahd_inb(ahd, SSTAT0) & SELDO) == 0 + && (ahd_inb(ahd, SSTAT1) & SELTO) == 0) + ; + ahd_outb(ahd, SCB_TASK_MANAGEMENT, 0); + ahd_search_qinfifo(ahd, SCB_GET_TARGET(ahd, scb), + SCB_GET_CHANNEL(ahd, scb), + SCB_GET_LUN(scb), scb->hscb->tag, + ROLE_INITIATOR, /*status*/0, + SEARCH_REMOVE); + } + break; + } case TRACEPOINT0: case TRACEPOINT1: case TRACEPOINT2: @@ -1711,8 +1816,8 @@ ROLE_INITIATOR)) ahd_set_transaction_status(scb, CAM_REQ_CMP); #endif - ahd_handle_devreset(ahd, &devinfo, CAM_BDR_SENT, - "Bus Device Reset", + ahd_handle_devreset(ahd, &devinfo, CAM_LUN_WILDCARD, + CAM_BDR_SENT, "Bus Device Reset", /*verbose_level*/0); printerror = 0; } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_PPR, FALSE) @@ -2410,8 +2515,9 @@ * occurs the need to renegotiate is * recorded persistently. */ + if ((ahd->features & AHD_WIDE) != 0) + tinfo->curr.width = AHD_WIDTH_UNKNOWN; tinfo->curr.period = AHD_PERIOD_UNKNOWN; - tinfo->curr.width = AHD_WIDTH_UNKNOWN; tinfo->curr.offset = AHD_OFFSET_UNKNOWN; } if (tinfo->curr.period != tinfo->goal.period @@ -3618,8 +3724,8 @@ if (type == AHDMSG_1B && ahd->msgout_index > index && (ahd->msgout_buf[index] == msgval - || ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0)) - && msgval == MSG_IDENTIFYFLAG) + || ((ahd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0 + && msgval == MSG_IDENTIFYFLAG))) found = TRUE; index++; } @@ -3965,7 +4071,7 @@ } #ifdef AHD_TARGET_MODE case MSG_BUS_DEV_RESET: - ahd_handle_devreset(ahd, devinfo, + ahd_handle_devreset(ahd, devinfo, CAM_LUN_WILDCARD, CAM_BDR_SENT, "Bus Device Reset Received", /*verbose_level*/0); @@ -4121,7 +4227,7 @@ * but rejected our response, we already cleared the * sync rate before sending our WDTR. */ - if (tinfo->goal.period) { + if (tinfo->goal.offset != tinfo->curr.offset) { /* Start the sync negotiation */ ahd->msgout_index = 0; @@ -4464,16 +4570,16 @@ */ static void ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, - cam_status status, char *message, int verbose_level) + u_int lun, cam_status status, char *message, + int verbose_level) { #ifdef AHD_TARGET_MODE struct ahd_tmode_tstate* tstate; - u_int lun; #endif int found; found = ahd_abort_scbs(ahd, devinfo->target, devinfo->channel, - CAM_LUN_WILDCARD, SCB_LIST_NULL, devinfo->role, + lun, SCB_LIST_NULL, devinfo->role, status); #ifdef AHD_TARGET_MODE @@ -4483,10 +4589,20 @@ */ tstate = ahd->enabled_targets[devinfo->our_scsiid]; if (tstate != NULL) { - for (lun = 0; lun < AHD_NUM_LUNS; lun++) { + u_int cur_lun; + u_int max_lun; + + if (lun != CAM_LUN_WILDCARD) { + cur_lun = 0; + max_lun = AHD_NUM_LUNS - 1; + } else { + cur_lun = lun; + max_lun = lun; + } + for (cur_lun <= max_lun; cur_lun++) { struct ahd_tmode_lstate* lstate; - lstate = tstate->enabled_luns[lun]; + lstate = tstate->enabled_luns[cur_lun]; if (lstate == NULL) continue; @@ -4506,7 +4622,7 @@ /*ppr_options*/0, AHD_TRANS_CUR, /*paused*/TRUE); ahd_send_async(ahd, devinfo->channel, devinfo->target, - CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); + lun, AC_SENT_BDR, NULL); if (message != NULL && (verbose_level <= bootverbose)) @@ -8129,8 +8245,11 @@ } ahd_outb(ahd, SEQCTL0, PERRORDIS|FAILDIS|FASTMODE); - if (bootverbose) + if (bootverbose) { printf(" %d instructions downloaded\n", downloaded); + printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n", + ahd_name(ahd), ahd->features, ahd->bugs, ahd->flags); + } } static int diff -Nru a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h --- a/drivers/scsi/aic7xxx/aic79xx_inline.h Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_inline.h Sun Feb 9 21:13:32 2003 @@ -2,7 +2,7 @@ * Inline routines shareable across OS platforms. * * Copyright (c) 1994-2001 Justin T. Gibbs. - * Copyright (c) 2000-2002 Adaptec Inc. + * Copyright (c) 2000-2003 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,7 +37,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#40 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#41 $ * * $FreeBSD$ */ @@ -272,7 +272,6 @@ if ((scb->flags & SCB_PACKETIZED) != 0) { /* XXX what about ACA?? It is type 4, but TAG_TYPE == 0x3. */ scb->hscb->task_attribute= scb->hscb->control & SCB_TAG_TYPE; - scb->hscb->task_management = 0; /* * For Rev A short lun workaround. */ @@ -770,7 +769,7 @@ ahd_setup_scb_common(ahd, scb); /* - * Make sure our data is consistant from the + * Make sure our data is consistent from the * perspective of the adapter. */ ahd_sync_scb(ahd, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c --- a/drivers/scsi/aic7xxx/aic79xx_osm.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c Sun Feb 9 21:13:28 2003 @@ -1,12 +1,12 @@ /* * Adaptec AIC79xx device driver for Linux. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#104 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#115 $ * * -------------------------------------------------------------------------- * Copyright (c) 1994-2000 Justin T. Gibbs. * Copyright (c) 1997-1999 Doug Ledford - * Copyright (c) 2000-2002 Adaptec Inc. + * Copyright (c) 2000-2003 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,12 +42,6 @@ * POSSIBILITY OF SUCH DAMAGES. */ -/* - * This is the only file where module.h should - * embed module global version info. - */ -#define AHD_MODVERSION_FILE - #include "aic79xx_osm.h" #include "aic79xx_inline.h" #include @@ -482,10 +476,7 @@ static void ahd_linux_filter_inquiry(struct ahd_softc *ahd, struct ahd_devinfo *devinfo); static void ahd_linux_dev_timed_unfreeze(u_long arg); -#if NO_YET static void ahd_linux_sem_timeout(u_long arg); -static int ahd_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag); -#endif static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd); static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd); static void ahd_linux_start_dv(struct ahd_softc *ahd); @@ -496,8 +487,6 @@ struct scsi_cmnd *cmd, struct ahd_devinfo *devinfo, struct ahd_linux_target *targ); -static uint32_t aic_error_action(struct scsi_cmnd *cmd, - struct scsi_inquiry_data *inq_data); static void ahd_linux_dv_fill_cmd(struct ahd_softc *ahd, struct scsi_cmnd *cmd, struct ahd_devinfo *devinfo); @@ -806,6 +795,10 @@ return (consumed); } +/******************************** Macros **************************************/ +#define BUILD_SCSIID(ahd, cmd) \ + ((((cmd)->device->id << TID_SHIFT) & TID) | (ahd)->our_id) + /************************ Host template entry points *************************/ static int ahd_linux_detect(Scsi_Host_Template *); static int ahd_linux_release(struct Scsi_Host *); @@ -971,7 +964,7 @@ struct ahd_linux_device *dev; u_long flags; - ahd = *(struct ahd_softc **)cmd->host->hostdata; + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; /* * Save the callback on completion function. @@ -995,8 +988,9 @@ ahd_midlayer_entrypoint_unlock(ahd, &flags); return (0); } - dev = ahd_linux_get_device(ahd, cmd->channel, cmd->target, - cmd->lun, /*alloc*/TRUE); + dev = ahd_linux_get_device(ahd, cmd->device->channel, + cmd->device->id, cmd->device->lun, + /*alloc*/TRUE); if (dev == NULL) { ahd_midlayer_entrypoint_unlock(ahd, &flags); printf("aic79xx_linux_queue: Unable to allocate device!\n"); @@ -1211,31 +1205,303 @@ ahd_linux_abort(Scsi_Cmnd *cmd) { struct ahd_softc *ahd; - u_long s; -#if NOTYET struct ahd_cmd *acmd; - int found; -#endif + struct ahd_cmd *list_acmd; + struct ahd_linux_device *dev; + struct scb *pending_scb; + u_long s; + u_int saved_scbptr; + u_int active_scbptr; + u_int last_phase; + int retval; + int paused; + int wait; + int disconnected; + ahd_mode_state saved_modes; - ahd = *(struct ahd_softc **)cmd->host->hostdata; -#if NOTYET - int error; - - error = ahd_linux_queue_recovery_cmd(cmd, SCB_ABORT); - if (error != 0) - printf("aic79xx_abort returns 0x%x\n", error); - return (error); -#else + pending_scb = NULL; + paused = FALSE; + wait = FALSE; + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; + acmd = (struct ahd_cmd *)cmd; + + printf("%s:%d:%d:%d: Attempting to abort cmd %p\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun, cmd); + + /* + * In all versions of Linux, we have to work around + * a major flaw in how the mid-layer is locked down + * if we are to sleep successfully in our error handler + * while allowing our interrupt handler to run. Since + * the midlayer acquires either the io_request_lock or + * our lock prior to calling us, we must use the + * spin_unlock_irq() method for unlocking our lock. + * This will force interrupts to be enabled on the + * current CPU. Since the EH thread should not have + * been running with CPU interrupts disabled other than + * by acquiring either the io_request_lock or our own + * lock, this *should* be safe. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_unlock_irq(&io_request_lock); +#endif ahd_midlayer_entrypoint_lock(ahd, &s); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { - printf("%s: Abort called for cmd %p\n", ahd_name(ahd), cmd); - ahd_dump_card_state(ahd); + + /* + * First determine if we currently own this command. + * Start by searching the device queue. If not found + * there, check the pending_scb list. If not found + * at all, and the system wanted us to just abort the + * command return success. + */ + dev = ahd_linux_get_device(ahd, cmd->device->channel, + cmd->device->id, cmd->device->lun, + /*alloc*/FALSE); + + if (dev == NULL) { + /* + * No target device for this command exists, + * so we must not still own the command. + */ + printf("%s:%d:%d:%d: Is not an active device\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + retval = SUCCESS; + goto no_cmd; + } + + TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) { + if (list_acmd == acmd) + break; + } + + if (list_acmd != NULL) { + printf("%s:%d:%d:%d: Command found on device queue\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); + cmd->result = DID_ABORT << 16; + ahd_linux_queue_cmd_complete(ahd, cmd); + retval = SUCCESS; + goto done; + } + + /* + * See if we can find a matching cmd in the pending list. + */ + LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { + if (pending_scb->io_ctx == cmd) + break; + } + + if (pending_scb == NULL) { + printf("%s:%d:%d:%d: Command not found\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + goto no_cmd; + } + + if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) { + /* + * We can't queue two recovery actions using the same SCB + */ + retval = FAILED; + goto done; + } + + /* + * Ensure that the card doesn't do anything + * behind our back. Also make sure that we + * didn't "just" miss an interrupt that would + * affect this cmd. + */ + ahd_pause_and_flushwork(ahd); + paused = TRUE; + + if ((pending_scb->flags & SCB_ACTIVE) == 0) { + printf("%s:%d:%d:%d: Command already completed\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + goto no_cmd; + } + + ahd_dump_card_state(ahd); + + disconnected = TRUE; + if (ahd_search_qinfifo(ahd, cmd->device->id, cmd->device->channel + 'A', + cmd->device->lun, pending_scb->hscb->tag, + ROLE_INITIATOR, CAM_REQ_ABORTED, + SEARCH_COMPLETE) > 0) { + printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun); + retval = SUCCESS; + goto done; + } + + saved_modes = ahd_save_modes(ahd); + ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI); + last_phase = ahd_inb(ahd, LASTPHASE); + saved_scbptr = ahd_get_scbptr(ahd); + active_scbptr = saved_scbptr; + if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) { + struct scb *bus_scb; + + bus_scb = ahd_lookup_scb(ahd, active_scbptr); + if (bus_scb == pending_scb) + disconnected = FALSE; + } + + /* + * At this point, pending_scb is the scb associated with the + * passed in command. That command is currently active on the + * bus or is in the disconnected state. + */ + if (last_phase != P_BUSFREE + && pending_scb->hscb->tag == active_scbptr) { + + /* + * We're active on the bus, so assert ATN + * and hope that the target responds. + */ + pending_scb = ahd_lookup_scb(ahd, active_scbptr); + pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT; + ahd_outb(ahd, MSG_OUT, HOST_MSG); + ahd_outb(ahd, SCSISIGO, last_phase|ATNO); + printf("%s:%d:%d:%d: Device is active, asserting ATN\n", + ahd_name(ahd), cmd->device->channel, + cmd->device->id, cmd->device->lun); + wait = TRUE; + } else if (disconnected) { + + /* + * Actually re-queue this SCB in an attempt + * to select the device before it reconnects. + */ + pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT; + ahd_set_scbptr(ahd, pending_scb->hscb->tag); + pending_scb->hscb->cdb_len = 0; + pending_scb->hscb->task_attribute = 0; + pending_scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK; + + if ((pending_scb->flags & SCB_PACKETIZED) != 0) { + /* + * Mark the SCB has having an outstanding + * task management function. Should the command + * complete normally before the task management + * function can be sent, the host will be notified + * to abort our requeued SCB. + */ + ahd_outb(ahd, SCB_TASK_MANAGEMENT, + pending_scb->hscb->task_management); + } else { + /* + * If non-packetized, set the MK_MESSAGE control + * bit indicating that we desire to send a message. + * We also set the disconnected flag since there is + * no guarantee that our SCB control byte matches + * the version on the card. We don't want the + * sequencer to abort the command thinking an + * unsolicited reselection occurred. + */ + pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED; + + /* + * The sequencer will never re-reference the + * in-core SCB. To make sure we are notified + * during reslection, set the MK_MESSAGE flag in + * the card's copy of the SCB. + */ + ahd_outb(ahd, SCB_CONTROL, + ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE); + } + + /* + * Clear out any entries in the QINFIFO first + * so we are the next SCB for this target + * to run. + */ + ahd_search_qinfifo(ahd, cmd->device->id, + cmd->device->channel + 'A', cmd->device->lun, + SCB_LIST_NULL, ROLE_INITIATOR, + CAM_REQUEUE_REQ, SEARCH_COMPLETE); + ahd_qinfifo_requeue_tail(ahd, pending_scb); + ahd_set_scbptr(ahd, saved_scbptr); + ahd_print_path(ahd, pending_scb); + printf("Device is disconnected, re-queuing SCB\n"); + wait = TRUE; + } else { + printf("%s:%d:%d:%d: Unable to deliver message\n", + ahd_name(ahd), cmd->device->channel, + cmd->device->id, cmd->device->lun); + retval = FAILED; + goto done; } + +no_cmd: + /* + * Our assumption is that if we don't have the command, no + * recovery action was required, so we return success. Again, + * the semantics of the mid-layer recovery engine are not + * well defined, so this may change in time. + */ + retval = SUCCESS; +done: + if (paused) + ahd_unpause(ahd); + if (wait) { + struct timer_list timer; + int ret; + + ahd->platform_data->flags |= AHD_UP_EH_SEMAPHORE; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &s); +#else + spin_unlock_irq(ahd->platform_data->host->host_lock); +#endif + init_timer(&timer); + timer.data = (u_long)ahd; + timer.expires = jiffies + (5 * HZ); + timer.function = ahd_linux_sem_timeout; + add_timer(&timer); + printf("Recovery code sleeping\n"); + down(&ahd->platform_data->eh_sem); + printf("Recovery code awake\n"); + ret = del_timer(&timer); + if (ret == 0) { + printf("Timer Expired\n"); + retval = FAILED; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_lock(ahd, &s); +#else + spin_lock_irq(ahd->platform_data->host->host_lock); #endif + } + acmd = TAILQ_FIRST(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->completeq); ahd_midlayer_entrypoint_unlock(ahd, &s); - return (FAILED); + if (acmd != NULL) { + acmd = ahd_linux_run_complete_queue(ahd, acmd); + if (acmd != NULL) { + ahd_midlayer_entrypoint_lock(ahd, &s); + ahd_schedule_completeq(ahd, acmd); + ahd_midlayer_entrypoint_unlock(ahd, &s); + } + } + ahd_schedule_runq(ahd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); #endif + return (retval); +} + + +static void +ahd_linux_dev_reset_complete(Scsi_Cmnd *cmd) +{ + free(cmd, M_DEVBUF); } /* @@ -1244,29 +1510,112 @@ static int ahd_linux_dev_reset(Scsi_Cmnd *cmd) { - struct ahd_softc *ahd; -#if NOTYET - struct ahd_cmd *acmd; - u_long s; - int found; -#endif + struct ahd_softc *ahd; + struct scsi_cmnd *recovery_cmd; + struct ahd_linux_device *dev; + struct ahd_initiator_tinfo *tinfo; + struct ahd_tmode_tstate *tstate; + struct scb *scb; + struct hardware_scb *hscb; + struct ahd_cmd *acmd; + u_long s; + struct timer_list timer; + int retval; - ahd = *(struct ahd_softc **)cmd->host->hostdata; -#ifdef AHD_DEBUG +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_unlock_irq(&io_request_lock); +#endif + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; + recovery_cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK); + memset(recovery_cmd, 0, sizeof(struct scsi_cmnd)); + recovery_cmd->device = cmd->device; + recovery_cmd->scsi_done = ahd_linux_dev_reset_complete; +#if AHD_DEBUG if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) - printf("%s: Dev reset called for cmd %p\n", - ahd_name(ahd), cmd); + printf("%s:%d:%d:%d: Device reset called for cmd %p\n", + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->device->lun, cmd); #endif -#if NOTYET - int error; + ahd_midlayer_entrypoint_lock(ahd, &s); - error = ahd_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); - if (error != 0) - printf("aic79xx_dev_reset returns 0x%x\n", error); - return (error); + dev = ahd_linux_get_device(ahd, cmd->device->channel, cmd->device->id, + cmd->device->lun, /*alloc*/FALSE); + if (dev == NULL) { + ahd_midlayer_entrypoint_unlock(ahd, &s); + return (FAILED); + } + if ((scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX)) == NULL) { + ahd_midlayer_entrypoint_unlock(ahd, &s); + return (FAILED); + } + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, + cmd->device->id, &tstate); + recovery_cmd->result = CAM_REQ_INPROG << 16; + recovery_cmd->host_scribble = (char *)scb; + scb->io_ctx = recovery_cmd; + scb->platform_data->dev = dev; + scb->sg_count = 0; + ahd_set_residual(scb, 0); + ahd_set_sense_residual(scb, 0); + hscb = scb->hscb; + hscb->control = 0; + hscb->scsiid = BUILD_SCSIID(ahd, cmd); + hscb->lun = cmd->lun; + hscb->cdb_len = 0; + hscb->task_management = SIU_TASKMGMT_LUN_RESET; + scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE; + if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { + scb->flags |= SCB_PACKETIZED; + } else { + hscb->control |= MK_MESSAGE; + } + dev->openings--; + dev->active++; + dev->commands_issued++; + LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links); + ahd_queue_scb(ahd, scb); + + ahd->platform_data->flags |= AHD_UP_EH_SEMAPHORE; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_unlock(ahd, &s); #else - return (FAILED); + spin_unlock_irq(ahd->platform_data->host->host_lock); +#endif + init_timer(&timer); + timer.data = (u_long)ahd; + timer.expires = jiffies + (5 * HZ); + timer.function = ahd_linux_sem_timeout; + add_timer(&timer); + printf("Recovery code sleeping\n"); + down(&ahd->platform_data->eh_sem); + printf("Recovery code awake\n"); + retval = SUCCESS; + if (del_timer(&timer) == 0) { + printf("Timer Expired\n"); + retval = FAILED; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + ahd_lock(ahd, &s); +#else + spin_lock_irq(ahd->platform_data->host->host_lock); +#endif + acmd = TAILQ_FIRST(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->completeq); + ahd_midlayer_entrypoint_unlock(ahd, &s); + if (acmd != NULL) { + acmd = ahd_linux_run_complete_queue(ahd, acmd); + if (acmd != NULL) { + ahd_midlayer_entrypoint_lock(ahd, &s); + ahd_schedule_completeq(ahd, acmd); + ahd_midlayer_entrypoint_unlock(ahd, &s); + } + } + ahd_schedule_runq(ahd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); #endif + printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval); + return (retval); } /* @@ -1283,14 +1632,14 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) spin_unlock_irq(&io_request_lock); #endif - ahd = *(struct ahd_softc **)cmd->host->hostdata; + ahd = *(struct ahd_softc **)cmd->device->host->hostdata; #ifdef AHD_DEBUG if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) printf("%s: Bus reset called for cmd %p\n", ahd_name(ahd), cmd); #endif ahd_midlayer_entrypoint_lock(ahd, &s); - found = ahd_reset_channel(ahd, cmd->channel + 'A', + found = ahd_reset_channel(ahd, cmd->device->channel + 'A', /*initiate reset*/TRUE); acmd = TAILQ_FIRST(&ahd->platform_data->completeq); TAILQ_INIT(&ahd->platform_data->completeq); @@ -1413,10 +1762,6 @@ return (NOTIFY_OK); } -/******************************** Macros **************************************/ -#define BUILD_SCSIID(ahd, cmd) \ - ((((cmd)->target << TID_SHIFT) & TID) | (ahd)->our_id) - /******************************** Bus DMA *************************************/ int ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent, @@ -2106,10 +2451,10 @@ static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd) { - int i; - int numtarg; + u_int target_id; + u_int numtarg; - i = 0; + target_id = 0; numtarg = 0; if (aic79xx_no_reset != 0) @@ -2124,21 +2469,15 @@ * Force negotiation to async for all targets that * will not see an initial bus reset. */ - for (; i < numtarg; i++) { + for (; target_id < numtarg; target_id++) { struct ahd_devinfo devinfo; struct ahd_initiator_tinfo *tinfo; struct ahd_tmode_tstate *tstate; - u_int our_id; - u_int target_id; - char channel; - - channel = 'A'; - our_id = ahd->our_id; - target_id = i; - tinfo = ahd_fetch_transinfo(ahd, channel, our_id, + + tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, target_id, &tstate); - ahd_compile_devinfo(&devinfo, our_id, target_id, - CAM_LUN_WILDCARD, channel, ROLE_INITIATOR); + ahd_compile_devinfo(&devinfo, ahd->our_id, target_id, + CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR); ahd_update_neg_request(ahd, &devinfo, tstate, tinfo, AHD_NEG_ALWAYS); } @@ -2192,7 +2531,10 @@ void ahd_platform_free(struct ahd_softc *ahd) { + struct ahd_linux_target *targ; + struct ahd_linux_device *dev; u_long s; + int i, j; if (ahd->platform_data != NULL) { /* Kill the DV kthread */ @@ -2214,6 +2556,23 @@ ahd_teardown_runq_tasklet(ahd); if (ahd->platform_data->host != NULL) scsi_unregister(ahd->platform_data->host); + + /* destroy all of the device and target objects */ + for (i = 0; i < AHD_NUM_TARGETS; i++) { + targ = ahd->platform_data->targets[i]; + if (targ != NULL) { + for (j = 0; j < AHD_NUM_LUNS; j++) { + if (targ->devices[j] != NULL) { + dev = targ->devices[j]; + ahd_linux_free_device(ahd, dev); + } + if (ahd->platform_data->targets[i] == + NULL) + break; + } + } + } + if (ahd->platform_data->irq != AHD_LINUX_NOIRQ) free_irq(ahd->platform_data->irq, ahd); if (ahd->tags[0] == BUS_SPACE_PIO @@ -2593,6 +2952,7 @@ struct ahd_devinfo devinfo; struct ahd_linux_target *targ; struct scsi_cmnd *cmd; + struct scsi_device *scsi_dev; struct scsi_sense_data *sense; uint8_t *buffer; u_long s; @@ -2620,6 +2980,12 @@ ahd_unlock(ahd, &s); cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK); + scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK); + scsi_dev->host = ahd->platform_data->host; + scsi_dev->id = devinfo.target; + scsi_dev->lun = devinfo.lun; + scsi_dev->channel = devinfo.channel - 'A'; + ahd->platform_data->dv_scsi_dev = scsi_dev; AHD_SET_DV_STATE(ahd, targ, AHD_DV_STATE_INQ_SHORT_ASYNC); @@ -2744,6 +3110,11 @@ if (cmd != NULL) free(cmd, M_DEVBUF); + if (ahd->platform_data->dv_scsi_dev != NULL) { + free(ahd->platform_data->dv_scsi_dev, M_DEVBUF); + ahd->platform_data->dv_scsi_dev = NULL; + } + ahd_lock(ahd, &s); if (targ->dv_buffer != NULL) free(targ->dv_buffer, M_DEVBUF); @@ -2760,9 +3131,13 @@ struct ahd_devinfo *devinfo, struct ahd_linux_target *targ) { + cam_status cam_status; u_int32_t status; + u_int scsi_status; - status = aic_error_action(cmd, targ->inq_data); + scsi_status = ahd_cmd_get_scsi_status(cmd); + cam_status = ahd_cmd_get_transaction_status(cmd); + status = aic_error_action(cmd, targ->inq_data, cam_status, scsi_status); #ifdef AHD_DEBUG @@ -2813,6 +3188,7 @@ switch (status & SS_MASK) { case SS_NOP: { + u_int xportflags; u_int spi3data; if (memcmp(targ->inq_data, targ->dv_buffer, @@ -2831,6 +3207,10 @@ if (ahd_linux_user_dv_setting(ahd) == 0) break; + xportflags = targ->inq_data->flags; + if ((xportflags & (SID_Sync|SID_WBus16)) == 0) + break; + spi3data = targ->inq_data->spi3data; switch (spi3data & SID_SPI_CLOCK_DT_ST) { default: @@ -3225,104 +3605,13 @@ } } -static uint32_t -aic_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data) -{ - aic_sense_action err_action; - cam_status status; - u_int scsi_status; - int sense; - - status = ahd_cmd_get_transaction_status(cmd); - scsi_status = ahd_cmd_get_scsi_status(cmd); - sense = (cmd->result >> 24) == DRIVER_SENSE; - - switch (status) { - case CAM_REQ_CMP: - err_action = SS_NOP; - break; - case CAM_AUTOSENSE_FAIL: - case CAM_SCSI_STATUS_ERROR: - - switch (scsi_status) { - case SCSI_STATUS_OK: - case SCSI_STATUS_COND_MET: - case SCSI_STATUS_INTERMED: - case SCSI_STATUS_INTERMED_COND_MET: - err_action = SS_NOP; - break; - case SCSI_STATUS_CMD_TERMINATED: - case SCSI_STATUS_CHECK_COND: - if (sense != 0) { - struct scsi_sense_data *sense; - - sense = (struct scsi_sense_data *) - &cmd->sense_buffer; - err_action = - aic_sense_error_action(sense, inq_data, 0); - - } else { - err_action = SS_RETRY|SSQ_FALLBACK - | SSQ_DECREMENT_COUNT|EIO; - } - break; - case SCSI_STATUS_QUEUE_FULL: - case SCSI_STATUS_BUSY: - err_action = SS_RETRY|SSQ_DELAY|SSQ_MANY - | SSQ_DECREMENT_COUNT|EBUSY; - break; - case SCSI_STATUS_RESERV_CONFLICT: - default: - err_action = SS_FAIL|EBUSY; - break; - } - break; - case CAM_CMD_TIMEOUT: - case CAM_REQ_CMP_ERR: - case CAM_UNEXP_BUSFREE: - case CAM_UNCOR_PARITY: - case CAM_DATA_RUN_ERR: - err_action = SS_RETRY|SSQ_FALLBACK|EIO; - break; - case CAM_UA_ABORT: - case CAM_UA_TERMIO: - case CAM_MSG_REJECT_REC: - case CAM_SEL_TIMEOUT: - err_action = SS_FAIL|EIO; - break; - case CAM_REQ_INVALID: - case CAM_PATH_INVALID: - case CAM_DEV_NOT_THERE: - case CAM_NO_HBA: - case CAM_PROVIDE_FAIL: - case CAM_REQ_TOO_BIG: - case CAM_RESRC_UNAVAIL: - case CAM_BUSY: - default: - /* panic?? These should never occur in our application. */ - err_action = SS_FAIL|EIO; - break; - case CAM_SCSI_BUS_RESET: - case CAM_BDR_SENT: - case CAM_REQUEUE_REQ: - /* Unconditional requeue */ - err_action = SS_RETRY; - break; - } - - return (err_action); -} - static void ahd_linux_dv_fill_cmd(struct ahd_softc *ahd, struct scsi_cmnd *cmd, struct ahd_devinfo *devinfo) { memset(cmd, 0, sizeof(struct scsi_cmnd)); - cmd->host = ahd->platform_data->host; + cmd->device = ahd->platform_data->dv_scsi_dev; cmd->scsi_done = ahd_linux_dv_complete; - cmd->target = devinfo->target; - cmd->lun = devinfo->lun; - cmd->channel = devinfo->channel - 'A'; } /* @@ -3475,23 +3764,6 @@ cmd->cmnd[4] = le | SSS_START; } -/* - * Return speed in KB/s. - */ -static u_int -ahd_linux_calc_speed(u_int width, u_int period, u_int offset) -{ - u_int freq; - - if (offset != 0 && period < AHD_SYNCRATE_MIN) - freq = aic_calc_syncsrate(period); - else - /* Roughly 3.3MB/s for async */ - freq = 3300; - freq <<= width; - return (freq); -} - static __inline int ahd_linux_dv_fallback(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) { @@ -3549,14 +3821,15 @@ if (targ->dv_last_ppr_options == 0) targ->dv_last_ppr_options = ppr_options; - cur_speed = ahd_linux_calc_speed(width, period, offset); - wide_speed = ahd_linux_calc_speed(MSG_EXT_WDTR_BUS_16_BIT, + cur_speed = aic_calc_speed(width, period, offset, AHD_SYNCRATE_MIN); + wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT, targ->dv_next_wide_period, - MAX_OFFSET); - narrow_speed = ahd_linux_calc_speed(MSG_EXT_WDTR_BUS_8_BIT, + MAX_OFFSET, AHD_SYNCRATE_MIN); + narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT, targ->dv_next_narrow_period, - MAX_OFFSET); - fallback_speed = ahd_linux_calc_speed(width, period+1, offset); + MAX_OFFSET, AHD_SYNCRATE_MIN); + fallback_speed = aic_calc_speed(width, period+1, offset, + AHD_SYNCRATE_MIN); #ifdef AHD_DEBUG if (ahd_debug & AHD_SHOW_DV) { printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, " @@ -3687,13 +3960,15 @@ struct scb *scb; u_long flags; - ahd = *((struct ahd_softc **)cmd->host->hostdata); + ahd = *((struct ahd_softc **)cmd->device->host->hostdata); ahd_lock(ahd, &flags); #ifdef AHD_DEBUG - if (ahd_debug & AHD_SHOW_DV) + if (ahd_debug & AHD_SHOW_DV) { printf("%s: Timeout while doing DV command %x.\n", ahd_name(ahd), cmd->cmnd[0]); + ahd_dump_card_state(ahd); + } #endif /* @@ -3715,7 +3990,7 @@ ahd_set_transaction_status(scb, CAM_AUTOSENSE_FAIL); else ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); - ahd_reset_channel(ahd, cmd->channel + 'A', /*initiate*/TRUE); + ahd_reset_channel(ahd, cmd->device->channel + 'A', /*initiate*/TRUE); /* * Add a minimal bus settle delay for devices that are slow to @@ -3765,7 +4040,7 @@ { struct ahd_softc *ahd; - ahd = *((struct ahd_softc **)cmd->host->hostdata); + ahd = *((struct ahd_softc **)cmd->device->host->hostdata); /* Delete the DV timer before it goes off! */ scsi_delete_timer(cmd); @@ -3773,7 +4048,8 @@ #ifdef AHD_DEBUG if (ahd_debug & AHD_SHOW_DV) printf("%s:%c:%d: Command completed, status= 0x%x\n", - ahd_name(ahd), cmd->channel, cmd->target, cmd->result); + ahd_name(ahd), cmd->device->channel, cmd->device->id, + cmd->result); #endif /* Wake up the state machine */ @@ -3967,12 +4243,13 @@ * Get an scb to use. */ tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id, - cmd->target, &tstate); + cmd->device->id, &tstate); if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0 || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) { col_idx = AHD_NEVER_COL_IDX; } else { - col_idx = AHD_BUILD_COL_IDX(cmd->target, cmd->lun); + col_idx = AHD_BUILD_COL_IDX(cmd->device->id, + cmd->device->lun); } if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, @@ -3992,7 +4269,7 @@ */ hscb->control = 0; hscb->scsiid = BUILD_SCSIID(ahd, cmd); - hscb->lun = cmd->lun; + scb->hscb->task_management = 0; mask = SCB_GET_TARGET_MASK(ahd, scb); if ((ahd->user_discenable & mask) != 0) @@ -4328,7 +4605,34 @@ break; } case AC_SENT_BDR: + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + Scsi_Device *scsi_dev; + + /* + * Find the SCSI device associated with this + * request and indicate that a UA is expected. + * XXX This should really be handled by the mid-layer. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + list_for_each_entry(scsi_dev, + &ahd->platform_data->host->my_devices, + siblings) { +#else + for (scsi_dev = ahd->platform_data->host->host_queue; + scsi_dev != NULL; scsi_dev = scsi_dev->next) { +#endif + if (channel - 'A' == scsi_dev->channel + && target == scsi_dev->id + && (lun == CAM_LUN_WILDCARD + || lun == scsi_dev->lun)) { + scsi_dev->was_reset = 1; + scsi_dev->expecting_cc_ua = 1; + } + } +#endif break; + } case AC_BUS_RESET: #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) if (ahd->platform_data->host != NULL) { @@ -4346,7 +4650,7 @@ * Calls the higher level scsi done function and frees the scb. */ void -ahd_done(struct ahd_softc *ahd, struct scb * scb) +ahd_done(struct ahd_softc *ahd, struct scb *scb) { Scsi_Cmnd *cmd; struct ahd_linux_device *dev; @@ -4445,8 +4749,8 @@ if (ahd_get_transaction_status(scb) == CAM_BDR_SENT || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED) ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT); - if ((scb->platform_data->flags & AHD_UP_EH_SEMAPHORE) != 0) { - scb->platform_data->flags &= ~AHD_UP_EH_SEMAPHORE; + if ((ahd->platform_data->flags & AHD_UP_EH_SEMAPHORE) != 0) { + ahd->platform_data->flags &= ~AHD_UP_EH_SEMAPHORE; up(&ahd->platform_data->eh_sem); } } @@ -4459,7 +4763,6 @@ ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_EMPTY; up(&ahd->platform_data->dv_sem); } - } static void @@ -4531,8 +4834,11 @@ printf("Copied %d bytes of sense data at %d:", sense_size, sense_offset); - for (i = 0; i < sense_size; i++) - printf(" 0x%x", cmd->sense_buffer[i]); + for (i = 0; i < sense_size; i++) { + if ((i & 0xF) == 0) + printf("\n"); + printf("0x%x ", cmd->sense_buffer[i]); + } printf("\n"); } #endif @@ -4658,10 +4964,13 @@ if (status != CAM_REQ_CMP) { struct ahd_linux_device *dev; struct ahd_devinfo devinfo; + cam_status cam_status; uint32_t action; + u_int scsi_status; - dev = ahd_linux_get_device(ahd, cmd->channel, - cmd->target, cmd->lun, + dev = ahd_linux_get_device(ahd, cmd->device->channel, + cmd->device->id, + cmd->device->lun, /*alloc*/FALSE); if (dev == NULL) @@ -4672,8 +4981,11 @@ dev->target->target, dev->lun, dev->target->channel == 0 ? 'A':'B', ROLE_INITIATOR); - - action = aic_error_action(cmd, dev->target->inq_data); + + scsi_status = ahd_cmd_get_scsi_status(cmd); + cam_status = ahd_cmd_get_transaction_status(cmd); + action = aic_error_action(cmd, dev->target->inq_data, + cam_status, scsi_status); if ((action & SSQ_FALLBACK) != 0) { /* Update stats */ @@ -4741,7 +5053,8 @@ * evoke a retry even if this command is being sent * via the eh thread. Ick! Ick! Ick! */ - cmd->retries--; + if (cmd->retries > 0) + cmd->retries--; new_status = DID_OK; ahd_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND); cmd->result |= (DRIVER_SENSE << 24); @@ -4936,7 +5249,6 @@ ahd_schedule_runq(ahd); } -#if NOT_YET static void ahd_linux_sem_timeout(u_long arg) { @@ -4951,305 +5263,6 @@ } ahd_unlock(ahd, &s); } - -static int -ahd_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) -{ - struct ahd_softc *ahd; - struct ahd_cmd *acmd; - struct ahd_cmd *list_acmd; - struct ahd_linux_device *dev; - struct scb *pending_scb; - u_long s; - u_int saved_scbptr; - u_int active_scb_index; - u_int last_phase; - int retval; - int paused; - int wait; - int disconnected; - - pending_scb = NULL; - paused = FALSE; - wait = FALSE; - ahd = *(struct ahd_softc **)cmd->host->hostdata; - acmd = (struct ahd_cmd *)cmd; - - printf("%s:%d:%d:%d: Attempting to queue a%s message\n", - ahd_name(ahd), cmd->channel, cmd->target, cmd->lun, - flag == SCB_ABORT ? "n ABORT" : " TARGET RESET"); - - /* - * In all versions of Linux, we have to work around - * a major flaw in how the mid-layer is locked down - * if we are to sleep successfully in our error handler - * while allowing our interrupt handler to run. Since - * the midlayer acquires either the io_request_lock or - * our lock prior to calling us, we must use the - * spin_unlock_irq() method for unlocking our lock. - * This will force interrupts to be enabled on the - * current CPU. Since the EH thread should not have - * been running with CPU interrupts disabled other than - * by acquiring either the io_request_lock or our own - * lock, this *should* be safe. - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_unlock_irq(&io_request_lock); -#endif - ahd_midlayer_entrypoint_lock(ahd, &s); - - /* - * First determine if we currently own this command. - * Start by searching the device queue. If not found - * there, check the pending_scb list. If not found - * at all, and the system wanted us to just abort the - * command return success. - */ - dev = ahd_linux_get_device(ahd, cmd->channel, cmd->target, - cmd->lun, /*alloc*/FALSE); - - if (dev == NULL) { - /* - * No target device for this command exists, - * so we must not still own the command. - */ - printf("%s:%d:%d:%d: Is not an active device\n", - ahd_name(ahd), cmd->channel, cmd->target, cmd->lun); - retval = SUCCESS; - goto no_cmd; - } - - TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) { - if (list_acmd == acmd) - break; - } - - if (list_acmd != NULL) { - printf("%s:%d:%d:%d: Command found on device queue\n", - ahd_name(ahd), cmd->channel, cmd->target, cmd->lun); - if (flag == SCB_ABORT) { - TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); - cmd->result = DID_ABORT << 16; - ahd_linux_queue_cmd_complete(ahd, cmd); - retval = SUCCESS; - goto done; - } - } - - /* - * See if we can find a matching cmd in the pending list. - */ - LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { - if (pending_scb->io_ctx == cmd) - break; - } - - if (pending_scb == NULL && flag == SCB_DEVICE_RESET) { - - /* Any SCB for this device will do for a target reset */ - LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) { - if (ahd_match_scb(ahd, pending_scb, cmd->target, - cmd->channel, CAM_LUN_WILDCARD, - SCB_LIST_NULL, ROLE_INITIATOR) == 0) - break; - } - } - - if (pending_scb == NULL) { - printf("%s:%d:%d:%d: Command not found\n", - ahd_name(ahd), cmd->channel, cmd->target, cmd->lun); - goto no_cmd; - } - - if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) { - /* - * We can't queue two recovery actions using the same SCB - */ - retval = FAILED; - goto done; - } - - /* - * Ensure that the card doesn't do anything - * behind our back. Also make sure that we - * didn't "just" miss an interrupt that would - * affect this cmd. - */ - ahd->flags |= AHD_ALL_INTERRUPTS; - do { - ahd_intr(ahd); - ahd_pause(ahd); - ahd_clear_critical_section(ahd); - } while (ahd_inb(ahd, INTSTAT) & INT_PEND); - ahd->flags &= ~AHD_ALL_INTERRUPTS; - paused = TRUE; - - ahd_dump_card_state(ahd); - - if ((pending_scb->flags & SCB_ACTIVE) == 0) { - printf("%s:%d:%d:%d: Command already completed\n", - ahd_name(ahd), cmd->channel, cmd->target, cmd->lun); - goto no_cmd; - } - - disconnected = TRUE; - if (flag == SCB_ABORT) { - if (ahd_search_qinfifo(ahd, cmd->target, cmd->channel + 'A', - cmd->lun, pending_scb->hscb->tag, - ROLE_INITIATOR, CAM_REQ_ABORTED, - SEARCH_COMPLETE) > 0) { - printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", - ahd_name(ahd), cmd->channel, cmd->target, - cmd->lun); - retval = SUCCESS; - goto done; - } - } else if (ahd_search_qinfifo(ahd, cmd->target, cmd->channel + 'A', - cmd->lun, pending_scb->hscb->tag, - ROLE_INITIATOR, /*status*/0, - SEARCH_COUNT) > 0) { - disconnected = FALSE; - } - - /* - * At this point, pending_scb is the scb associated with the - * passed in command. That command is currently active on the - * bus, is in the disconnected state, or we're hoping to find - * a command for the same target active on the bus to abuse to - * send a BDR. Queue the appropriate message based on which of - * these states we are in. - */ - last_phase = ahd_inb(ahd, LASTPHASE); - saved_scbptr = ahd_inb(ahd, SCBPTR); - active_scb_index = ahd_inb(ahd, SCB_TAG); - if (last_phase != P_BUSFREE - && (pending_scb->hscb->tag == active_scb_index - || (flag == SCB_DEVICE_RESET - && SCSIID_TARGET(ahd, ahd_inb(ahd, SAVED_SCSIID)) == cmd->target))) { - - /* - * We're active on the bus, so assert ATN - * and hope that the target responds. - */ - pending_scb = ahd_lookup_scb(ahd, active_scb_index); - pending_scb->flags |= SCB_RECOVERY_SCB|flag; - ahd_outb(ahd, MSG_OUT, HOST_MSG); - ahd_outb(ahd, SCSISIGO, last_phase|ATNO); - printf("%s:%d:%d:%d: Device is active, asserting ATN\n", - ahd_name(ahd), cmd->channel, cmd->target, cmd->lun); - wait = TRUE; - } else if (disconnected) { - - /* - * Actually re-queue this SCB in an attempt - * to select the device before it reconnects. - * In either case (selection or reselection), - * we will now issue the approprate message - * to the timed-out device. - * - * Set the MK_MESSAGE control bit indicating - * that we desire to send a message. We - * also set the disconnected flag since - * in the paging case there is no guarantee - * that our SCB control byte matches the - * version on the card. We don't want the - * sequencer to abort the command thinking - * an unsolicited reselection occurred. - */ - pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED; - pending_scb->flags |= SCB_RECOVERY_SCB|flag; - - /* - * In the non-paging case, the sequencer will - * never re-reference the in-core SCB. - * To make sure we are notified during - * reslection, set the MK_MESSAGE flag in - * the card's copy of the SCB. - */ - ahd_outb(ahd, SCBPTR, pending_scb->hscb->tag); - ahd_outb(ahd, SCB_CONTROL, - ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE); - - /* - * Clear out any entries in the QINFIFO first - * so we are the next SCB for this target - * to run. - */ - ahd_search_qinfifo(ahd, cmd->target, cmd->channel + 'A', - cmd->lun, SCB_LIST_NULL, ROLE_INITIATOR, - CAM_REQUEUE_REQ, SEARCH_COMPLETE); - ahd_print_path(ahd, pending_scb); - printf("Queuing a recovery SCB\n"); - ahd_qinfifo_requeue_tail(ahd, pending_scb); - ahd_outb(ahd, SCBPTR, saved_scbptr); - printf("%s:%d:%d:%d: Device is disconnected, re-queuing SCB\n", - ahd_name(ahd), cmd->channel, cmd->target, cmd->lun); - wait = TRUE; - } else { - printf("%s:%d:%d:%d: Unable to deliver message\n", - ahd_name(ahd), cmd->channel, cmd->target, cmd->lun); - retval = FAILED; - goto done; - } - -no_cmd: - /* - * Our assumption is that if we don't have the command, no - * recovery action was required, so we return success. Again, - * the semantics of the mid-layer recovery engine are not - * well defined, so this may change in time. - */ - retval = SUCCESS; -done: - if (paused) - ahd_unpause(ahd); - if (wait) { - struct timer_list timer; - int ret; - - pending_scb->platform_data->flags |= AHD_UP_EH_SEMAPHORE; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_unlock(ahd, &s); -#else - spin_unlock_irq(ahd->platform_data->host->host_lock); -#endif - init_timer(&timer); - timer.data = (u_long)ahd; - timer.expires = jiffies + (5 * HZ); - timer.function = ahd_linux_sem_timeout; - add_timer(&timer); - printf("Recovery code sleeping\n"); - down(&ahd->platform_data->eh_sem); - printf("Recovery code awake\n"); - ret = del_timer(&timer); - if (ret == 0) { - printf("Timer Expired\n"); - retval = FAILED; - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ahd_lock(ahd, &s); -#else - spin_lock_irq(ahd->platform_data->host->host_lock); -#endif - } - acmd = TAILQ_FIRST(&ahd->platform_data->completeq); - TAILQ_INIT(&ahd->platform_data->completeq); - ahd_midlayer_entry_unlock(ahd, &s); - if (acmd != NULL) { - acmd = ahd_linux_run_complete_queue(ahd, acmd); - if (acmd != NULL) { - ahd_midlayer_entrypoint_lock(ahd, &s); - ahd_schedule_completeq(ahd, acmd); - ahd_midlayer_entrypoint_unlock(ahd, &s); - } - } - ahd_schedule_runq(ahd); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_lock_irq(&io_request_lock); -#endif - return (retval); -} -#endif static void ahd_linux_dev_timed_unfreeze(u_long arg) diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h --- a/drivers/scsi/aic7xxx/aic79xx_osm.h Sun Feb 9 21:13:33 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h Sun Feb 9 21:13:33 2003 @@ -36,7 +36,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#102 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#108 $ * */ #ifndef _AIC79XX_LINUX_H_ @@ -50,11 +50,9 @@ #include #include #include -#ifndef AHD_MODVERSION_FILE -#define __NO_VERSION__ -#endif #include #include +#include #ifndef KERNEL_VERSION #define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) @@ -72,7 +70,6 @@ #define AIC_LIB_PREFIX ahd #include "scsi.h" #include "hosts.h" -#include "aiclib.h" /* Name space conflict with BSD queue macros */ #ifdef LIST_HEAD @@ -83,6 +80,7 @@ #include "queue.h" #include "scsi_message.h" #include "scsi_iu.h" +#include "aiclib.h" /*********************************** Debugging ********************************/ #ifdef CONFIG_AIC79XX_DEBUG_ENABLE @@ -288,7 +286,7 @@ #include #endif -#define AIC79XX_DRIVER_VERSION "1.3.0.BETA2" +#define AIC79XX_DRIVER_VERSION "1.3.0" /**************************** Front End Queues ********************************/ /* @@ -323,7 +321,7 @@ /* * A per probed device structure used to deal with some error recovery * scenarios that the Linux mid-layer code just doesn't know how to - * handle. The structure allocated for a device only becomes persistant + * handle. The structure allocated for a device only becomes persistent * after a successfully completed inquiry command to the target when * that inquiry data indicates a lun is present. */ @@ -489,7 +487,7 @@ * Per-SCB OSM storage. */ typedef enum { - AHD_UP_EH_SEMAPHORE + AHD_UP_EH_SEMAPHORE = 0x1 } ahd_linux_scb_flags; struct scb_platform_data { @@ -543,6 +541,7 @@ struct semaphore dv_cmd_sem; /* XXX This needs to be in * the target struct */ + struct scsi_device *dv_scsi_dev; struct Scsi_Host *host; /* pointer to scsi host */ #define AHD_LINUX_NOIRQ ((uint32_t)~0) uint32_t irq; /* IRQ for this adapter */ diff -Nru a/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped --- a/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped Sun Feb 9 21:13:37 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_reg.h_shipped Sun Feb 9 21:13:37 2003 @@ -2,8 +2,8 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#77 $ - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#59 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $ */ typedef int (ahd_reg_print_t)(u_int, u_int *, u_int); typedef struct ahd_reg_parse_entry { @@ -2367,11 +2367,13 @@ #define SPLTINT 0x01 #define SEQINTCODE 0x02 -#define SAW_HWERR 0x17 -#define TRACEPOINT3 0x16 -#define TRACEPOINT2 0x15 -#define TRACEPOINT1 0x14 -#define TRACEPOINT0 0x13 +#define SAW_HWERR 0x19 +#define TRACEPOINT3 0x18 +#define TRACEPOINT2 0x17 +#define TRACEPOINT1 0x16 +#define TRACEPOINT0 0x15 +#define TASKMGMT_CMD_CMPLT_OKAY 0x14 +#define TASKMGMT_FUNC_COMPLETE 0x13 #define ENTERING_NONPACK 0x12 #define CFG4OVERRUN 0x11 #define STATUS_OVERRUN 0x10 @@ -3772,5 +3774,5 @@ /* Exported Labels */ -#define LABEL_seq_isr 0x25a -#define LABEL_timer_isr 0x256 +#define LABEL_seq_isr 0x263 +#define LABEL_timer_isr 0x25f diff -Nru a/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped --- a/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_reg_print.c_shipped Sun Feb 9 21:13:28 2003 @@ -2,8 +2,8 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#77 $ - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#59 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $ */ #include "aic79xx_osm.h" @@ -59,17 +59,19 @@ { "STATUS_OVERRUN", 0x10, 0xff }, { "CFG4OVERRUN", 0x11, 0xff }, { "ENTERING_NONPACK", 0x12, 0xff }, - { "TRACEPOINT0", 0x13, 0xff }, - { "TRACEPOINT1", 0x14, 0xff }, - { "TRACEPOINT2", 0x15, 0xff }, - { "TRACEPOINT3", 0x16, 0xff }, - { "SAW_HWERR", 0x17, 0xff } + { "TASKMGMT_FUNC_COMPLETE",0x13, 0xff }, + { "TASKMGMT_CMD_CMPLT_OKAY",0x14, 0xff }, + { "TRACEPOINT0", 0x15, 0xff }, + { "TRACEPOINT1", 0x16, 0xff }, + { "TRACEPOINT2", 0x17, 0xff }, + { "TRACEPOINT3", 0x18, 0xff }, + { "SAW_HWERR", 0x19, 0xff } }; int ahd_seqintcode_print(u_int regvalue, u_int *cur_col, u_int wrap) { - return (ahd_print_register(SEQINTCODE_parse_table, 24, "SEQINTCODE", + return (ahd_print_register(SEQINTCODE_parse_table, 26, "SEQINTCODE", 0x02, regvalue, cur_col, wrap)); } diff -Nru a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped --- a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped Sun Feb 9 21:13:37 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped Sun Feb 9 21:13:37 2003 @@ -2,92 +2,97 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#77 $ - * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#59 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#78 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#60 $ */ static uint8_t seqprog[] = { 0xff, 0x02, 0x06, 0x78, - 0x00, 0xea, 0x3c, 0x59, + 0x00, 0xea, 0x46, 0x59, 0x01, 0xea, 0x04, 0x30, 0xff, 0x04, 0x0c, 0x78, - 0x17, 0xea, 0x3c, 0x59, - 0x17, 0xea, 0x04, 0x00, - 0x33, 0xea, 0x30, 0x59, + 0x19, 0xea, 0x46, 0x59, + 0x19, 0xea, 0x04, 0x00, + 0x33, 0xea, 0x3a, 0x59, 0x33, 0xea, 0x00, 0x00, 0x60, 0x3a, 0x1a, 0x68, 0x04, 0x47, 0x1b, 0x68, 0xff, 0x21, 0x1b, 0x70, - 0x40, 0x4b, 0x7e, 0x69, - 0x00, 0xe2, 0x40, 0x59, - 0x40, 0x4b, 0x7e, 0x69, - 0x20, 0x4b, 0x6e, 0x69, + 0x40, 0x4b, 0x88, 0x69, + 0x00, 0xe2, 0x4a, 0x59, + 0x40, 0x4b, 0x88, 0x69, + 0x20, 0x4b, 0x78, 0x69, 0xfc, 0x42, 0x24, 0x78, 0x10, 0x40, 0x24, 0x78, - 0x00, 0xe2, 0x8c, 0x5d, + 0x00, 0xe2, 0xa4, 0x5d, 0x20, 0x4d, 0x28, 0x78, - 0x00, 0xe2, 0x8c, 0x5d, + 0x00, 0xe2, 0xa4, 0x5d, 0x00, 0xe2, 0x34, 0x58, - 0x00, 0xe2, 0x5c, 0x58, - 0x00, 0xe2, 0x6c, 0x58, + 0x00, 0xe2, 0x66, 0x58, + 0x00, 0xe2, 0x76, 0x58, 0x00, 0xe2, 0x06, 0x40, - 0x33, 0xea, 0x30, 0x59, + 0x33, 0xea, 0x3a, 0x59, 0x33, 0xea, 0x00, 0x00, - 0x01, 0x52, 0x4e, 0x7d, + 0x01, 0x52, 0x66, 0x7d, 0x02, 0x58, 0x50, 0x31, 0xff, 0xea, 0x10, 0x0b, + 0xff, 0x93, 0x45, 0x78, + 0x50, 0x4b, 0x40, 0x68, + 0xbf, 0x3a, 0x74, 0x08, + 0x14, 0xea, 0x46, 0x59, + 0x14, 0xea, 0x04, 0x00, 0x08, 0xa8, 0x51, 0x03, - 0x01, 0xa4, 0x43, 0x78, - 0x00, 0xe2, 0x32, 0x5b, + 0x01, 0xa4, 0x4d, 0x78, + 0x00, 0xe2, 0x44, 0x5b, 0x00, 0xe2, 0x34, 0x40, 0xff, 0xea, 0xd4, 0x19, 0x02, 0xa8, 0x84, 0x32, - 0x00, 0xea, 0x30, 0x59, + 0x00, 0xea, 0x3a, 0x59, 0x01, 0xea, 0x00, 0x30, - 0x00, 0xe2, 0x80, 0x5d, - 0x00, 0xe2, 0x4e, 0x4d, - 0x11, 0xea, 0x30, 0x59, + 0x00, 0xe2, 0x98, 0x5d, + 0x00, 0xe2, 0x66, 0x4d, + 0x11, 0xea, 0x3a, 0x59, 0x11, 0xea, 0x00, 0x00, - 0x00, 0xe2, 0x80, 0x5d, - 0x00, 0xe2, 0x4e, 0x4d, - 0x33, 0xea, 0x30, 0x59, + 0x00, 0xe2, 0x98, 0x5d, + 0x00, 0xe2, 0x66, 0x4d, + 0x33, 0xea, 0x3a, 0x59, 0x33, 0xea, 0x00, 0x00, - 0x00, 0xe2, 0x28, 0x43, - 0x00, 0xea, 0x30, 0x59, + 0x00, 0xe2, 0x3a, 0x43, + 0x00, 0xea, 0x3a, 0x59, 0x01, 0xea, 0x00, 0x30, - 0x80, 0xf9, 0x64, 0x68, - 0x00, 0xe2, 0x2e, 0x59, - 0x11, 0xea, 0x30, 0x59, + 0x80, 0xf9, 0x6e, 0x68, + 0x00, 0xe2, 0x38, 0x59, + 0x11, 0xea, 0x3a, 0x59, 0x11, 0xea, 0x00, 0x00, - 0x80, 0xf9, 0x2e, 0x79, + 0x80, 0xf9, 0x38, 0x79, 0xff, 0xea, 0xd4, 0x0d, - 0x22, 0xea, 0x30, 0x59, + 0x22, 0xea, 0x3a, 0x59, 0x22, 0xea, 0x00, 0x00, - 0x10, 0x16, 0x76, 0x78, + 0x10, 0x16, 0x80, 0x78, 0x01, 0x0b, 0xa2, 0x32, 0x10, 0x16, 0x2c, 0x00, - 0x18, 0xad, 0xe4, 0x78, - 0x04, 0xad, 0xb2, 0x68, - 0x80, 0xad, 0x4e, 0x7d, - 0x10, 0xad, 0x80, 0x78, + 0x18, 0xad, 0xee, 0x78, + 0x04, 0xad, 0xbc, 0x68, + 0x80, 0xad, 0x66, 0x7d, + 0x10, 0xad, 0x8a, 0x78, 0xe7, 0xad, 0x5a, 0x0d, 0xe7, 0xad, 0x5a, 0x09, - 0x00, 0xe2, 0x8e, 0x58, + 0x00, 0xe2, 0x98, 0x58, 0xff, 0xea, 0x56, 0x02, 0x04, 0x7c, 0x78, 0x32, - 0x20, 0x16, 0x4e, 0x7d, + 0x20, 0x16, 0x66, 0x7d, 0x04, 0x38, 0x79, 0x32, 0x80, 0x37, 0x6f, 0x16, - 0xff, 0x2d, 0x9d, 0x60, - 0xff, 0x29, 0x9d, 0x60, - 0x40, 0x51, 0xad, 0x78, - 0xff, 0x4f, 0x9d, 0x68, + 0xff, 0x2d, 0xa7, 0x60, + 0xff, 0x29, 0xa7, 0x60, + 0x40, 0x51, 0xb7, 0x78, + 0xff, 0x4f, 0xa7, 0x68, 0xff, 0x4d, 0xc1, 0x19, 0x00, 0x4e, 0xd5, 0x19, - 0x00, 0xe2, 0xac, 0x50, + 0x00, 0xe2, 0xb6, 0x50, 0x01, 0x4c, 0xc1, 0x31, 0x00, 0x50, 0xd5, 0x19, - 0x00, 0xe2, 0xac, 0x48, - 0x80, 0x18, 0x4e, 0x7d, + 0x00, 0xe2, 0xb6, 0x48, + 0x80, 0x18, 0x66, 0x7d, 0x02, 0x4a, 0x1d, 0x30, 0x10, 0xea, 0x18, 0x00, 0x60, 0x18, 0x30, 0x00, @@ -95,7 +100,7 @@ 0x02, 0xea, 0x02, 0x00, 0xff, 0xea, 0xa0, 0x0a, 0x80, 0x18, 0x30, 0x04, - 0x40, 0xad, 0x4e, 0x7d, + 0x40, 0xad, 0x66, 0x7d, 0xe7, 0xad, 0x5a, 0x09, 0x02, 0xa8, 0x40, 0x31, 0xff, 0xea, 0xc0, 0x09, @@ -105,25 +110,25 @@ 0xff, 0xea, 0x2a, 0x03, 0xff, 0xea, 0x2e, 0x03, 0x01, 0x10, 0xd4, 0x31, - 0x10, 0xa8, 0xd9, 0x68, + 0x10, 0xa8, 0xe3, 0x68, 0x3d, 0xa9, 0xc5, 0x29, 0xfe, 0xe2, 0xc4, 0x09, 0x01, 0xea, 0xc6, 0x01, 0x02, 0xe2, 0xc8, 0x31, 0x02, 0xec, 0x50, 0x31, 0x02, 0xa0, 0xda, 0x31, - 0xff, 0xa9, 0xd8, 0x70, + 0xff, 0xa9, 0xe2, 0x70, 0x02, 0xa0, 0x28, 0x37, - 0xff, 0x21, 0xe1, 0x70, + 0xff, 0x21, 0xeb, 0x70, 0x02, 0x22, 0x51, 0x31, 0x02, 0xa0, 0x2c, 0x33, 0x02, 0xa0, 0x44, 0x36, 0x02, 0xa0, 0x40, 0x32, 0x02, 0xa0, 0x44, 0x36, - 0x04, 0x47, 0xe9, 0x68, - 0x40, 0x16, 0x14, 0x69, - 0xff, 0x2d, 0x19, 0x61, - 0xff, 0x29, 0x4f, 0x75, + 0x04, 0x47, 0xf3, 0x68, + 0x40, 0x16, 0x1e, 0x69, + 0xff, 0x2d, 0x23, 0x61, + 0xff, 0x29, 0x67, 0x75, 0x01, 0x37, 0xc1, 0x31, 0x02, 0x28, 0x55, 0x32, 0x01, 0xea, 0x5a, 0x01, @@ -135,20 +140,20 @@ 0x01, 0x50, 0xa1, 0x1a, 0xff, 0x4e, 0x9d, 0x1a, 0xff, 0x4f, 0x9f, 0x22, - 0xff, 0x8d, 0x0d, 0x71, - 0x80, 0xac, 0x0c, 0x71, - 0x20, 0x16, 0x0c, 0x69, + 0xff, 0x8d, 0x17, 0x71, + 0x80, 0xac, 0x16, 0x71, + 0x20, 0x16, 0x16, 0x69, 0x02, 0x8c, 0x51, 0x31, - 0x00, 0xe2, 0xf6, 0x40, + 0x00, 0xe2, 0x00, 0x41, 0x01, 0xac, 0x08, 0x31, 0x09, 0xea, 0x5a, 0x01, 0x02, 0x8c, 0x51, 0x32, 0xff, 0xea, 0x1a, 0x07, 0x04, 0x24, 0xf9, 0x30, - 0x1d, 0xea, 0x24, 0x41, + 0x1d, 0xea, 0x2e, 0x41, 0x02, 0x2c, 0x51, 0x31, 0x04, 0xac, 0xf9, 0x30, - 0x19, 0xea, 0x24, 0x59, + 0x19, 0xea, 0x2e, 0x59, 0x02, 0x8c, 0x59, 0x32, 0x02, 0x28, 0x19, 0x33, 0x02, 0xa8, 0x50, 0x36, @@ -170,23 +175,23 @@ 0x02, 0x20, 0xb9, 0x30, 0x02, 0x20, 0x51, 0x31, 0x4c, 0xa9, 0xd7, 0x28, - 0x10, 0xa8, 0x4f, 0x79, + 0x10, 0xa8, 0x59, 0x79, 0x01, 0x6b, 0xc0, 0x30, 0x02, 0x64, 0xc8, 0x00, 0x40, 0x3a, 0x74, 0x04, - 0x00, 0xe2, 0x5c, 0x58, - 0x33, 0xea, 0x30, 0x59, + 0x00, 0xe2, 0x66, 0x58, + 0x33, 0xea, 0x3a, 0x59, 0x33, 0xea, 0x00, 0x00, 0x30, 0x3f, 0xc0, 0x09, - 0x30, 0xe0, 0x50, 0x61, - 0x20, 0x3f, 0x66, 0x69, - 0x10, 0x3f, 0x50, 0x79, + 0x30, 0xe0, 0x5a, 0x61, + 0x20, 0x3f, 0x70, 0x69, + 0x10, 0x3f, 0x5a, 0x79, 0x02, 0xea, 0x7e, 0x00, - 0x00, 0xea, 0x30, 0x59, + 0x00, 0xea, 0x3a, 0x59, 0x01, 0xea, 0x00, 0x30, 0x02, 0x48, 0x51, 0x35, 0x01, 0xea, 0x7e, 0x00, - 0x11, 0xea, 0x30, 0x59, + 0x11, 0xea, 0x3a, 0x59, 0x11, 0xea, 0x00, 0x00, 0x02, 0x48, 0x51, 0x35, 0x08, 0xea, 0x98, 0x00, @@ -196,11 +201,11 @@ 0x0f, 0x67, 0xc0, 0x09, 0x00, 0x34, 0x69, 0x02, 0x20, 0xea, 0x96, 0x00, - 0x00, 0xe2, 0xdc, 0x41, - 0x40, 0x3a, 0x9a, 0x69, + 0x00, 0xe2, 0xee, 0x41, + 0x40, 0x3a, 0xa4, 0x69, 0x02, 0x55, 0x06, 0x68, - 0x02, 0x56, 0x9a, 0x69, - 0xff, 0x5b, 0x9a, 0x61, + 0x02, 0x56, 0xa4, 0x69, + 0xff, 0x5b, 0xa4, 0x61, 0x02, 0x20, 0x51, 0x31, 0x80, 0xea, 0xb2, 0x01, 0x44, 0xea, 0x00, 0x00, @@ -208,140 +213,144 @@ 0x33, 0xea, 0x00, 0x00, 0xff, 0xea, 0xb2, 0x09, 0xff, 0xe0, 0xc0, 0x19, - 0xff, 0xe0, 0x9c, 0x79, + 0xff, 0xe0, 0xa6, 0x79, 0x02, 0x94, 0x51, 0x31, - 0x00, 0xe2, 0x92, 0x41, + 0x00, 0xe2, 0x9c, 0x41, 0x02, 0x5e, 0x50, 0x31, 0x02, 0xa8, 0xb8, 0x30, 0x02, 0x5c, 0x50, 0x31, - 0xff, 0x95, 0xad, 0x71, + 0xff, 0x95, 0xb7, 0x71, 0x02, 0x94, 0x41, 0x31, 0x02, 0x22, 0x51, 0x31, 0x02, 0xa0, 0x2c, 0x33, 0x02, 0xa0, 0x44, 0x32, - 0x00, 0xe2, 0xb6, 0x41, - 0x10, 0xa8, 0xb7, 0x69, + 0x00, 0xe2, 0xc0, 0x41, + 0x10, 0xa8, 0xc1, 0x69, 0x3d, 0xa9, 0xc9, 0x29, 0x01, 0xe4, 0xc8, 0x01, 0x01, 0xea, 0xca, 0x01, 0xff, 0xea, 0xda, 0x01, 0x02, 0x20, 0x51, 0x31, 0x02, 0x96, 0x41, 0x32, - 0xff, 0x21, 0xbf, 0x61, + 0xff, 0x21, 0xc9, 0x61, 0xff, 0xea, 0x46, 0x02, 0x02, 0x5c, 0x50, 0x31, 0x40, 0xea, 0x96, 0x00, - 0x02, 0x56, 0x94, 0x6d, - 0x01, 0x55, 0x94, 0x6d, - 0x10, 0xa8, 0xcb, 0x79, - 0x10, 0x40, 0xcc, 0x69, - 0x01, 0x56, 0x06, 0x68, + 0x02, 0x56, 0xac, 0x6d, + 0x01, 0x55, 0xac, 0x6d, + 0x10, 0xa8, 0xd5, 0x79, + 0x10, 0x40, 0xde, 0x69, + 0x01, 0x56, 0xde, 0x79, + 0xff, 0x93, 0x07, 0x78, + 0x13, 0xea, 0x46, 0x59, + 0x13, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x06, 0x40, 0xbf, 0x3a, 0x74, 0x08, 0x08, 0xea, 0x98, 0x00, 0x08, 0x57, 0xae, 0x00, 0x01, 0xa9, 0x69, 0x32, 0x01, 0xaa, 0x6b, 0x32, + 0x40, 0xea, 0x66, 0x02, 0x08, 0x3c, 0x78, 0x00, 0x80, 0xea, 0x62, 0x02, - 0x40, 0xea, 0x66, 0x02, - 0x00, 0xe2, 0x92, 0x5b, + 0x00, 0xe2, 0xa4, 0x5b, 0x01, 0x36, 0xc1, 0x31, - 0x9f, 0xe0, 0x26, 0x7c, - 0x80, 0xe0, 0xf0, 0x71, - 0xa0, 0xe0, 0x28, 0x72, - 0xc0, 0xe0, 0x1e, 0x72, - 0xe0, 0xe0, 0x58, 0x72, - 0x01, 0xea, 0x3c, 0x59, + 0x9f, 0xe0, 0x38, 0x7c, + 0x80, 0xe0, 0x02, 0x72, + 0xa0, 0xe0, 0x3a, 0x72, + 0xc0, 0xe0, 0x30, 0x72, + 0xe0, 0xe0, 0x6a, 0x72, + 0x01, 0xea, 0x46, 0x59, 0x01, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xdc, 0x41, - 0x80, 0x33, 0xf7, 0x79, - 0x03, 0xea, 0x3c, 0x59, + 0x00, 0xe2, 0xee, 0x41, + 0x80, 0x33, 0x09, 0x7a, + 0x03, 0xea, 0x46, 0x59, 0x03, 0xea, 0x04, 0x00, - 0xee, 0x00, 0xfe, 0x69, + 0xee, 0x00, 0x10, 0x6a, 0x05, 0xea, 0xb4, 0x00, - 0x33, 0xea, 0x30, 0x59, + 0x33, 0xea, 0x3a, 0x59, 0x33, 0xea, 0x00, 0x00, 0x02, 0xa8, 0x90, 0x32, - 0x00, 0xe2, 0x56, 0x59, + 0x00, 0xe2, 0x60, 0x59, 0xef, 0x92, 0xd5, 0x19, - 0x00, 0xe2, 0x0e, 0x52, + 0x00, 0xe2, 0x20, 0x52, 0x0b, 0x84, 0xe1, 0x30, 0x02, 0xea, 0x36, 0x00, 0xa8, 0xea, 0x32, 0x00, - 0x00, 0xe2, 0x14, 0x42, + 0x00, 0xe2, 0x26, 0x42, 0x01, 0x92, 0xd1, 0x30, 0x10, 0x80, 0x89, 0x31, 0x20, 0xea, 0x32, 0x00, 0xbf, 0x33, 0x67, 0x0a, - 0x20, 0x19, 0x16, 0x6a, - 0x02, 0x4d, 0xdc, 0x69, + 0x20, 0x19, 0x28, 0x6a, + 0x02, 0x4d, 0xee, 0x69, 0x40, 0x33, 0x67, 0x02, - 0x00, 0xe2, 0xdc, 0x41, - 0x80, 0x33, 0x95, 0x6a, + 0x00, 0xe2, 0xee, 0x41, + 0x80, 0x33, 0xa7, 0x6a, 0x01, 0x44, 0x10, 0x33, 0x08, 0xa8, 0x51, 0x03, - 0x00, 0xe2, 0xdc, 0x41, + 0x00, 0xe2, 0xee, 0x41, 0x10, 0xea, 0x80, 0x00, 0x01, 0x31, 0xc5, 0x31, - 0x80, 0xe2, 0x44, 0x62, - 0x10, 0xa8, 0x69, 0x6a, + 0x80, 0xe2, 0x56, 0x62, + 0x10, 0xa8, 0x7b, 0x6a, 0xc0, 0xaa, 0xc5, 0x01, - 0x40, 0xa8, 0x35, 0x6a, + 0x40, 0xa8, 0x47, 0x6a, 0xbf, 0xe2, 0xc4, 0x09, - 0x20, 0xa8, 0x49, 0x7a, + 0x20, 0xa8, 0x5b, 0x7a, 0x01, 0xe2, 0x88, 0x30, - 0x00, 0xe2, 0x92, 0x5b, - 0xa0, 0x36, 0x51, 0x62, + 0x00, 0xe2, 0xa4, 0x5b, + 0xa0, 0x36, 0x63, 0x62, 0x23, 0xa8, 0x89, 0x08, - 0x00, 0xe2, 0x92, 0x5b, - 0xa0, 0x36, 0x51, 0x62, - 0x00, 0xa8, 0x48, 0x42, - 0xff, 0xe2, 0x48, 0x62, - 0x00, 0xe2, 0x68, 0x42, + 0x00, 0xe2, 0xa4, 0x5b, + 0xa0, 0x36, 0x63, 0x62, + 0x00, 0xa8, 0x5a, 0x42, + 0xff, 0xe2, 0x5a, 0x62, + 0x00, 0xe2, 0x7a, 0x42, 0x40, 0xea, 0x98, 0x00, 0x01, 0xe2, 0x88, 0x30, - 0x00, 0xe2, 0x92, 0x5b, - 0xa0, 0x36, 0x27, 0x72, + 0x00, 0xe2, 0xa4, 0x5b, + 0xa0, 0x36, 0x39, 0x72, 0x40, 0xea, 0x98, 0x00, 0x01, 0x31, 0x89, 0x32, 0x08, 0xea, 0x62, 0x02, - 0x00, 0xe2, 0xdc, 0x41, - 0xe0, 0xea, 0xa2, 0x5b, - 0x80, 0xe0, 0xa0, 0x6a, - 0x04, 0xe0, 0x40, 0x73, - 0x02, 0xe0, 0x70, 0x73, - 0x00, 0xea, 0xfe, 0x72, - 0x03, 0xe0, 0x80, 0x73, - 0x23, 0xe0, 0x7a, 0x72, - 0x08, 0xe0, 0x9c, 0x72, - 0x00, 0xe2, 0x92, 0x5b, - 0x07, 0xea, 0x3c, 0x59, + 0x00, 0xe2, 0xee, 0x41, + 0xe0, 0xea, 0xb4, 0x5b, + 0x80, 0xe0, 0xb2, 0x6a, + 0x04, 0xe0, 0x52, 0x73, + 0x02, 0xe0, 0x82, 0x73, + 0x00, 0xea, 0x10, 0x73, + 0x03, 0xe0, 0x92, 0x73, + 0x23, 0xe0, 0x8c, 0x72, + 0x08, 0xe0, 0xae, 0x72, + 0x00, 0xe2, 0xa4, 0x5b, + 0x07, 0xea, 0x46, 0x59, 0x07, 0xea, 0x04, 0x00, - 0x08, 0x42, 0xdd, 0x71, - 0x04, 0x42, 0x77, 0x62, + 0x08, 0x42, 0xef, 0x71, + 0x04, 0x42, 0x89, 0x62, 0x01, 0x43, 0x89, 0x30, - 0x00, 0xe2, 0x68, 0x42, + 0x00, 0xe2, 0x7a, 0x42, 0x01, 0x44, 0xd4, 0x31, - 0x00, 0xe2, 0x68, 0x42, + 0x00, 0xe2, 0x7a, 0x42, 0x01, 0x00, 0x60, 0x32, - 0x33, 0xea, 0x30, 0x59, + 0x33, 0xea, 0x3a, 0x59, 0x33, 0xea, 0x00, 0x00, 0x4c, 0x34, 0xc1, 0x28, 0x01, 0x64, 0xc0, 0x31, - 0x00, 0x30, 0x31, 0x59, + 0x00, 0x30, 0x3b, 0x59, 0x01, 0x30, 0x01, 0x30, - 0x01, 0xe0, 0x9a, 0x7a, - 0xa0, 0xea, 0x98, 0x5b, - 0x01, 0xa0, 0x9a, 0x62, - 0x01, 0x84, 0x93, 0x7a, - 0x01, 0xa7, 0x9c, 0x7a, - 0x00, 0xe2, 0x9c, 0x42, - 0x03, 0xea, 0x3c, 0x59, + 0x01, 0xe0, 0xac, 0x7a, + 0xa0, 0xea, 0xaa, 0x5b, + 0x01, 0xa0, 0xac, 0x62, + 0x01, 0x84, 0xa5, 0x7a, + 0x01, 0xa7, 0xae, 0x7a, + 0x00, 0xe2, 0xae, 0x42, + 0x03, 0xea, 0x46, 0x59, 0x03, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x9c, 0x42, - 0x07, 0xea, 0xaa, 0x5b, + 0x00, 0xe2, 0xae, 0x42, + 0x07, 0xea, 0xbc, 0x5b, 0x01, 0x44, 0xd4, 0x31, - 0x00, 0xe2, 0xdc, 0x41, + 0x00, 0xe2, 0xee, 0x41, 0x3f, 0xe0, 0x6a, 0x0a, 0xc0, 0x34, 0xc1, 0x09, 0x00, 0x35, 0x51, 0x01, @@ -352,54 +361,54 @@ 0x01, 0xea, 0xc6, 0x01, 0x02, 0xe2, 0xc8, 0x31, 0x02, 0xec, 0x40, 0x31, - 0xff, 0xa1, 0xbc, 0x72, + 0xff, 0xa1, 0xce, 0x72, 0x02, 0xe8, 0xda, 0x31, 0x02, 0xa0, 0x50, 0x31, - 0x00, 0xe2, 0xde, 0x42, + 0x00, 0xe2, 0xf0, 0x42, 0x80, 0x33, 0x67, 0x02, 0x01, 0x44, 0xd4, 0x31, - 0x00, 0xe2, 0x92, 0x5b, + 0x00, 0xe2, 0xa4, 0x5b, 0x01, 0x33, 0x67, 0x02, - 0xe0, 0x36, 0xf9, 0x62, + 0xe0, 0x36, 0x0b, 0x63, 0x02, 0x33, 0x67, 0x02, - 0x20, 0x46, 0xf2, 0x62, + 0x20, 0x46, 0x04, 0x63, 0xff, 0xea, 0x52, 0x09, - 0xa8, 0xea, 0x98, 0x5b, - 0x04, 0xa8, 0xd9, 0x7a, + 0xa8, 0xea, 0xaa, 0x5b, + 0x04, 0xa8, 0xeb, 0x7a, 0x01, 0x34, 0xc1, 0x31, - 0x00, 0xa9, 0xd9, 0x62, + 0x00, 0xa9, 0xeb, 0x62, 0x01, 0x35, 0xc1, 0x31, - 0x00, 0xaa, 0xe3, 0x72, + 0x00, 0xaa, 0xf5, 0x72, 0x01, 0xa9, 0x52, 0x11, - 0xff, 0xa9, 0xce, 0x6a, - 0x00, 0xe2, 0xf2, 0x42, + 0xff, 0xa9, 0xe0, 0x6a, + 0x00, 0xe2, 0x04, 0x43, 0x10, 0x33, 0x67, 0x02, - 0x04, 0xa8, 0xf3, 0x7a, + 0x04, 0xa8, 0x05, 0x7b, 0xfb, 0xa8, 0x51, 0x0b, 0xff, 0xea, 0x66, 0x0a, - 0x01, 0xa4, 0xed, 0x6a, + 0x01, 0xa4, 0xff, 0x6a, 0x02, 0xa8, 0x90, 0x32, - 0x00, 0xe2, 0x56, 0x59, - 0x10, 0xa8, 0x9d, 0x7a, - 0xff, 0xea, 0xaa, 0x5b, - 0x00, 0xe2, 0x9c, 0x42, - 0x04, 0xea, 0x3c, 0x59, + 0x00, 0xe2, 0x60, 0x59, + 0x10, 0xa8, 0xaf, 0x7a, + 0xff, 0xea, 0xbc, 0x5b, + 0x00, 0xe2, 0xae, 0x42, + 0x04, 0xea, 0x46, 0x59, 0x04, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x9c, 0x42, - 0x04, 0xea, 0x3c, 0x59, + 0x00, 0xe2, 0xae, 0x42, + 0x04, 0xea, 0x46, 0x59, 0x04, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xdc, 0x41, - 0x08, 0xa8, 0x95, 0x7a, - 0xc0, 0x33, 0x09, 0x7b, - 0x80, 0x33, 0x95, 0x6a, - 0xff, 0x88, 0x09, 0x6b, - 0x40, 0x33, 0x95, 0x6a, - 0x10, 0xa8, 0x0f, 0x7b, - 0x0a, 0xea, 0x3c, 0x59, + 0x00, 0xe2, 0xee, 0x41, + 0x08, 0xa8, 0xa7, 0x7a, + 0xc0, 0x33, 0x1b, 0x7b, + 0x80, 0x33, 0xa7, 0x6a, + 0xff, 0x88, 0x1b, 0x6b, + 0x40, 0x33, 0xa7, 0x6a, + 0x10, 0xa8, 0x21, 0x7b, + 0x0a, 0xea, 0x46, 0x59, 0x0a, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x28, 0x5b, - 0x00, 0xe2, 0x5c, 0x43, - 0x50, 0x4b, 0x16, 0x6b, + 0x00, 0xe2, 0x3a, 0x5b, + 0x00, 0xe2, 0x6e, 0x43, + 0x50, 0x4b, 0x28, 0x6b, 0xbf, 0x3a, 0x74, 0x08, 0x01, 0xe0, 0xf8, 0x31, 0xff, 0xea, 0xc0, 0x09, @@ -407,24 +416,24 @@ 0x00, 0x2f, 0x5f, 0x22, 0x04, 0x47, 0x8f, 0x02, 0x01, 0xfc, 0xc0, 0x35, - 0x33, 0xea, 0x30, 0x59, + 0x33, 0xea, 0x3a, 0x59, 0x33, 0xea, 0x00, 0x00, 0x02, 0x42, 0x51, 0x31, 0x10, 0xa8, 0x51, 0x03, - 0xff, 0x88, 0x37, 0x6b, - 0x01, 0xa4, 0x33, 0x6b, - 0x02, 0xa4, 0x3b, 0x6b, - 0x01, 0x84, 0x3b, 0x7b, + 0xff, 0x88, 0x49, 0x6b, + 0x01, 0xa4, 0x45, 0x6b, + 0x02, 0xa4, 0x4d, 0x6b, + 0x01, 0x84, 0x4d, 0x7b, 0x02, 0x28, 0x19, 0x33, 0x02, 0xa8, 0x50, 0x36, - 0xff, 0x88, 0x3b, 0x73, - 0x00, 0xe2, 0x12, 0x5b, + 0xff, 0x88, 0x4d, 0x73, + 0x00, 0xe2, 0x24, 0x5b, 0x02, 0x2c, 0x19, 0x33, 0x02, 0xa8, 0x58, 0x32, 0x04, 0xa4, 0x49, 0x07, - 0xc0, 0x33, 0x95, 0x6a, + 0xc0, 0x33, 0xa7, 0x6a, 0x04, 0xa8, 0x51, 0x03, - 0x20, 0xa8, 0x5d, 0x6b, + 0x20, 0xa8, 0x6f, 0x6b, 0x02, 0xa8, 0x40, 0x31, 0xc0, 0x34, 0xc1, 0x09, 0x00, 0x35, 0x51, 0x01, @@ -439,66 +448,66 @@ 0xf7, 0x57, 0xae, 0x08, 0x08, 0xea, 0x98, 0x00, 0x01, 0x44, 0xd4, 0x31, - 0xee, 0x00, 0x66, 0x6b, + 0xee, 0x00, 0x78, 0x6b, 0x02, 0xea, 0xb4, 0x00, - 0x00, 0xe2, 0x8e, 0x5b, - 0x09, 0x4c, 0x68, 0x7b, + 0x00, 0xe2, 0xa0, 0x5b, + 0x09, 0x4c, 0x7a, 0x7b, 0x08, 0x4c, 0x06, 0x68, - 0x0b, 0xea, 0x3c, 0x59, + 0x0b, 0xea, 0x46, 0x59, 0x0b, 0xea, 0x04, 0x00, 0x01, 0x44, 0xd4, 0x31, - 0x20, 0x33, 0xdd, 0x79, - 0x00, 0xe2, 0x78, 0x5b, - 0x00, 0xe2, 0xdc, 0x41, - 0x01, 0x84, 0x7d, 0x7b, + 0x20, 0x33, 0xef, 0x79, + 0x00, 0xe2, 0x8a, 0x5b, + 0x00, 0xe2, 0xee, 0x41, + 0x01, 0x84, 0x8f, 0x7b, 0x01, 0xa4, 0x49, 0x07, 0x08, 0x60, 0x30, 0x33, 0x08, 0x80, 0x41, 0x37, 0xdf, 0x33, 0x67, 0x0a, - 0xee, 0x00, 0x8a, 0x6b, + 0xee, 0x00, 0x9c, 0x6b, 0x05, 0xea, 0xb4, 0x00, - 0x33, 0xea, 0x30, 0x59, + 0x33, 0xea, 0x3a, 0x59, 0x33, 0xea, 0x00, 0x00, - 0x00, 0xe2, 0x56, 0x59, - 0x00, 0xe2, 0x9c, 0x42, + 0x00, 0xe2, 0x60, 0x59, + 0x00, 0xe2, 0xae, 0x42, 0x01, 0xea, 0x6c, 0x02, 0xc0, 0xea, 0x66, 0x06, - 0xff, 0x42, 0x92, 0x7b, - 0x04, 0x4c, 0x92, 0x6b, + 0xff, 0x42, 0xa4, 0x7b, + 0x04, 0x4c, 0xa4, 0x6b, 0xe0, 0x41, 0x6c, 0x0e, 0x01, 0x44, 0xd4, 0x31, - 0xff, 0x42, 0x9a, 0x7b, - 0x04, 0x4c, 0x9a, 0x6b, + 0xff, 0x42, 0xac, 0x7b, + 0x04, 0x4c, 0xac, 0x6b, 0xe0, 0x41, 0x6c, 0x0a, - 0xe0, 0x36, 0xdd, 0x61, + 0xe0, 0x36, 0xef, 0x61, 0xff, 0xea, 0xca, 0x09, 0x01, 0xe2, 0xc8, 0x31, 0x01, 0x46, 0xda, 0x35, 0x01, 0x44, 0xd4, 0x35, 0x10, 0xea, 0x80, 0x00, 0x01, 0xe2, 0x62, 0x36, - 0x04, 0xa6, 0xb2, 0x7b, + 0x04, 0xa6, 0xc4, 0x7b, 0xff, 0xea, 0x5a, 0x09, 0xff, 0xea, 0x4c, 0x0d, - 0x01, 0xa6, 0xd0, 0x6b, - 0x10, 0xad, 0x4e, 0x7d, - 0x80, 0xad, 0xc8, 0x6b, - 0x08, 0xad, 0x4e, 0x6d, + 0x01, 0xa6, 0xe2, 0x6b, + 0x10, 0xad, 0x66, 0x7d, + 0x80, 0xad, 0xda, 0x6b, + 0x08, 0xad, 0x66, 0x6d, 0x04, 0x84, 0xf9, 0x30, 0x00, 0xea, 0x08, 0x81, 0xff, 0xea, 0xd4, 0x09, 0x02, 0x84, 0xf9, 0x88, 0x1d, 0xea, 0x5a, 0x01, 0x04, 0xa6, 0x4c, 0x05, - 0x04, 0xa6, 0x4e, 0x7d, + 0x04, 0xa6, 0x66, 0x7d, 0xff, 0xea, 0x5a, 0x09, 0x03, 0x84, 0x59, 0x89, 0x03, 0xea, 0x4c, 0x01, - 0x80, 0x1a, 0x4e, 0x7d, + 0x80, 0x1a, 0x66, 0x7d, 0x08, 0xb0, 0xe0, 0x30, 0x04, 0xb0, 0xe0, 0x30, 0x03, 0xb0, 0xf0, 0x30, - 0x01, 0x78, 0xdc, 0x7b, + 0x01, 0x78, 0xee, 0x7b, 0x01, 0xa7, 0x4e, 0x11, 0x01, 0xb0, 0x06, 0x33, 0x7f, 0x83, 0xe9, 0x08, @@ -509,244 +518,247 @@ 0x00, 0x86, 0x0d, 0x23, 0x00, 0x87, 0x0f, 0x23, 0x01, 0x84, 0xc5, 0x31, - 0x01, 0xa7, 0xf2, 0x7b, + 0x01, 0xa7, 0x04, 0x7c, 0x04, 0xe2, 0xc4, 0x01, - 0x80, 0x83, 0xf9, 0x7b, + 0x80, 0x83, 0x0b, 0x7c, 0x02, 0xe2, 0xc4, 0x01, 0xff, 0xea, 0x4c, 0x09, 0x01, 0xe2, 0x36, 0x30, 0xc8, 0x19, 0x32, 0x00, 0x88, 0x19, 0x32, 0x00, 0x01, 0xac, 0xd4, 0x99, - 0x00, 0xe2, 0x4e, 0x55, + 0x00, 0xe2, 0x66, 0x55, 0xfe, 0xa6, 0x4c, 0x0d, 0x0b, 0x98, 0xe1, 0x30, 0x01, 0xa0, 0x4f, 0x09, 0xfd, 0xa4, 0x49, 0x09, - 0x80, 0xa3, 0x0f, 0x7c, + 0x80, 0xa3, 0x21, 0x7c, 0x02, 0xa4, 0x48, 0x01, - 0x01, 0xa7, 0x12, 0x7c, + 0x01, 0xa7, 0x24, 0x7c, 0x04, 0xa4, 0x48, 0x01, 0x01, 0xa4, 0x36, 0x30, 0xa8, 0xea, 0x32, 0x00, 0xfd, 0xa4, 0x49, 0x0b, 0x05, 0xa3, 0x07, 0x33, - 0x80, 0x83, 0x1f, 0x6c, + 0x80, 0x83, 0x31, 0x6c, 0x02, 0xea, 0x4c, 0x05, 0xff, 0xea, 0x4c, 0x0d, - 0x00, 0xe2, 0x28, 0x59, - 0x02, 0xa6, 0xb4, 0x6b, + 0x00, 0xe2, 0x32, 0x59, + 0x02, 0xa6, 0xc6, 0x6b, 0x80, 0xf9, 0xf2, 0x05, - 0xc0, 0x33, 0x2d, 0x7c, - 0x03, 0xea, 0x3c, 0x59, + 0xc0, 0x33, 0x3f, 0x7c, + 0x03, 0xea, 0x46, 0x59, 0x03, 0xea, 0x04, 0x00, - 0x20, 0x33, 0x51, 0x7c, - 0x01, 0x84, 0x37, 0x6c, - 0x06, 0xea, 0x3c, 0x59, + 0x20, 0x33, 0x63, 0x7c, + 0x01, 0x84, 0x49, 0x6c, + 0x06, 0xea, 0x46, 0x59, 0x06, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x54, 0x44, + 0x00, 0xe2, 0x66, 0x44, 0x01, 0x00, 0x60, 0x32, - 0xee, 0x00, 0x40, 0x6c, + 0xee, 0x00, 0x52, 0x6c, 0x05, 0xea, 0xb4, 0x00, - 0x33, 0xea, 0x30, 0x59, + 0x33, 0xea, 0x3a, 0x59, 0x33, 0xea, 0x00, 0x00, 0x80, 0x3d, 0x7a, 0x00, - 0xfc, 0x42, 0x42, 0x7c, + 0xfc, 0x42, 0x54, 0x7c, 0x7f, 0x3d, 0x7a, 0x08, - 0x00, 0x30, 0x31, 0x59, + 0x00, 0x30, 0x3b, 0x59, 0x01, 0x30, 0x01, 0x30, - 0x09, 0xea, 0x3c, 0x59, + 0x09, 0xea, 0x46, 0x59, 0x09, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xdc, 0x41, - 0x01, 0xa4, 0x37, 0x6c, - 0x00, 0xe2, 0x04, 0x5c, + 0x00, 0xe2, 0xee, 0x41, + 0x01, 0xa4, 0x49, 0x6c, + 0x00, 0xe2, 0x16, 0x5c, 0x20, 0x33, 0x67, 0x02, 0x01, 0x00, 0x60, 0x32, - 0x02, 0xa6, 0x5c, 0x7c, - 0x00, 0xe2, 0x20, 0x5c, - 0x00, 0xe2, 0x5c, 0x58, - 0x00, 0xe2, 0x6c, 0x58, + 0x02, 0xa6, 0x6e, 0x7c, + 0x00, 0xe2, 0x32, 0x5c, + 0x00, 0xe2, 0x66, 0x58, + 0x00, 0xe2, 0x76, 0x58, 0x00, 0xe2, 0x30, 0x58, - 0x00, 0x30, 0x31, 0x59, + 0x00, 0x30, 0x3b, 0x59, 0x01, 0x30, 0x01, 0x30, - 0x20, 0x19, 0x5c, 0x6c, - 0x00, 0xe2, 0x84, 0x5c, - 0x04, 0x19, 0x76, 0x6c, + 0x20, 0x19, 0x6e, 0x6c, + 0x00, 0xe2, 0x96, 0x5c, + 0x04, 0x19, 0x88, 0x6c, 0x02, 0x19, 0x32, 0x00, - 0x01, 0x84, 0x77, 0x7c, - 0x01, 0x1b, 0x70, 0x7c, - 0x01, 0x1a, 0x76, 0x6c, - 0x00, 0xe2, 0x26, 0x44, - 0x80, 0x4b, 0x7c, 0x6c, - 0x01, 0x4c, 0x78, 0x7c, - 0x03, 0x42, 0x26, 0x6c, - 0x00, 0xe2, 0xae, 0x5b, + 0x01, 0x84, 0x89, 0x7c, + 0x01, 0x1b, 0x82, 0x7c, + 0x01, 0x1a, 0x88, 0x6c, + 0x00, 0xe2, 0x38, 0x44, + 0x80, 0x4b, 0x8e, 0x6c, + 0x01, 0x4c, 0x8a, 0x7c, + 0x03, 0x42, 0x38, 0x6c, + 0x00, 0xe2, 0xc0, 0x5b, 0x80, 0xf9, 0xf2, 0x01, - 0x04, 0x33, 0xdd, 0x79, - 0x00, 0xe2, 0xdc, 0x41, - 0x02, 0x1b, 0x8c, 0x7c, - 0x08, 0x5d, 0x8a, 0x7c, + 0x04, 0x33, 0xef, 0x79, + 0x00, 0xe2, 0xee, 0x41, + 0x02, 0x1b, 0x9e, 0x7c, + 0x08, 0x5d, 0x9c, 0x7c, 0x03, 0x68, 0x00, 0x37, 0x01, 0x84, 0x09, 0x07, - 0x08, 0x5d, 0x96, 0x6c, - 0x00, 0xe2, 0x5c, 0x58, - 0x00, 0x30, 0x31, 0x59, + 0x08, 0x5d, 0xa8, 0x6c, + 0x00, 0xe2, 0x66, 0x58, + 0x00, 0x30, 0x3b, 0x59, 0x01, 0x30, 0x01, 0x30, - 0x00, 0xe2, 0x84, 0x44, - 0x80, 0x1b, 0xa0, 0x7c, - 0x80, 0x84, 0xa1, 0x6c, + 0x00, 0xe2, 0x96, 0x44, + 0x80, 0x1b, 0xb2, 0x7c, + 0x80, 0x84, 0xb3, 0x6c, 0xff, 0x85, 0x0b, 0x1b, 0xff, 0x86, 0x0d, 0x23, 0xff, 0x87, 0x0f, 0x23, 0xf8, 0x1b, 0x08, 0x0b, 0xff, 0xea, 0x4e, 0x09, - 0x04, 0x1b, 0xa8, 0x7c, + 0x04, 0x1b, 0xba, 0x7c, 0x01, 0xa7, 0x4e, 0x01, 0xff, 0xea, 0x06, 0x0b, 0x03, 0x68, 0x00, 0x37, - 0x00, 0xe2, 0xac, 0x58, + 0x00, 0xe2, 0xb6, 0x58, 0x10, 0xea, 0x18, 0x00, 0xf9, 0xd9, 0xb2, 0x0d, 0x01, 0xd9, 0xb2, 0x05, 0xff, 0xea, 0xd4, 0x09, - 0x10, 0x5b, 0xcc, 0x6c, - 0x08, 0x5b, 0xd4, 0x6c, - 0x20, 0x5b, 0xc2, 0x6c, - 0x02, 0x5b, 0xe2, 0x6d, - 0x0e, 0xea, 0x3c, 0x59, + 0x10, 0x5b, 0xde, 0x6c, + 0x08, 0x5b, 0xe6, 0x6c, + 0x20, 0x5b, 0xd4, 0x6c, + 0x02, 0x5b, 0xfa, 0x6d, + 0x0e, 0xea, 0x46, 0x59, 0x0e, 0xea, 0x04, 0x00, - 0x08, 0x19, 0xc8, 0x7c, + 0x08, 0x19, 0xda, 0x7c, 0xdf, 0x5c, 0xb8, 0x08, 0x01, 0xd9, 0xb2, 0x05, 0x02, 0xea, 0xb4, 0x00, 0x01, 0xd9, 0xb2, 0x05, - 0x01, 0xa4, 0xab, 0x6d, - 0x00, 0xe2, 0x04, 0x5c, - 0x00, 0xe2, 0xee, 0x5c, + 0x01, 0xa4, 0xc3, 0x6d, + 0x00, 0xe2, 0x16, 0x5c, + 0x00, 0xe2, 0x06, 0x5d, 0x01, 0xd9, 0xb2, 0x05, - 0x00, 0xe2, 0x12, 0x5b, + 0x00, 0xe2, 0x24, 0x5b, 0xf3, 0x92, 0xd5, 0x19, - 0x00, 0xe2, 0xe2, 0x54, - 0x80, 0x92, 0xe3, 0x6c, - 0x0f, 0xea, 0x3c, 0x59, + 0x00, 0xe2, 0xf4, 0x54, + 0x80, 0x92, 0xf5, 0x6c, + 0x0f, 0xea, 0x46, 0x59, 0x0f, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xea, 0x44, + 0x00, 0xe2, 0xfc, 0x44, 0x04, 0x8c, 0xe1, 0x30, 0x01, 0xea, 0xf2, 0x00, 0x02, 0xea, 0x36, 0x00, 0xa8, 0xea, 0x32, 0x00, - 0x00, 0xe2, 0x70, 0x5d, + 0xff, 0x93, 0x03, 0x7d, + 0x14, 0xea, 0x46, 0x59, + 0x14, 0xea, 0x04, 0x00, + 0x00, 0xe2, 0x88, 0x5d, 0x01, 0xd9, 0xb2, 0x05, 0x02, 0xa8, 0xf4, 0x31, - 0x02, 0xa6, 0x00, 0x7d, - 0x00, 0xe2, 0x2a, 0x59, - 0x20, 0x5b, 0x0e, 0x6d, - 0xfc, 0x42, 0xfa, 0x7c, - 0x10, 0x40, 0xfc, 0x6c, - 0x20, 0x4d, 0xfe, 0x7c, - 0x08, 0x5d, 0x0e, 0x6d, - 0x02, 0xa6, 0xb4, 0x6b, - 0x00, 0xe2, 0x2a, 0x59, - 0x20, 0x5b, 0x0e, 0x6d, - 0x01, 0x1b, 0x2e, 0x6d, - 0xfc, 0x42, 0x0a, 0x7d, - 0x10, 0x40, 0x0c, 0x6d, - 0x20, 0x4d, 0x4e, 0x7d, - 0x08, 0x5d, 0x4e, 0x7d, + 0x02, 0xa6, 0x18, 0x7d, + 0x00, 0xe2, 0x34, 0x59, + 0x20, 0x5b, 0x26, 0x6d, + 0xfc, 0x42, 0x12, 0x7d, + 0x10, 0x40, 0x14, 0x6d, + 0x20, 0x4d, 0x16, 0x7d, + 0x08, 0x5d, 0x26, 0x6d, + 0x02, 0xa6, 0xc6, 0x6b, + 0x00, 0xe2, 0x34, 0x59, + 0x20, 0x5b, 0x26, 0x6d, + 0x01, 0x1b, 0x46, 0x6d, + 0xfc, 0x42, 0x22, 0x7d, + 0x10, 0x40, 0x24, 0x6d, + 0x20, 0x4d, 0x66, 0x7d, + 0x08, 0x5d, 0x66, 0x7d, 0x02, 0x19, 0x32, 0x00, 0x01, 0x5b, 0x40, 0x31, - 0x00, 0xe2, 0x84, 0x5c, - 0x00, 0xe2, 0x78, 0x5b, + 0x00, 0xe2, 0x96, 0x5c, + 0x00, 0xe2, 0x8a, 0x5b, 0x20, 0xea, 0xb6, 0x00, - 0x00, 0xe2, 0xae, 0x5b, + 0x00, 0xe2, 0xc0, 0x5b, 0x20, 0x5c, 0xb8, 0x00, - 0x04, 0x19, 0x24, 0x6d, - 0x01, 0x1a, 0x24, 0x6d, - 0x00, 0xe2, 0x2a, 0x59, - 0x01, 0x1a, 0x4e, 0x7d, + 0x04, 0x19, 0x3c, 0x6d, + 0x01, 0x1a, 0x3c, 0x6d, + 0x00, 0xe2, 0x34, 0x59, + 0x01, 0x1a, 0x66, 0x7d, 0x80, 0xf9, 0xf2, 0x01, - 0x20, 0xa0, 0x94, 0x7d, - 0x08, 0xa8, 0x2d, 0x7d, - 0x00, 0xe2, 0x40, 0x45, + 0x20, 0xa0, 0xac, 0x7d, + 0x08, 0xa8, 0x45, 0x7d, + 0x00, 0xe2, 0x58, 0x45, 0x02, 0xea, 0xb4, 0x04, 0x02, 0x19, 0x32, 0x00, - 0x08, 0xa8, 0x51, 0x7d, - 0x04, 0x5d, 0xaa, 0x7d, - 0x01, 0x1a, 0xaa, 0x7d, + 0x08, 0xa8, 0x69, 0x7d, + 0x04, 0x5d, 0xc2, 0x7d, + 0x01, 0x1a, 0xc2, 0x7d, 0x01, 0xa4, 0x49, 0x03, 0x80, 0xf9, 0xf2, 0x01, 0x02, 0xa8, 0x84, 0x32, 0x02, 0xea, 0xb4, 0x00, - 0x00, 0xe2, 0x22, 0x43, + 0x00, 0xe2, 0x34, 0x43, 0x02, 0xa8, 0x84, 0x32, 0x02, 0xea, 0xb4, 0x00, 0xff, 0xea, 0xd4, 0x19, - 0x00, 0xe2, 0x36, 0x59, + 0x00, 0xe2, 0x40, 0x59, 0x11, 0x00, 0x00, 0x10, - 0x00, 0xe2, 0x80, 0x5d, - 0x00, 0xe2, 0x22, 0x53, + 0x00, 0xe2, 0x98, 0x5d, + 0x00, 0xe2, 0x34, 0x53, 0xff, 0xea, 0xd4, 0x0d, - 0x00, 0xe2, 0x2a, 0x59, - 0x40, 0x5b, 0x5c, 0x6d, - 0x04, 0x5d, 0xaa, 0x7d, - 0x01, 0x1a, 0xaa, 0x7d, - 0x20, 0x4d, 0x4e, 0x7d, - 0x40, 0x5b, 0x94, 0x7d, - 0x04, 0x5d, 0xaa, 0x7d, - 0x01, 0x1a, 0xaa, 0x7d, + 0x00, 0xe2, 0x34, 0x59, + 0x40, 0x5b, 0x74, 0x6d, + 0x04, 0x5d, 0xc2, 0x7d, + 0x01, 0x1a, 0xc2, 0x7d, + 0x20, 0x4d, 0x66, 0x7d, + 0x40, 0x5b, 0xac, 0x7d, + 0x04, 0x5d, 0xc2, 0x7d, + 0x01, 0x1a, 0xc2, 0x7d, 0x80, 0xf9, 0xf2, 0x01, 0x01, 0xa4, 0x49, 0x03, - 0x08, 0xa8, 0x41, 0x6d, + 0x08, 0xa8, 0x59, 0x6d, 0x02, 0xea, 0xb4, 0x04, - 0xff, 0x6a, 0x76, 0x7d, - 0x10, 0xea, 0x3c, 0x59, + 0xff, 0x6a, 0x8e, 0x7d, + 0x10, 0xea, 0x46, 0x59, 0x10, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x76, 0x45, - 0x00, 0xe2, 0x28, 0x59, - 0x10, 0x5d, 0x68, 0x6d, - 0x40, 0x5b, 0x4e, 0x7d, + 0x00, 0xe2, 0x8e, 0x45, + 0x00, 0xe2, 0x32, 0x59, + 0x10, 0x5d, 0x80, 0x6d, + 0x40, 0x5b, 0x66, 0x7d, 0x02, 0x19, 0x32, 0x00, 0x80, 0xf9, 0xf2, 0x01, 0xff, 0xea, 0x10, 0x03, 0x08, 0xa8, 0x51, 0x03, - 0x00, 0xe2, 0x40, 0x45, - 0x80, 0xf9, 0x4e, 0x6d, + 0x00, 0xe2, 0x58, 0x45, + 0x80, 0xf9, 0x66, 0x6d, 0x01, 0x43, 0xc1, 0x31, - 0x00, 0xfb, 0x4e, 0x65, + 0x00, 0xfb, 0x66, 0x65, 0x01, 0x42, 0xc1, 0x31, - 0x00, 0xfa, 0x4e, 0x65, + 0x00, 0xfa, 0x66, 0x65, 0x01, 0xe8, 0xd4, 0x1d, 0x30, 0x3f, 0xc0, 0x09, - 0x30, 0xe0, 0x4e, 0x65, - 0x40, 0x4b, 0x4e, 0x6d, + 0x30, 0xe0, 0x66, 0x65, + 0x40, 0x4b, 0x66, 0x6d, 0xff, 0xea, 0x52, 0x01, - 0xee, 0x00, 0x9a, 0x6d, + 0xee, 0x00, 0xb2, 0x6d, 0x80, 0xf9, 0xf2, 0x01, 0x02, 0xea, 0xb4, 0x00, 0x20, 0xea, 0x9a, 0x00, - 0xf3, 0x42, 0xa4, 0x6d, - 0x12, 0xea, 0x3c, 0x59, + 0xf3, 0x42, 0xbc, 0x6d, + 0x12, 0xea, 0x46, 0x59, 0x12, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xdc, 0x41, - 0x0d, 0xea, 0x3c, 0x59, + 0x00, 0xe2, 0xee, 0x41, + 0x0d, 0xea, 0x46, 0x59, 0x0d, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0xdc, 0x41, - 0x11, 0xea, 0x3c, 0x59, + 0x00, 0xe2, 0xee, 0x41, + 0x11, 0xea, 0x46, 0x59, 0x11, 0xea, 0x04, 0x00, - 0x00, 0xe2, 0x12, 0x5b, + 0x00, 0xe2, 0x24, 0x5b, 0x08, 0x5a, 0xb4, 0x00, - 0x00, 0xe2, 0xcc, 0x5d, + 0x00, 0xe2, 0xe4, 0x5d, 0xa8, 0xea, 0x32, 0x00, - 0x00, 0xe2, 0x2a, 0x59, - 0x80, 0x1a, 0xbe, 0x7d, - 0x00, 0xe2, 0xcc, 0x5d, + 0x00, 0xe2, 0x34, 0x59, + 0x80, 0x1a, 0xd6, 0x7d, + 0x00, 0xe2, 0xe4, 0x5d, 0x80, 0x19, 0x32, 0x00, - 0x40, 0x5b, 0xc4, 0x6d, - 0x08, 0x5a, 0xc4, 0x7d, - 0x20, 0x4d, 0x4e, 0x7d, + 0x40, 0x5b, 0xdc, 0x6d, + 0x08, 0x5a, 0xdc, 0x7d, + 0x20, 0x4d, 0x66, 0x7d, 0x02, 0x84, 0x09, 0x03, - 0x40, 0x5b, 0x94, 0x7d, - 0x08, 0xa8, 0x39, 0x6d, + 0x40, 0x5b, 0xac, 0x7d, + 0x08, 0xa8, 0x51, 0x6d, 0x02, 0xea, 0xb4, 0x04, 0x01, 0x38, 0xe1, 0x30, 0x05, 0x39, 0xe3, 0x98, @@ -930,116 +942,122 @@ { ahd_patch0_func, 7, 1, 1 }, { ahd_patch2_func, 24, 1, 2 }, { ahd_patch0_func, 25, 1, 1 }, - { ahd_patch2_func, 35, 1, 2 }, - { ahd_patch0_func, 36, 1, 1 }, - { ahd_patch2_func, 39, 1, 2 }, - { ahd_patch0_func, 40, 1, 1 }, - { ahd_patch2_func, 43, 1, 2 }, - { ahd_patch0_func, 44, 1, 1 }, - { ahd_patch2_func, 46, 1, 2 }, - { ahd_patch0_func, 47, 1, 1 }, - { ahd_patch2_func, 50, 1, 2 }, - { ahd_patch0_func, 51, 1, 1 }, - { ahd_patch2_func, 54, 1, 2 }, - { ahd_patch0_func, 55, 1, 1 }, - { ahd_patch2_func, 152, 6, 1 }, - { ahd_patch1_func, 158, 2, 1 }, - { ahd_patch3_func, 160, 1, 1 }, - { ahd_patch2_func, 169, 1, 2 }, - { ahd_patch0_func, 170, 1, 1 }, - { ahd_patch4_func, 171, 2, 2 }, - { ahd_patch0_func, 173, 6, 3 }, - { ahd_patch2_func, 176, 1, 2 }, - { ahd_patch0_func, 177, 1, 1 }, - { ahd_patch2_func, 180, 1, 2 }, - { ahd_patch0_func, 181, 1, 1 }, - { ahd_patch5_func, 183, 2, 1 }, - { ahd_patch3_func, 191, 16, 2 }, - { ahd_patch0_func, 207, 1, 1 }, - { ahd_patch6_func, 227, 2, 1 }, - { ahd_patch5_func, 231, 2, 1 }, - { ahd_patch1_func, 245, 1, 2 }, - { ahd_patch0_func, 246, 1, 1 }, - { ahd_patch1_func, 249, 1, 2 }, - { ahd_patch0_func, 250, 1, 1 }, - { ahd_patch2_func, 253, 1, 2 }, - { ahd_patch0_func, 254, 1, 1 }, - { ahd_patch1_func, 309, 1, 2 }, - { ahd_patch0_func, 310, 1, 1 }, - { ahd_patch2_func, 318, 1, 2 }, + { ahd_patch1_func, 32, 1, 2 }, + { ahd_patch0_func, 33, 1, 1 }, + { ahd_patch2_func, 40, 1, 2 }, + { ahd_patch0_func, 41, 1, 1 }, + { ahd_patch2_func, 44, 1, 2 }, + { ahd_patch0_func, 45, 1, 1 }, + { ahd_patch2_func, 48, 1, 2 }, + { ahd_patch0_func, 49, 1, 1 }, + { ahd_patch2_func, 51, 1, 2 }, + { ahd_patch0_func, 52, 1, 1 }, + { ahd_patch2_func, 55, 1, 2 }, + { ahd_patch0_func, 56, 1, 1 }, + { ahd_patch2_func, 59, 1, 2 }, + { ahd_patch0_func, 60, 1, 1 }, + { ahd_patch2_func, 157, 6, 1 }, + { ahd_patch1_func, 163, 2, 1 }, + { ahd_patch3_func, 165, 1, 1 }, + { ahd_patch2_func, 174, 1, 2 }, + { ahd_patch0_func, 175, 1, 1 }, + { ahd_patch4_func, 176, 2, 2 }, + { ahd_patch0_func, 178, 6, 3 }, + { ahd_patch2_func, 181, 1, 2 }, + { ahd_patch0_func, 182, 1, 1 }, + { ahd_patch2_func, 185, 1, 2 }, + { ahd_patch0_func, 186, 1, 1 }, + { ahd_patch5_func, 188, 2, 1 }, + { ahd_patch3_func, 196, 16, 2 }, + { ahd_patch0_func, 212, 1, 1 }, + { ahd_patch6_func, 232, 2, 1 }, + { ahd_patch1_func, 236, 1, 2 }, + { ahd_patch0_func, 237, 1, 1 }, + { ahd_patch5_func, 240, 2, 1 }, + { ahd_patch1_func, 254, 1, 2 }, + { ahd_patch0_func, 255, 1, 1 }, + { ahd_patch1_func, 258, 1, 2 }, + { ahd_patch0_func, 259, 1, 1 }, + { ahd_patch2_func, 262, 1, 2 }, + { ahd_patch0_func, 263, 1, 1 }, + { ahd_patch1_func, 318, 1, 2 }, { ahd_patch0_func, 319, 1, 1 }, - { ahd_patch2_func, 322, 1, 2 }, - { ahd_patch0_func, 323, 1, 1 }, - { ahd_patch1_func, 330, 1, 2 }, - { ahd_patch0_func, 331, 1, 1 }, - { ahd_patch7_func, 350, 1, 1 }, - { ahd_patch7_func, 353, 1, 1 }, - { ahd_patch7_func, 355, 1, 1 }, - { ahd_patch7_func, 367, 1, 1 }, - { ahd_patch1_func, 377, 1, 2 }, - { ahd_patch0_func, 378, 1, 1 }, - { ahd_patch1_func, 380, 1, 2 }, - { ahd_patch0_func, 381, 1, 1 }, + { ahd_patch2_func, 327, 1, 2 }, + { ahd_patch0_func, 328, 1, 1 }, + { ahd_patch2_func, 331, 1, 2 }, + { ahd_patch0_func, 332, 1, 1 }, + { ahd_patch1_func, 339, 1, 2 }, + { ahd_patch0_func, 340, 1, 1 }, + { ahd_patch7_func, 359, 1, 1 }, + { ahd_patch7_func, 362, 1, 1 }, + { ahd_patch7_func, 364, 1, 1 }, + { ahd_patch7_func, 376, 1, 1 }, + { ahd_patch1_func, 386, 1, 2 }, + { ahd_patch0_func, 387, 1, 1 }, { ahd_patch1_func, 389, 1, 2 }, { ahd_patch0_func, 390, 1, 1 }, - { ahd_patch2_func, 401, 1, 2 }, - { ahd_patch0_func, 402, 1, 1 }, - { ahd_patch8_func, 404, 1, 1 }, - { ahd_patch9_func, 431, 1, 1 }, - { ahd_patch1_func, 438, 1, 2 }, - { ahd_patch0_func, 439, 1, 1 }, - { ahd_patch2_func, 451, 1, 2 }, - { ahd_patch0_func, 452, 1, 1 }, - { ahd_patch10_func, 480, 1, 1 }, - { ahd_patch11_func, 489, 1, 2 }, - { ahd_patch0_func, 490, 1, 1 }, - { ahd_patch12_func, 495, 1, 1 }, - { ahd_patch11_func, 496, 1, 1 }, - { ahd_patch13_func, 509, 1, 2 }, - { ahd_patch0_func, 510, 1, 1 }, - { ahd_patch1_func, 532, 1, 2 }, - { ahd_patch0_func, 533, 1, 1 }, - { ahd_patch1_func, 536, 1, 2 }, - { ahd_patch0_func, 537, 1, 1 }, - { ahd_patch2_func, 542, 1, 2 }, - { ahd_patch0_func, 543, 1, 1 }, - { ahd_patch2_func, 547, 1, 2 }, - { ahd_patch0_func, 548, 1, 1 }, - { ahd_patch1_func, 549, 1, 2 }, - { ahd_patch0_func, 550, 1, 1 }, - { ahd_patch2_func, 561, 1, 2 }, - { ahd_patch0_func, 562, 1, 1 }, - { ahd_patch14_func, 566, 1, 1 }, - { ahd_patch15_func, 571, 1, 1 }, - { ahd_patch16_func, 572, 2, 1 }, - { ahd_patch15_func, 576, 1, 2 }, - { ahd_patch0_func, 577, 1, 1 }, - { ahd_patch2_func, 584, 1, 2 }, - { ahd_patch0_func, 585, 1, 1 }, - { ahd_patch2_func, 600, 1, 2 }, - { ahd_patch0_func, 601, 1, 1 }, - { ahd_patch1_func, 607, 1, 2 }, - { ahd_patch0_func, 608, 1, 1 }, - { ahd_patch1_func, 622, 1, 2 }, - { ahd_patch0_func, 623, 1, 1 }, - { ahd_patch14_func, 647, 1, 1 }, - { ahd_patch14_func, 663, 1, 1 }, - { ahd_patch2_func, 675, 1, 2 }, - { ahd_patch0_func, 676, 1, 1 }, - { ahd_patch1_func, 693, 1, 2 }, - { ahd_patch0_func, 694, 1, 1 }, - { ahd_patch14_func, 699, 1, 1 }, - { ahd_patch1_func, 719, 1, 2 }, - { ahd_patch0_func, 720, 1, 1 }, - { ahd_patch1_func, 722, 1, 2 }, - { ahd_patch0_func, 723, 1, 1 }, - { ahd_patch1_func, 725, 1, 2 }, - { ahd_patch0_func, 726, 1, 1 }, - { ahd_patch17_func, 728, 1, 2 }, - { ahd_patch0_func, 729, 2, 1 }, - { ahd_patch18_func, 732, 4, 2 }, - { ahd_patch0_func, 736, 1, 1 }, - { ahd_patch18_func, 742, 11, 1 } + { ahd_patch1_func, 398, 1, 2 }, + { ahd_patch0_func, 399, 1, 1 }, + { ahd_patch2_func, 410, 1, 2 }, + { ahd_patch0_func, 411, 1, 1 }, + { ahd_patch8_func, 413, 1, 1 }, + { ahd_patch9_func, 440, 1, 1 }, + { ahd_patch1_func, 447, 1, 2 }, + { ahd_patch0_func, 448, 1, 1 }, + { ahd_patch2_func, 460, 1, 2 }, + { ahd_patch0_func, 461, 1, 1 }, + { ahd_patch10_func, 489, 1, 1 }, + { ahd_patch11_func, 498, 1, 2 }, + { ahd_patch0_func, 499, 1, 1 }, + { ahd_patch12_func, 504, 1, 1 }, + { ahd_patch11_func, 505, 1, 1 }, + { ahd_patch13_func, 518, 1, 2 }, + { ahd_patch0_func, 519, 1, 1 }, + { ahd_patch1_func, 541, 1, 2 }, + { ahd_patch0_func, 542, 1, 1 }, + { ahd_patch1_func, 545, 1, 2 }, + { ahd_patch0_func, 546, 1, 1 }, + { ahd_patch2_func, 551, 1, 2 }, + { ahd_patch0_func, 552, 1, 1 }, + { ahd_patch2_func, 556, 1, 2 }, + { ahd_patch0_func, 557, 1, 1 }, + { ahd_patch1_func, 558, 1, 2 }, + { ahd_patch0_func, 559, 1, 1 }, + { ahd_patch2_func, 570, 1, 2 }, + { ahd_patch0_func, 571, 1, 1 }, + { ahd_patch14_func, 575, 1, 1 }, + { ahd_patch15_func, 580, 1, 1 }, + { ahd_patch16_func, 581, 2, 1 }, + { ahd_patch15_func, 585, 1, 2 }, + { ahd_patch0_func, 586, 1, 1 }, + { ahd_patch2_func, 593, 1, 2 }, + { ahd_patch0_func, 594, 1, 1 }, + { ahd_patch2_func, 609, 1, 2 }, + { ahd_patch0_func, 610, 1, 1 }, + { ahd_patch1_func, 616, 1, 2 }, + { ahd_patch0_func, 617, 1, 1 }, + { ahd_patch1_func, 631, 1, 2 }, + { ahd_patch0_func, 632, 1, 1 }, + { ahd_patch1_func, 639, 1, 2 }, + { ahd_patch0_func, 640, 1, 1 }, + { ahd_patch14_func, 659, 1, 1 }, + { ahd_patch14_func, 675, 1, 1 }, + { ahd_patch2_func, 687, 1, 2 }, + { ahd_patch0_func, 688, 1, 1 }, + { ahd_patch1_func, 705, 1, 2 }, + { ahd_patch0_func, 706, 1, 1 }, + { ahd_patch14_func, 711, 1, 1 }, + { ahd_patch1_func, 731, 1, 2 }, + { ahd_patch0_func, 732, 1, 1 }, + { ahd_patch1_func, 734, 1, 2 }, + { ahd_patch0_func, 735, 1, 1 }, + { ahd_patch1_func, 737, 1, 2 }, + { ahd_patch0_func, 738, 1, 1 }, + { ahd_patch17_func, 740, 1, 2 }, + { ahd_patch0_func, 741, 2, 1 }, + { ahd_patch18_func, 744, 4, 2 }, + { ahd_patch0_func, 748, 1, 1 }, + { ahd_patch18_func, 754, 11, 1 } }; static struct cs { @@ -1048,19 +1066,19 @@ } critical_sections[] = { { 11, 12 }, { 13, 14 }, - { 24, 32 }, - { 33, 46 }, - { 59, 62 }, - { 89, 114 }, - { 115, 146 }, - { 148, 152 }, - { 160, 168 }, - { 191, 224 }, - { 647, 663 }, - { 663, 681 }, - { 686, 692 }, - { 699, 704 }, - { 704, 710 } + { 24, 37 }, + { 38, 51 }, + { 64, 67 }, + { 94, 119 }, + { 120, 151 }, + { 153, 157 }, + { 165, 173 }, + { 196, 245 }, + { 659, 675 }, + { 675, 693 }, + { 698, 704 }, + { 711, 716 }, + { 716, 722 } }; static const int num_critical_sections = sizeof(critical_sections) diff -Nru a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h --- a/drivers/scsi/aic7xxx/aic7xxx.h Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx.h Sun Feb 9 21:13:32 2003 @@ -37,7 +37,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#67 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#70 $ * * $FreeBSD$ */ @@ -318,11 +318,11 @@ */ typedef enum { AHC_FNONE = 0x000, - AHC_PRIMARY_CHANNEL = 0x003,/* + AHC_PRIMARY_CHANNEL = 0x003, /* * The channel that should * be probed first. */ - AHC_USEDEFAULTS = 0x004,/* + AHC_USEDEFAULTS = 0x004, /* * For cards without an seeprom * or a BIOS to initialize the chip's * SRAM, we use the default target @@ -330,29 +330,29 @@ */ AHC_SEQUENCER_DEBUG = 0x008, AHC_SHARED_SRAM = 0x010, - AHC_LARGE_SEEPROM = 0x020,/* Uses C56_66 not C46 */ + AHC_LARGE_SEEPROM = 0x020, /* Uses C56_66 not C46 */ AHC_RESET_BUS_A = 0x040, AHC_RESET_BUS_B = 0x080, AHC_EXTENDED_TRANS_A = 0x100, AHC_EXTENDED_TRANS_B = 0x200, AHC_TERM_ENB_A = 0x400, AHC_TERM_ENB_B = 0x800, - AHC_INITIATORROLE = 0x1000,/* + AHC_INITIATORROLE = 0x1000, /* * Allow initiator operations on * this controller. */ - AHC_TARGETROLE = 0x2000,/* + AHC_TARGETROLE = 0x2000, /* * Allow target operations on this * controller. */ AHC_NEWEEPROM_FMT = 0x4000, AHC_RESOURCE_SHORTAGE = 0x8000, - AHC_TQINFIFO_BLOCKED = 0x10000,/* Blocked waiting for ATIOs */ - AHC_INT50_SPEEDFLEX = 0x20000,/* + AHC_TQINFIFO_BLOCKED = 0x10000, /* Blocked waiting for ATIOs */ + AHC_INT50_SPEEDFLEX = 0x20000, /* * Internal 50pin connector * sits behind an aic3860 */ - AHC_SCB_BTT = 0x40000,/* + AHC_SCB_BTT = 0x40000, /* * The busy targets table is * stored in SCB space rather * than SRAM. @@ -363,7 +363,9 @@ AHC_EDGE_INTERRUPT = 0x800000, /* Device uses edge triggered ints */ AHC_39BIT_ADDRESSING = 0x1000000, /* Use 39 bit addressing scheme. */ AHC_LSCBS_ENABLED = 0x2000000, /* 64Byte SCBs enabled */ - AHC_SCB_CONFIG_USED = 0x4000000 /* No SEEPROM but SCB2 had info. */ + AHC_SCB_CONFIG_USED = 0x4000000, /* No SEEPROM but SCB2 had info. */ + AHC_NO_BIOS_INIT = 0x8000000, /* No BIOS left over settings. */ + AHC_DISABLE_PCI_PERR = 0x10000000 } ahc_flag; /************************* Hardware SCB Definition ***************************/ @@ -758,6 +760,7 @@ #define AHC_SYNCRATE_ULTRA 3 #define AHC_SYNCRATE_FAST 6 #define AHC_SYNCRATE_MAX AHC_SYNCRATE_DT +#define AHC_SYNCRATE_MIN 13 /***************************** Lookup Tables **********************************/ /* diff -Nru a/drivers/scsi/aic7xxx/aic7xxx.seq b/drivers/scsi/aic7xxx/aic7xxx.seq --- a/drivers/scsi/aic7xxx/aic7xxx.seq Sun Feb 9 21:13:35 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx.seq Sun Feb 9 21:13:35 2003 @@ -40,7 +40,7 @@ * $FreeBSD$ */ -VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 $" +VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $" PATCH_ARG_LIST = "struct ahc_softc *ahc" PREFIX = "ahc_" @@ -193,7 +193,7 @@ * Setup the DMA for sending the identify and * command information. */ - or SEQ_FLAGS, CMDPHASE_PENDING; + mvi SEQ_FLAGS, CMDPHASE_PENDING; mov A, TQINPOS; if ((ahc->features & AHC_CMD_CHAN) != 0) { @@ -306,7 +306,7 @@ } else { mvi DFDAT, SCB_LIST_NULL; } - mvi SEQ_FLAGS, TARG_CMD_PENDING; + or SEQ_FLAGS, TARG_CMD_PENDING; test SEQ_FLAGS2, TARGET_MSG_PENDING jnz target_mesgout_pending; test SCSISIGI, ATNI jnz target_mesgout_continue; @@ -512,6 +512,7 @@ target_mesgout_continue: call target_inb; target_mesgout_pending: + and SEQ_FLAGS2, ~TARGET_MSG_PENDING; /* Local Processing goes here... */ jmp host_target_message_loop; diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c --- a/drivers/scsi/aic7xxx/aic7xxx_core.c Sun Feb 9 21:13:31 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c Sun Feb 9 21:13:31 2003 @@ -37,7 +37,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#108 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#112 $ * * $FreeBSD$ */ @@ -1844,8 +1844,9 @@ * occurs the need to renegotiate is * recorded persistently. */ + if ((ahc->features & AHC_WIDE) != 0) + tinfo->curr.width = AHC_WIDTH_UNKNOWN; tinfo->curr.period = AHC_PERIOD_UNKNOWN; - tinfo->curr.width = AHC_WIDTH_UNKNOWN; tinfo->curr.offset = AHC_OFFSET_UNKNOWN; } if (tinfo->curr.period != tinfo->goal.period @@ -3443,7 +3444,7 @@ * but rejected our response, we already cleared the * sync rate before sending our WDTR. */ - if (tinfo->goal.offset) { + if (tinfo->goal.offset != tinfo->curr.offset) { /* Start the sync negotiation */ ahc->msgout_index = 0; @@ -4045,6 +4046,14 @@ * to disturb the integrity of the bus. */ ahc_pause(ahc); + if ((ahc_inb(ahc, HCNTRL) & CHIPRST) != 0) { + /* + * The chip has not been initialized since + * PCI/EISA/VLB bus reset. Don't trust + * "left over BIOS data". + */ + ahc->flags |= AHC_NO_BIOS_INIT; + } sxfrctl1_b = 0; if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) { u_int sblkctl; @@ -4539,8 +4548,9 @@ size_t driver_data_size; uint32_t physaddr; -#ifdef AHC_DEBUG_SEQUENCER - ahc->flags |= AHC_SEQUENCER_DEBUG; +#ifdef AHC_DEBUG + if ((ahc_debug & AHC_DEBUG_SEQUENCER) != 0) + ahc->flags |= AHC_SEQUENCER_DEBUG; #endif #ifdef AHC_PRINT_SRAM @@ -4875,7 +4885,7 @@ tinfo->curr.protocol_version = 2; tinfo->curr.transport_version = 2; } - tstate->ultraenb = ultraenb; + tstate->ultraenb = 0; } ahc->user_discenable = discenable; ahc->user_tagenable = tagenable; @@ -6483,8 +6493,11 @@ ahc_outb(ahc, SEQCTL, PERRORDIS|FAILDIS|FASTMODE); ahc_restart(ahc); - if (bootverbose) + if (bootverbose) { printf(" %d instructions downloaded\n", downloaded); + printf("%s: Features 0x%x, Bugs 0x%x, Flags 0x%x\n", + ahc_name(ahc), ahc->features, ahc->bugs, ahc->flags); + } } static int @@ -6702,6 +6715,7 @@ struct scb *scb; struct scb_tailq *untagged_q; u_int cur_col; + int paused; int target; int maxtarget; int i; @@ -6712,12 +6726,21 @@ uint8_t scb_index; uint8_t saved_scbptr; - saved_scbptr = ahc_inb(ahc, SCBPTR); + if (ahc_is_paused(ahc)) { + paused = 1; + } else { + paused = 0; + ahc_pause(ahc); + } + saved_scbptr = ahc_inb(ahc, SCBPTR); last_phase = ahc_inb(ahc, LASTPHASE); - printf("%s: Dumping Card State %s, at SEQADDR 0x%x\n", + printf(">>>>>>>>>>>>>>>>>> Dump Card State Begins <<<<<<<<<<<<<<<<<\n" + "%s: Dumping Card State %s, at SEQADDR 0x%x\n", ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg, ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); + if (paused) + printf("Card was paused\n"); printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n", ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX), ahc_inb(ahc, ARG_2)); @@ -6725,13 +6748,14 @@ ahc_inb(ahc, SCBPTR)); cur_col = 0; if ((ahc->features & AHC_DT) != 0) - ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50); + ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50); + ahc_scsisigi_print(ahc_inb(ahc, SCSISIGI), &cur_col, 50); ahc_error_print(ahc_inb(ahc, ERROR), &cur_col, 50); - ahc_scsiphase_print(ahc_inb(ahc, SCSIPHASE), &cur_col, 50); ahc_scsibusl_print(ahc_inb(ahc, SCSIBUSL), &cur_col, 50); ahc_lastphase_print(ahc_inb(ahc, LASTPHASE), &cur_col, 50); ahc_scsiseq_print(ahc_inb(ahc, SCSISEQ), &cur_col, 50); ahc_sblkctl_print(ahc_inb(ahc, SBLKCTL), &cur_col, 50); + ahc_scsirate_print(ahc_inb(ahc, SCSIRATE), &cur_col, 50); ahc_seqctl_print(ahc_inb(ahc, SEQCTL), &cur_col, 50); ahc_seq_flags_print(ahc_inb(ahc, SEQ_FLAGS), &cur_col, 50); ahc_sstat0_print(ahc_inb(ahc, SSTAT0), &cur_col, 50); @@ -6862,7 +6886,10 @@ } ahc_platform_dump_card_state(ahc); + printf("\n<<<<<<<<<<<<<<<<< Dump Card State Ends >>>>>>>>>>>>>>>>>>\n"); ahc_outb(ahc, SCBPTR, saved_scbptr); + if (paused == 0) + ahc_unpause(ahc); } /************************* Target Mode ****************************************/ diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_inline.h b/drivers/scsi/aic7xxx/aic7xxx_inline.h --- a/drivers/scsi/aic7xxx/aic7xxx_inline.h Sun Feb 9 21:13:37 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_inline.h Sun Feb 9 21:13:37 2003 @@ -460,7 +460,7 @@ ahc->qinfifo[ahc->qinfifonext++] = scb->hscb->tag; /* - * Make sure our data is consistant from the + * Make sure our data is consistent from the * perspective of the adapter. */ ahc_sync_scb(ahc, scb, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c Sun Feb 9 21:13:28 2003 @@ -1,7 +1,7 @@ /* * Adaptec AIC7xxx device driver for Linux. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#169 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#179 $ * * Copyright (c) 1994 John Aycock * The University of Calgary Department of Computer Science. @@ -119,12 +119,6 @@ * */ -/* - * This is the only file where module.h should - * embed module global version info. - */ -#define AHC_MODVERSION_FILE - #include "aic7xxx_osm.h" #include "aic7xxx_inline.h" #include @@ -524,8 +518,6 @@ struct scsi_cmnd *cmd, struct ahc_devinfo *devinfo, struct ahc_linux_target *targ); -static uint32_t aic_dv_error_action(struct scsi_cmnd *cmd, - struct scsi_inquiry_data *inq_data); static void ahc_linux_dv_fill_cmd(struct ahc_softc *ahc, struct scsi_cmnd *cmd, struct ahc_devinfo *devinfo); @@ -976,7 +968,7 @@ struct ahc_linux_device *dev; u_long flags; - ahc = *(struct ahc_softc **)cmd->host->hostdata; + ahc = *(struct ahc_softc **)cmd->device->host->hostdata; /* * Save the callback on completion function. @@ -1000,8 +992,8 @@ ahc_midlayer_entrypoint_unlock(ahc, &flags); return (0); } - dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target, - cmd->lun, /*alloc*/TRUE); + dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, + cmd->device->lun, /*alloc*/TRUE); if (dev == NULL) { ahc_midlayer_entrypoint_unlock(ahc, &flags); printf("aic7xxx_linux_queue: Unable to allocate device!\n"); @@ -1245,12 +1237,12 @@ u_long s; int found; - ahc = *(struct ahc_softc **)cmd->host->hostdata; + ahc = *(struct ahc_softc **)cmd->device->host->hostdata; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) spin_unlock_irq(&io_request_lock); #endif ahc_midlayer_entrypoint_lock(ahc, &s); - found = ahc_reset_channel(ahc, cmd->channel + 'A', + found = ahc_reset_channel(ahc, cmd->device->channel + 'A', /*initiate reset*/TRUE); acmd = TAILQ_FIRST(&ahc->platform_data->completeq); TAILQ_INIT(&ahc->platform_data->completeq); @@ -1374,10 +1366,10 @@ } /******************************** Macros **************************************/ -#define BUILD_SCSIID(ahc, cmd) \ - ((((cmd)->target << TID_SHIFT) & TID) \ - | (((cmd)->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \ - | (((cmd)->channel == 0) ? 0 : TWIN_CHNLB)) +#define BUILD_SCSIID(ahc, cmd) \ + ((((cmd)->device->id << TID_SHIFT) & TID) \ + | (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \ + | (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB)) /******************************** Bus DMA *************************************/ int @@ -2045,6 +2037,9 @@ #endif ahc->seltime = (aic7xxx_seltime & 0x3) << 4; ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; + if (aic7xxx_pci_parity == 0) + ahc->flags |= AHC_DISABLE_PCI_PERR; + if (TAILQ_EMPTY(&ahc_tailq)) register_reboot_notifier(&ahc_linux_notifier); return (0); @@ -2053,7 +2048,10 @@ void ahc_platform_free(struct ahc_softc *ahc) { + struct ahc_linux_target *targ; + struct ahc_linux_device *dev; u_long s; + int i, j; if (ahc->platform_data != NULL) { /* Kill the DV kthread */ @@ -2077,6 +2075,23 @@ #endif if (ahc->platform_data->host != NULL) scsi_unregister(ahc->platform_data->host); + + /* destroy all of the device and target objects */ + for (i = 0; i < AHC_NUM_TARGETS; i++) { + targ = ahc->platform_data->targets[i]; + if (targ != NULL) { + for (j = 0; j < AHC_NUM_LUNS; j++) { + if (targ->devices[j] != NULL) { + dev = targ->devices[j]; + ahc_linux_free_device(ahc, dev); + } + if (ahc->platform_data->targets[i] == + NULL) + break; + } + } + } + if (ahc->platform_data->irq != AHC_LINUX_NOIRQ) free_irq(ahc->platform_data->irq, ahc); if (ahc->tag == BUS_SPACE_PIO @@ -2446,6 +2461,7 @@ struct ahc_devinfo devinfo; struct ahc_linux_target *targ; struct scsi_cmnd *cmd; + struct scsi_device *scsi_dev; struct scsi_sense_data *sense; uint8_t *buffer; u_long s; @@ -2473,6 +2489,12 @@ ahc_unlock(ahc, &s); cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK); + scsi_dev = malloc(sizeof(struct scsi_device), M_DEVBUF, M_WAITOK); + scsi_dev->host = ahc->platform_data->host; + scsi_dev->id = devinfo.target; + scsi_dev->lun = devinfo.lun; + scsi_dev->channel = devinfo.channel - 'A'; + ahc->platform_data->dv_scsi_dev = scsi_dev; AHC_SET_DV_STATE(ahc, targ, AHC_DV_STATE_INQ_SHORT_ASYNC); @@ -2597,6 +2619,11 @@ if (cmd != NULL) free(cmd, M_DEVBUF); + if (ahc->platform_data->dv_scsi_dev != NULL) { + free(ahc->platform_data->dv_scsi_dev, M_DEVBUF); + ahc->platform_data->dv_scsi_dev = NULL; + } + ahc_lock(ahc, &s); if (targ->dv_buffer != NULL) free(targ->dv_buffer, M_DEVBUF); @@ -2613,9 +2640,13 @@ struct ahc_devinfo *devinfo, struct ahc_linux_target *targ) { + cam_status cam_status; u_int32_t status; + u_int scsi_status; - status = aic_dv_error_action(cmd, targ->inq_data); + scsi_status = ahc_cmd_get_scsi_status(cmd); + cam_status = ahc_cmd_get_transaction_status(cmd); + status = aic_error_action(cmd, targ->inq_data, cam_status, scsi_status); #ifdef AHC_DEBUG @@ -2666,6 +2697,7 @@ switch (status & SS_MASK) { case SS_NOP: { + u_int xportflags; u_int spi3data; if (memcmp(targ->inq_data, targ->dv_buffer, @@ -2684,6 +2716,10 @@ if (ahc_linux_user_dv_setting(ahc) == 0) break; + xportflags = targ->inq_data->flags; + if ((xportflags & (SID_Sync|SID_WBus16)) == 0) + break; + spi3data = targ->inq_data->spi3data; switch (spi3data & SID_SPI_CLOCK_DT_ST) { default: @@ -3077,104 +3113,13 @@ } } -static uint32_t -aic_dv_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data) -{ - aic_sense_action err_action; - cam_status status; - u_int scsi_status; - int sense; - - status = ahc_cmd_get_transaction_status(cmd); - scsi_status = ahc_cmd_get_scsi_status(cmd); - sense = (cmd->result >> 24) == DRIVER_SENSE; - - switch (status) { - case CAM_REQ_CMP: - err_action = SS_NOP; - break; - case CAM_AUTOSENSE_FAIL: - case CAM_SCSI_STATUS_ERROR: - - switch (scsi_status) { - case SCSI_STATUS_OK: - case SCSI_STATUS_COND_MET: - case SCSI_STATUS_INTERMED: - case SCSI_STATUS_INTERMED_COND_MET: - err_action = SS_NOP; - break; - case SCSI_STATUS_CMD_TERMINATED: - case SCSI_STATUS_CHECK_COND: - if (sense != 0) { - struct scsi_sense_data *sense; - - sense = (struct scsi_sense_data *) - &cmd->sense_buffer; - err_action = - aic_sense_error_action(sense, inq_data, 0); - - } else { - err_action = SS_RETRY|SSQ_FALLBACK - | SSQ_DECREMENT_COUNT|EIO; - } - break; - case SCSI_STATUS_QUEUE_FULL: - case SCSI_STATUS_BUSY: - err_action = SS_RETRY|SSQ_DELAY|SSQ_MANY - | SSQ_DECREMENT_COUNT|EBUSY; - break; - case SCSI_STATUS_RESERV_CONFLICT: - default: - err_action = SS_FAIL|EBUSY; - break; - } - break; - case CAM_REQ_CMP_ERR: - case CAM_CMD_TIMEOUT: - case CAM_UNEXP_BUSFREE: - case CAM_UNCOR_PARITY: - case CAM_DATA_RUN_ERR: - err_action = SS_RETRY|SSQ_FALLBACK|EIO; - break; - case CAM_UA_ABORT: - case CAM_UA_TERMIO: - case CAM_MSG_REJECT_REC: - case CAM_SEL_TIMEOUT: - err_action = SS_FAIL|EIO; - break; - case CAM_REQ_INVALID: - case CAM_PATH_INVALID: - case CAM_DEV_NOT_THERE: - case CAM_NO_HBA: - case CAM_PROVIDE_FAIL: - case CAM_REQ_TOO_BIG: - case CAM_RESRC_UNAVAIL: - case CAM_BUSY: - default: - /* panic?? These should never occur in our application. */ - err_action = SS_FAIL|EIO; - break; - case CAM_SCSI_BUS_RESET: - case CAM_BDR_SENT: - case CAM_REQUEUE_REQ: - /* Unconditional requeue */ - err_action = SS_RETRY; - break; - } - - return (err_action); -} - static void ahc_linux_dv_fill_cmd(struct ahc_softc *ahc, struct scsi_cmnd *cmd, struct ahc_devinfo *devinfo) { memset(cmd, 0, sizeof(struct scsi_cmnd)); - cmd->host = ahc->platform_data->host; + cmd->device = ahc->platform_data->dv_scsi_dev; cmd->scsi_done = ahc_linux_dv_complete; - cmd->target = devinfo->target; - cmd->lun = devinfo->lun; - cmd->channel = devinfo->channel - 'A'; } /* @@ -3327,23 +3272,6 @@ cmd->cmnd[4] = le | SSS_START; } -/* - * Return speed in KB/s. - */ -static u_int -ahc_linux_calc_speed(u_int width, u_int period, u_int offset) -{ - u_int freq; - - if (offset != 0) - freq = aic_calc_syncsrate(period); - else - /* Roughly 3.3MB/s for async */ - freq = 3300; - freq <<= width; - return (freq); -} - static int ahc_linux_fallback(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) { @@ -3391,14 +3319,17 @@ if (targ->dv_last_ppr_options == 0) targ->dv_last_ppr_options = ppr_options; - cur_speed = ahc_linux_calc_speed(width, period, offset); - wide_speed = ahc_linux_calc_speed(MSG_EXT_WDTR_BUS_16_BIT, + cur_speed = aic_calc_speed(width, period, offset, AHC_SYNCRATE_MIN); + wide_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_16_BIT, targ->dv_next_wide_period, - MAX_OFFSET); - narrow_speed = ahc_linux_calc_speed(MSG_EXT_WDTR_BUS_8_BIT, + MAX_OFFSET, + AHC_SYNCRATE_MIN); + narrow_speed = aic_calc_speed(MSG_EXT_WDTR_BUS_8_BIT, targ->dv_next_narrow_period, - MAX_OFFSET); - fallback_speed = ahc_linux_calc_speed(width, period+1, offset); + MAX_OFFSET, + AHC_SYNCRATE_MIN); + fallback_speed = aic_calc_speed(width, period+1, offset, + AHC_SYNCRATE_MIN); #ifdef AHC_DEBUG if (ahc_debug & AHC_SHOW_DV) { printf("cur_speed= %d, wide_speed= %d, narrow_speed= %d, " @@ -3532,13 +3463,15 @@ struct scb *scb; u_long flags; - ahc = *((struct ahc_softc **)cmd->host->hostdata); + ahc = *((struct ahc_softc **)cmd->device->host->hostdata); ahc_lock(ahc, &flags); #ifdef AHC_DEBUG - if (ahc_debug & AHC_SHOW_DV) + if (ahc_debug & AHC_SHOW_DV) { printf("%s: Timeout while doing DV command %x.\n", ahc_name(ahc), cmd->cmnd[0]); + ahc_dump_card_state(ahc); + } #endif /* @@ -3560,7 +3493,7 @@ ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL); else ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT); - ahc_reset_channel(ahc, cmd->channel + 'A', /*initiate*/TRUE); + ahc_reset_channel(ahc, cmd->device->channel + 'A', /*initiate*/TRUE); /* * Add a minimal bus settle delay for devices that are slow to @@ -3610,7 +3543,7 @@ { struct ahc_softc *ahc; - ahc = *((struct ahc_softc **)cmd->host->hostdata); + ahc = *((struct ahc_softc **)cmd->device->host->hostdata); /* Delete the DV timer before it goes off! */ scsi_delete_timer(cmd); @@ -3618,7 +3551,8 @@ #ifdef AHC_DEBUG if (ahc_debug & AHC_SHOW_DV) printf("%s:%d:%d: Command completed, status= 0x%x\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->result); + ahc_name(ahc), cmd->device->channel, + cmd->device->id, cmd->result); #endif /* Wake up the state machine */ @@ -3834,7 +3768,7 @@ */ hscb->control = 0; hscb->scsiid = BUILD_SCSIID(ahc, cmd); - hscb->lun = cmd->lun; + hscb->lun = cmd->device->lun; mask = SCB_GET_TARGET_MASK(ahc, scb); tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb), SCB_GET_OUR_ID(scb), @@ -4245,7 +4179,34 @@ break; } case AC_SENT_BDR: + { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + Scsi_Device *scsi_dev; + + /* + * Find the SCSI device associated with this + * request and indicate that a UA is expected. + * XXX This should really be handled by the mid-layer. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + list_for_each_entry(scsi_dev, + &ahc->platform_data->host->my_devices, + siblings) { +#else + for (scsi_dev = ahc->platform_data->host->host_queue; + scsi_dev != NULL; scsi_dev = scsi_dev->next) { +#endif + if (channel - 'A' == scsi_dev->channel + && target == scsi_dev->id + && (lun == CAM_LUN_WILDCARD + || lun == scsi_dev->lun)) { + scsi_dev->was_reset = 1; + scsi_dev->expecting_cc_ua = 1; + } + } +#endif break; + } case AC_BUS_RESET: #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) if (ahc->platform_data->host != NULL) { @@ -4371,8 +4332,8 @@ if (ahc_get_transaction_status(scb) == CAM_BDR_SENT || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED) ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT); - if ((scb->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) { - scb->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE; + if ((ahc->platform_data->flags & AHC_UP_EH_SEMAPHORE) != 0) { + ahc->platform_data->flags &= ~AHC_UP_EH_SEMAPHORE; up(&ahc->platform_data->eh_sem); } } @@ -4441,8 +4402,11 @@ printf("Copied %d bytes of sense data:", sense_size); - for (i = 0; i < sense_size; i++) - printf(" 0x%x", cmd->sense_buffer[i]); + for (i = 0; i < sense_size; i++) { + if ((i & 0xF) == 0) + printf("\n"); + printf("0x%x ", cmd->sense_buffer[i]); + } printf("\n"); } #endif @@ -4616,7 +4580,8 @@ * evoke a retry even if this command is being sent * via the eh thread. Ick! Ick! Ick! */ - cmd->retries--; + if (cmd->retries > 0) + cmd->retries--; new_status = DID_OK; ahc_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND); cmd->result |= (DRIVER_SENSE << 24); @@ -4851,6 +4816,7 @@ u_int saved_scbptr; u_int active_scb_index; u_int last_phase; + u_int saved_scsiid; int retval; int paused; int wait; @@ -4859,11 +4825,12 @@ pending_scb = NULL; paused = FALSE; wait = FALSE; - ahc = *(struct ahc_softc **)cmd->host->hostdata; + ahc = *(struct ahc_softc **)cmd->device->host->hostdata; acmd = (struct ahc_cmd *)cmd; printf("%s:%d:%d:%d: Attempting to queue a%s message\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun, + ahc_name(ahc), cmd->device->channel, + cmd->device->id, cmd->device->lun, flag == SCB_ABORT ? "n ABORT" : " TARGET RESET"); /* @@ -4892,8 +4859,8 @@ * at all, and the system wanted us to just abort the * command return success. */ - dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target, - cmd->lun, /*alloc*/FALSE); + dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, + cmd->device->lun, /*alloc*/FALSE); if (dev == NULL) { /* @@ -4901,7 +4868,8 @@ * so we must not still own the command. */ printf("%s:%d:%d:%d: Is not an active device\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); retval = SUCCESS; goto no_cmd; } @@ -4913,7 +4881,8 @@ if (list_acmd != NULL) { printf("%s:%d:%d:%d: Command found on device queue\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); if (flag == SCB_ABORT) { TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); cmd->result = DID_ABORT << 16; @@ -4924,11 +4893,13 @@ } if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0 - && ahc_search_untagged_queues(ahc, cmd, cmd->target, - cmd->channel + 'A', cmd->lun, + && ahc_search_untagged_queues(ahc, cmd, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) { printf("%s:%d:%d:%d: Command found on untagged queue\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); retval = SUCCESS; goto done; } @@ -4945,8 +4916,9 @@ /* Any SCB for this device will do for a target reset */ LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) { - if (ahc_match_scb(ahc, pending_scb, cmd->target, - cmd->channel + 'A', CAM_LUN_WILDCARD, + if (ahc_match_scb(ahc, pending_scb, cmd->device->id, + cmd->device->channel + 'A', + CAM_LUN_WILDCARD, SCB_LIST_NULL, ROLE_INITIATOR) == 0) break; } @@ -4954,7 +4926,8 @@ if (pending_scb == NULL) { printf("%s:%d:%d:%d: Command not found\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); goto no_cmd; } @@ -4978,24 +4951,28 @@ if ((pending_scb->flags & SCB_ACTIVE) == 0) { printf("%s:%d:%d:%d: Command already completed\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); goto no_cmd; } disconnected = TRUE; if (flag == SCB_ABORT) { - if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, pending_scb->hscb->tag, + if (ahc_search_qinfifo(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, + pending_scb->hscb->tag, ROLE_INITIATOR, CAM_REQ_ABORTED, SEARCH_COMPLETE) > 0) { printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n", - ahc_name(ahc), cmd->channel, cmd->target, - cmd->lun); + ahc_name(ahc), cmd->device->channel, + cmd->device->id, cmd->device->lun); retval = SUCCESS; goto done; } - } else if (ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, pending_scb->hscb->tag, + } else if (ahc_search_qinfifo(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, pending_scb->hscb->tag, ROLE_INITIATOR, /*status*/0, SEARCH_COUNT) > 0) { disconnected = FALSE; @@ -5024,10 +5001,11 @@ last_phase = ahc_inb(ahc, LASTPHASE); saved_scbptr = ahc_inb(ahc, SCBPTR); active_scb_index = ahc_inb(ahc, SCB_TAG); + saved_scsiid = ahc_inb(ahc, SAVED_SCSIID); if (last_phase != P_BUSFREE && (pending_scb->hscb->tag == active_scb_index || (flag == SCB_DEVICE_RESET - && SCSIID_TARGET(ahc, ahc_inb(ahc, SAVED_SCSIID)) == cmd->target))) { + && SCSIID_TARGET(ahc, saved_scsiid) == cmd->device->id))) { /* * We're active on the bus, so assert ATN @@ -5038,7 +5016,8 @@ ahc_outb(ahc, MSG_OUT, HOST_MSG); ahc_outb(ahc, SCSISIGO, last_phase|ATNO); printf("%s:%d:%d:%d: Device is active, asserting ATN\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); wait = TRUE; } else if (disconnected) { @@ -5068,8 +5047,9 @@ * same element in the SCB, SCB_NEXT, for * both the qinfifo and the disconnected list. */ - ahc_search_disc_list(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, pending_scb->hscb->tag, + ahc_search_disc_list(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, pending_scb->hscb->tag, /*stop_on_first*/TRUE, /*remove*/TRUE, /*save_state*/FALSE); @@ -5092,19 +5072,20 @@ * so we are the next SCB for this target * to run. */ - ahc_search_qinfifo(ahc, cmd->target, cmd->channel + 'A', - cmd->lun, SCB_LIST_NULL, ROLE_INITIATOR, - CAM_REQUEUE_REQ, SEARCH_COMPLETE); - ahc_print_path(ahc, pending_scb); - printf("Queuing a recovery SCB\n"); + ahc_search_qinfifo(ahc, cmd->device->id, + cmd->device->channel + 'A', + cmd->device->lun, SCB_LIST_NULL, + ROLE_INITIATOR, CAM_REQUEUE_REQ, + SEARCH_COMPLETE); ahc_qinfifo_requeue_tail(ahc, pending_scb); ahc_outb(ahc, SCBPTR, saved_scbptr); - printf("%s:%d:%d:%d: Device is disconnected, re-queuing SCB\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_print_path(ahc, pending_scb); + printf("Device is disconnected, re-queuing SCB\n"); wait = TRUE; } else { printf("%s:%d:%d:%d: Unable to deliver message\n", - ahc_name(ahc), cmd->channel, cmd->target, cmd->lun); + ahc_name(ahc), cmd->device->channel, cmd->device->id, + cmd->device->lun); retval = FAILED; goto done; } @@ -5124,7 +5105,7 @@ struct timer_list timer; int ret; - pending_scb->platform_data->flags |= AHC_UP_EH_SEMAPHORE; + ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) ahc_unlock(ahc, &s); #else diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h Sun Feb 9 21:13:31 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h Sun Feb 9 21:13:31 2003 @@ -18,7 +18,7 @@ * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * - * Copyright (c) 2000-2001 Adaptec Inc. + * Copyright (c) 2000-2003 Adaptec Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,7 +53,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#118 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#123 $ * */ #ifndef _AIC7XXX_LINUX_H_ @@ -67,9 +67,6 @@ #include #include #include -#ifndef AHC_MODVERSION_FILE -#define __NO_VERSION__ -#endif #include #include #include @@ -90,7 +87,6 @@ #define AIC_LIB_PREFIX ahc #include "scsi.h" #include "hosts.h" -#include "aiclib.h" /* Name space conflict with BSD queue macros */ #ifdef LIST_HEAD @@ -100,6 +96,7 @@ #include "cam.h" #include "queue.h" #include "scsi_message.h" +#include "aiclib.h" /*********************************** Debugging ********************************/ #ifdef CONFIG_AIC7XXX_DEBUG_ENABLE @@ -302,7 +299,7 @@ #include #endif -#define AIC7XXX_DRIVER_VERSION "6.2.26" +#define AIC7XXX_DRIVER_VERSION "6.2.28" /**************************** Front End Queues ********************************/ /* @@ -337,7 +334,7 @@ /* * A per probed device structure used to deal with some error recovery * scenarios that the Linux mid-layer code just doesn't know how to - * handle. The structure allocated for a device only becomes persistant + * handle. The structure allocated for a device only becomes persistent * after a successfully completed inquiry command to the target when * that inquiry data indicates a lun is present. */ @@ -497,7 +494,7 @@ * Per-SCB OSM storage. */ typedef enum { - AHC_UP_EH_SEMAPHORE + AHC_UP_EH_SEMAPHORE = 0x1 } ahc_linux_scb_flags; struct scb_platform_data { @@ -550,6 +547,7 @@ struct semaphore dv_cmd_sem; /* XXX This needs to be in * the target struct */ + struct scsi_device *dv_scsi_dev; struct Scsi_Host *host; /* pointer to scsi host */ #define AHC_LINUX_NOIRQ ((uint32_t)~0) uint32_t irq; /* IRQ for this adapter */ diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c --- a/drivers/scsi/aic7xxx/aic7xxx_pci.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c Sun Feb 9 21:13:28 2003 @@ -39,7 +39,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#55 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_pci.c#57 $ * * $FreeBSD$ */ @@ -641,6 +641,7 @@ #define AHC_494X_SLOT_CHANNEL_D 7 #define DEVCONFIG 0x40 +#define PCIERRGENDIS 0x80000000ul #define SCBSIZE32 0x00010000ul /* aic789X only */ #define REXTVALID 0x00001000ul /* ultra cards only */ #define MPORTMODE 0x00000400ul /* aic7870+ only */ @@ -785,6 +786,7 @@ u_int sxfrctl1; u_int scsiseq; u_int dscommand0; + uint32_t devconfig; int error; uint8_t sblkctl; @@ -809,6 +811,8 @@ */ ahc_intr_enable(ahc, FALSE); + devconfig = ahc_pci_read_config(ahc->dev_softc, DEVCONFIG, /*bytes*/4); + /* * If we need to support high memory, enable dual * address cycles. This bit must be set to enable @@ -816,21 +820,30 @@ * 64bit bus (PCI64BIT set in devconfig). */ if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { - uint32_t devconfig; if (bootverbose) printf("%s: Enabling 39Bit Addressing\n", ahc_name(ahc)); - devconfig = ahc_pci_read_config(ahc->dev_softc, - DEVCONFIG, /*bytes*/4); devconfig |= DACEN; - ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, - devconfig, /*bytes*/4); } + /* Ensure that pci error generation, a test feature, is disabled. */ + devconfig |= PCIERRGENDIS; + + ahc_pci_write_config(ahc->dev_softc, DEVCONFIG, devconfig, /*bytes*/4); + /* Ensure busmastering is enabled */ command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, /*bytes*/1); command |= PCIM_CMD_BUSMASTEREN; + + /* + * Disable PCI parity error reporting. Users typically + * do this to work around broken PCI chipsets that get + * the parity timing wrong and thus generate lots of spurious + * errors. + */ + if ((ahc->flags & AHC_DISABLE_PCI_PERR) != 0) + command &= ~PCIM_CMD_PERRESPEN; ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, /*bytes*/1); /* On all PCI adapters, we allow SCB paging */ @@ -947,7 +960,8 @@ * a SEEPROM. */ /* See if someone else set us up already */ - if (scsiseq != 0) { + if ((ahc->flags & AHC_NO_BIOS_INIT) == 0 + && scsiseq != 0) { printf("%s: Using left over BIOS settings\n", ahc_name(ahc)); ahc->flags &= ~AHC_USEDEFAULTS; diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped b/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped --- a/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped Sun Feb 9 21:13:33 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped Sun Feb 9 21:13:33 2003 @@ -2,7 +2,7 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $ */ typedef int (ahc_reg_print_t)(u_int, u_int *, u_int); diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped b/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped --- a/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_reg_print.c_shipped Sun Feb 9 21:13:32 2003 @@ -2,7 +2,7 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $ */ diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped --- a/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped Sun Feb 9 21:13:37 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped Sun Feb 9 21:13:37 2003 @@ -2,13 +2,13 @@ * DO NOT EDIT - This file is automatically generated * from the following source files: * - * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#53 $ + * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#54 $ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#37 $ */ static uint8_t seqprog[] = { 0xb2, 0x00, 0x00, 0x08, 0xf7, 0x11, 0x22, 0x08, - 0x00, 0x65, 0xea, 0x59, + 0x00, 0x65, 0xec, 0x59, 0xf7, 0x01, 0x02, 0x08, 0xff, 0x6a, 0x24, 0x08, 0x40, 0x00, 0x40, 0x68, @@ -21,15 +21,15 @@ 0x01, 0x4d, 0xc8, 0x30, 0x00, 0x4c, 0x12, 0x70, 0x01, 0x39, 0xa2, 0x30, - 0x00, 0x6a, 0xd2, 0x5e, + 0x00, 0x6a, 0xd4, 0x5e, 0x01, 0x51, 0x20, 0x31, 0x01, 0x57, 0xae, 0x00, 0x0d, 0x6a, 0x76, 0x00, - 0x00, 0x51, 0x24, 0x5e, + 0x00, 0x51, 0x26, 0x5e, 0x01, 0x51, 0xc8, 0x30, 0x00, 0x39, 0xc8, 0x60, 0x00, 0xbb, 0x30, 0x70, - 0xc1, 0x6a, 0xea, 0x5e, + 0xc1, 0x6a, 0xec, 0x5e, 0x01, 0xbf, 0x72, 0x30, 0x01, 0x40, 0x7e, 0x31, 0x01, 0x90, 0x80, 0x30, @@ -46,13 +46,13 @@ 0x80, 0x0b, 0xb6, 0x78, 0x20, 0x6a, 0x16, 0x00, 0xa4, 0x6a, 0x06, 0x00, - 0x08, 0x3c, 0x78, 0x00, + 0x08, 0x6a, 0x78, 0x00, 0x01, 0x50, 0xc8, 0x30, 0xe0, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0x0e, 0x5e, + 0x48, 0x6a, 0x10, 0x5e, 0x01, 0x6a, 0xdc, 0x01, 0x88, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0x0e, 0x5e, + 0x48, 0x6a, 0x10, 0x5e, 0x01, 0x6a, 0x26, 0x01, 0xf0, 0x19, 0x7a, 0x08, 0x0f, 0x18, 0xc8, 0x08, @@ -63,7 +63,7 @@ 0x80, 0x3d, 0x7a, 0x00, 0x01, 0x3d, 0xd8, 0x31, 0x01, 0x3d, 0x32, 0x31, - 0x10, 0x03, 0x4c, 0x79, + 0x10, 0x03, 0x4e, 0x79, 0x00, 0x65, 0xf2, 0x58, 0x80, 0x66, 0xae, 0x78, 0x01, 0x66, 0xd8, 0x31, @@ -79,7 +79,7 @@ 0x00, 0x65, 0xaa, 0x48, 0x01, 0x66, 0xd8, 0x31, 0x01, 0x66, 0x32, 0x31, - 0x10, 0x03, 0x4c, 0x79, + 0x10, 0x03, 0x4e, 0x79, 0x00, 0x65, 0xf2, 0x58, 0x01, 0x66, 0xd8, 0x31, 0x01, 0x66, 0x32, 0x31, @@ -87,13 +87,13 @@ 0x40, 0x3c, 0x78, 0x00, 0xff, 0x6a, 0xd8, 0x01, 0xff, 0x6a, 0x32, 0x01, - 0x10, 0x6a, 0x78, 0x00, + 0x10, 0x3c, 0x78, 0x00, 0x02, 0x57, 0x40, 0x69, 0x10, 0x03, 0x3e, 0x69, 0x00, 0x65, 0x20, 0x41, 0x02, 0x57, 0xae, 0x00, 0x00, 0x65, 0x9e, 0x40, - 0x61, 0x6a, 0xea, 0x5e, + 0x61, 0x6a, 0xec, 0x5e, 0x08, 0x51, 0x20, 0x71, 0x02, 0x0b, 0xb2, 0x78, 0x00, 0x65, 0xae, 0x40, @@ -105,8 +105,8 @@ 0x08, 0x1f, 0xc4, 0x78, 0x80, 0x3d, 0x7a, 0x00, 0x20, 0x6a, 0x16, 0x00, - 0x00, 0x65, 0xca, 0x41, - 0x00, 0x65, 0xc4, 0x5e, + 0x00, 0x65, 0xcc, 0x41, + 0x00, 0x65, 0xc6, 0x5e, 0x00, 0x65, 0x12, 0x40, 0x20, 0x11, 0xd2, 0x68, 0x20, 0x6a, 0x18, 0x00, @@ -137,57 +137,58 @@ 0x01, 0xb9, 0x7a, 0x30, 0x01, 0xba, 0x7c, 0x30, 0x00, 0x65, 0xea, 0x58, - 0x80, 0x0b, 0xc2, 0x79, + 0x80, 0x0b, 0xc4, 0x79, 0x12, 0x01, 0x02, 0x00, 0x01, 0xab, 0xac, 0x30, - 0xe4, 0x6a, 0x80, 0x5d, + 0xe4, 0x6a, 0x82, 0x5d, 0x40, 0x6a, 0x16, 0x00, - 0x80, 0xba, 0x96, 0x5d, + 0x80, 0xba, 0x98, 0x5d, 0x20, 0xb8, 0x18, 0x79, - 0x20, 0x6a, 0x96, 0x5d, - 0x00, 0xab, 0x96, 0x5d, + 0x20, 0x6a, 0x98, 0x5d, + 0x00, 0xab, 0x98, 0x5d, 0x01, 0xa9, 0x78, 0x30, 0x10, 0xb8, 0x20, 0x79, - 0xe4, 0x6a, 0x80, 0x5d, + 0xe4, 0x6a, 0x82, 0x5d, 0x00, 0x65, 0xae, 0x40, 0x10, 0x03, 0x3c, 0x69, - 0x08, 0x3c, 0x58, 0x69, - 0x04, 0x3c, 0x90, 0x69, - 0x02, 0x3c, 0x96, 0x69, - 0x01, 0x3c, 0x42, 0x79, + 0x08, 0x3c, 0x5a, 0x69, + 0x04, 0x3c, 0x92, 0x69, + 0x02, 0x3c, 0x98, 0x69, + 0x01, 0x3c, 0x44, 0x79, 0xff, 0x6a, 0x70, 0x00, - 0x00, 0x65, 0xa2, 0x59, - 0x00, 0x6a, 0xd2, 0x5e, + 0x00, 0x65, 0xa4, 0x59, + 0x00, 0x6a, 0xd4, 0x5e, 0xff, 0x38, 0x30, 0x71, 0x0d, 0x6a, 0x76, 0x00, - 0x00, 0x38, 0x24, 0x5e, + 0x00, 0x38, 0x26, 0x5e, 0x00, 0x65, 0xea, 0x58, 0x12, 0x01, 0x02, 0x00, 0x00, 0x65, 0x18, 0x41, 0xa4, 0x6a, 0x06, 0x00, 0x00, 0x65, 0xf2, 0x58, + 0xfd, 0x57, 0xae, 0x08, 0x00, 0x65, 0xae, 0x40, - 0xe4, 0x6a, 0x80, 0x5d, - 0x20, 0x3c, 0x48, 0x79, - 0x02, 0x6a, 0x96, 0x5d, - 0x04, 0x6a, 0x96, 0x5d, - 0x01, 0x03, 0x4a, 0x69, + 0xe4, 0x6a, 0x82, 0x5d, + 0x20, 0x3c, 0x4a, 0x79, + 0x02, 0x6a, 0x98, 0x5d, + 0x04, 0x6a, 0x98, 0x5d, + 0x01, 0x03, 0x4c, 0x69, 0xf7, 0x11, 0x22, 0x08, 0xff, 0x6a, 0x24, 0x08, 0xff, 0x6a, 0x06, 0x08, 0x01, 0x6a, 0x7e, 0x00, - 0x00, 0x65, 0xa2, 0x59, + 0x00, 0x65, 0xa4, 0x59, 0x00, 0x65, 0x04, 0x40, 0x80, 0x86, 0xc8, 0x08, 0x01, 0x4f, 0xc8, 0x30, - 0x00, 0x50, 0x6a, 0x61, - 0xc4, 0x6a, 0x80, 0x5d, - 0x40, 0x3c, 0x66, 0x79, - 0x28, 0x6a, 0x96, 0x5d, - 0x00, 0x65, 0x4a, 0x41, - 0x08, 0x6a, 0x96, 0x5d, - 0x00, 0x65, 0x4a, 0x41, - 0x84, 0x6a, 0x80, 0x5d, + 0x00, 0x50, 0x6c, 0x61, + 0xc4, 0x6a, 0x82, 0x5d, + 0x40, 0x3c, 0x68, 0x79, + 0x28, 0x6a, 0x98, 0x5d, + 0x00, 0x65, 0x4c, 0x41, + 0x08, 0x6a, 0x98, 0x5d, + 0x00, 0x65, 0x4c, 0x41, + 0x84, 0x6a, 0x82, 0x5d, 0x00, 0x65, 0xf2, 0x58, 0x01, 0x66, 0xc8, 0x30, 0x01, 0x64, 0xd8, 0x31, @@ -195,62 +196,62 @@ 0x5b, 0x64, 0xc8, 0x28, 0x30, 0x64, 0xca, 0x18, 0x01, 0x6c, 0xc8, 0x30, - 0xff, 0x64, 0x8c, 0x79, + 0xff, 0x64, 0x8e, 0x79, 0x08, 0x01, 0x02, 0x00, - 0x02, 0x0b, 0x7e, 0x79, - 0x01, 0x64, 0x84, 0x61, + 0x02, 0x0b, 0x80, 0x79, + 0x01, 0x64, 0x86, 0x61, 0xf7, 0x01, 0x02, 0x08, 0x01, 0x06, 0xd8, 0x31, 0x01, 0x06, 0x32, 0x31, 0xff, 0x64, 0xc8, 0x18, - 0xff, 0x64, 0x7e, 0x69, + 0xff, 0x64, 0x80, 0x69, 0xf7, 0x3c, 0x78, 0x08, 0x00, 0x65, 0x20, 0x41, 0x40, 0xaa, 0x7e, 0x10, - 0x04, 0xaa, 0x80, 0x5d, - 0x00, 0x65, 0x5c, 0x42, - 0xc4, 0x6a, 0x80, 0x5d, + 0x04, 0xaa, 0x82, 0x5d, + 0x00, 0x65, 0x5e, 0x42, + 0xc4, 0x6a, 0x82, 0x5d, 0xc0, 0x6a, 0x7e, 0x00, - 0x00, 0xa8, 0x96, 0x5d, + 0x00, 0xa8, 0x98, 0x5d, 0xe4, 0x6a, 0x06, 0x00, - 0x00, 0x6a, 0x96, 0x5d, - 0x00, 0x65, 0x4a, 0x41, - 0x10, 0x3c, 0xa6, 0x69, - 0x00, 0xbb, 0x9c, 0x44, + 0x00, 0x6a, 0x98, 0x5d, + 0x00, 0x65, 0x4c, 0x41, + 0x10, 0x3c, 0xa8, 0x69, + 0x00, 0xbb, 0x9e, 0x44, 0x18, 0x6a, 0xda, 0x01, 0x01, 0x69, 0xd8, 0x31, 0x1c, 0x6a, 0xd0, 0x01, 0x09, 0xee, 0xdc, 0x01, - 0x80, 0xee, 0xae, 0x79, + 0x80, 0xee, 0xb0, 0x79, 0xff, 0x6a, 0xdc, 0x09, 0x01, 0x93, 0x26, 0x01, 0x03, 0x6a, 0x2a, 0x01, 0x01, 0x69, 0x32, 0x31, - 0x1c, 0x6a, 0xf2, 0x5d, + 0x1c, 0x6a, 0xf4, 0x5d, 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0xba, 0x5e, + 0x00, 0x65, 0xbc, 0x5e, 0x01, 0x50, 0xa0, 0x18, 0x02, 0x6a, 0x22, 0x05, 0x1a, 0x01, 0x02, 0x00, 0x80, 0x6a, 0x74, 0x00, 0x40, 0x6a, 0x78, 0x00, 0x40, 0x6a, 0x16, 0x00, - 0x00, 0x65, 0xea, 0x5d, + 0x00, 0x65, 0xec, 0x5d, 0x01, 0x3f, 0xc8, 0x30, - 0xbf, 0x64, 0x5c, 0x7a, - 0x80, 0x64, 0xb0, 0x73, - 0xa0, 0x64, 0x12, 0x74, - 0xc0, 0x64, 0x06, 0x74, - 0xe0, 0x64, 0x42, 0x74, - 0x01, 0x6a, 0xea, 0x5e, - 0x00, 0x65, 0xca, 0x41, + 0xbf, 0x64, 0x5e, 0x7a, + 0x80, 0x64, 0xb2, 0x73, + 0xa0, 0x64, 0x14, 0x74, + 0xc0, 0x64, 0x08, 0x74, + 0xe0, 0x64, 0x44, 0x74, + 0x01, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0xcc, 0x41, 0xf7, 0x11, 0x22, 0x08, 0x01, 0x06, 0xd4, 0x30, 0xff, 0x6a, 0x24, 0x08, 0xf7, 0x01, 0x02, 0x08, - 0x09, 0x0c, 0xe4, 0x79, + 0x09, 0x0c, 0xe6, 0x79, 0x08, 0x0c, 0x04, 0x68, - 0xb1, 0x6a, 0xea, 0x5e, + 0xb1, 0x6a, 0xec, 0x5e, 0xff, 0x6a, 0x26, 0x09, 0x12, 0x01, 0x02, 0x00, 0x02, 0x6a, 0x08, 0x30, @@ -263,33 +264,33 @@ 0x00, 0xa5, 0x4a, 0x21, 0x00, 0xa6, 0x4c, 0x21, 0x00, 0xa7, 0x4e, 0x25, - 0x08, 0xeb, 0xee, 0x7e, - 0x80, 0xeb, 0x04, 0x7a, + 0x08, 0xeb, 0xf0, 0x7e, + 0x80, 0xeb, 0x06, 0x7a, 0xff, 0x6a, 0xd6, 0x09, - 0x08, 0xeb, 0x08, 0x6a, + 0x08, 0xeb, 0x0a, 0x6a, 0xff, 0x6a, 0xd4, 0x0c, - 0x80, 0xa3, 0xee, 0x6e, - 0x88, 0xeb, 0x1e, 0x72, - 0x08, 0xeb, 0xee, 0x6e, - 0x04, 0xea, 0x22, 0xe2, - 0x08, 0xee, 0xee, 0x6e, + 0x80, 0xa3, 0xf0, 0x6e, + 0x88, 0xeb, 0x20, 0x72, + 0x08, 0xeb, 0xf0, 0x6e, + 0x04, 0xea, 0x24, 0xe2, + 0x08, 0xee, 0xf0, 0x6e, 0x04, 0x6a, 0xd0, 0x81, 0x05, 0xa4, 0xc0, 0x89, 0x03, 0xa5, 0xc2, 0x31, 0x09, 0x6a, 0xd6, 0x05, - 0x00, 0x65, 0x06, 0x5a, + 0x00, 0x65, 0x08, 0x5a, 0x06, 0xa4, 0xd4, 0x89, - 0x80, 0x94, 0xee, 0x7e, + 0x80, 0x94, 0xf0, 0x7e, 0x07, 0xe9, 0x10, 0x31, - 0x01, 0x8c, 0x2a, 0x7a, + 0x01, 0x8c, 0x2c, 0x7a, 0x01, 0x55, 0xaa, 0x10, 0x01, 0xe9, 0x46, 0x31, - 0x00, 0xa3, 0xcc, 0x5e, - 0x00, 0x65, 0xf8, 0x59, + 0x00, 0xa3, 0xce, 0x5e, + 0x00, 0x65, 0xfa, 0x59, 0x01, 0xa4, 0xca, 0x30, - 0x01, 0x55, 0x36, 0x7a, + 0x01, 0x55, 0x38, 0x7a, 0x04, 0x65, 0xca, 0x00, - 0x80, 0xa3, 0x3a, 0x7a, + 0x80, 0xa3, 0x3c, 0x7a, 0x02, 0x65, 0xca, 0x00, 0x01, 0x65, 0xf8, 0x31, 0x80, 0x93, 0x26, 0x01, @@ -297,168 +298,168 @@ 0x01, 0x8c, 0xc8, 0x30, 0x00, 0x88, 0xc8, 0x18, 0x02, 0x64, 0xc8, 0x88, - 0xff, 0x64, 0xee, 0x7e, - 0xff, 0x8d, 0x50, 0x6a, - 0xff, 0x8e, 0x50, 0x6a, + 0xff, 0x64, 0xf0, 0x7e, + 0xff, 0x8d, 0x52, 0x6a, + 0xff, 0x8e, 0x52, 0x6a, 0x03, 0x8c, 0xd4, 0x98, - 0x00, 0x65, 0xee, 0x56, + 0x00, 0x65, 0xf0, 0x56, 0x01, 0x64, 0x70, 0x30, 0xff, 0x64, 0xc8, 0x10, 0x01, 0x64, 0xc8, 0x18, 0x00, 0x8c, 0x18, 0x19, 0xff, 0x8d, 0x1a, 0x21, 0xff, 0x8e, 0x1c, 0x25, - 0xc0, 0x3c, 0x60, 0x7a, - 0x21, 0x6a, 0xea, 0x5e, + 0xc0, 0x3c, 0x62, 0x7a, + 0x21, 0x6a, 0xec, 0x5e, 0xa8, 0x6a, 0x76, 0x00, 0x79, 0x6a, 0x76, 0x00, - 0x40, 0x3f, 0x68, 0x6a, + 0x40, 0x3f, 0x6a, 0x6a, 0x04, 0x3b, 0x76, 0x00, 0x04, 0x6a, 0xd4, 0x81, - 0x20, 0x3c, 0x70, 0x7a, - 0x51, 0x6a, 0xea, 0x5e, - 0x00, 0x65, 0x8a, 0x42, + 0x20, 0x3c, 0x72, 0x7a, + 0x51, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0x8c, 0x42, 0x20, 0x3c, 0x78, 0x00, - 0x00, 0xb3, 0xcc, 0x5e, + 0x00, 0xb3, 0xce, 0x5e, 0x07, 0xac, 0x10, 0x31, 0x05, 0xb3, 0x46, 0x31, 0x88, 0x6a, 0xcc, 0x00, - 0xac, 0x6a, 0x00, 0x5e, + 0xac, 0x6a, 0x02, 0x5e, 0xa3, 0x6a, 0xcc, 0x00, - 0xb3, 0x6a, 0x04, 0x5e, - 0x00, 0x65, 0x40, 0x5a, + 0xb3, 0x6a, 0x06, 0x5e, + 0x00, 0x65, 0x42, 0x5a, 0xfd, 0xa4, 0x48, 0x09, 0x01, 0x8c, 0xaa, 0x08, 0x03, 0x8c, 0x10, 0x30, - 0x00, 0x65, 0xf8, 0x5d, - 0x01, 0xa4, 0x9c, 0x7a, + 0x00, 0x65, 0xfa, 0x5d, + 0x01, 0xa4, 0x9e, 0x7a, 0x04, 0x3b, 0x76, 0x08, 0x01, 0x3b, 0x26, 0x31, 0x80, 0x02, 0x04, 0x00, - 0x10, 0x0c, 0x92, 0x7a, - 0x03, 0x9e, 0x94, 0x6a, + 0x10, 0x0c, 0x94, 0x7a, + 0x03, 0x9e, 0x96, 0x6a, 0x7f, 0x02, 0x04, 0x08, - 0x91, 0x6a, 0xea, 0x5e, - 0x00, 0x65, 0xca, 0x41, + 0x91, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0xcc, 0x41, 0x01, 0xa4, 0xca, 0x30, - 0x80, 0xa3, 0xa2, 0x7a, + 0x80, 0xa3, 0xa4, 0x7a, 0x02, 0x65, 0xca, 0x00, - 0x01, 0x55, 0xa6, 0x7a, + 0x01, 0x55, 0xa8, 0x7a, 0x04, 0x65, 0xca, 0x00, 0x01, 0x65, 0xf8, 0x31, 0x01, 0x3b, 0x26, 0x31, - 0x00, 0x65, 0x0c, 0x5a, - 0x01, 0xfc, 0xb4, 0x6a, - 0x80, 0x0b, 0xaa, 0x6a, - 0x10, 0x0c, 0xaa, 0x7a, - 0x20, 0x93, 0xaa, 0x6a, + 0x00, 0x65, 0x0e, 0x5a, + 0x01, 0xfc, 0xb6, 0x6a, + 0x80, 0x0b, 0xac, 0x6a, + 0x10, 0x0c, 0xac, 0x7a, + 0x20, 0x93, 0xac, 0x6a, 0x02, 0x93, 0x26, 0x01, - 0x02, 0xfc, 0xbe, 0x7a, - 0x40, 0x0d, 0xd8, 0x6a, + 0x02, 0xfc, 0xc0, 0x7a, + 0x40, 0x0d, 0xda, 0x6a, 0x01, 0xa4, 0x48, 0x01, - 0x00, 0x65, 0xd8, 0x42, - 0x40, 0x0d, 0xc4, 0x6a, - 0x00, 0x65, 0x0c, 0x5a, - 0x00, 0x65, 0xb6, 0x42, - 0x80, 0xfc, 0xce, 0x7a, - 0x80, 0xa4, 0xce, 0x6a, + 0x00, 0x65, 0xda, 0x42, + 0x40, 0x0d, 0xc6, 0x6a, + 0x00, 0x65, 0x0e, 0x5a, + 0x00, 0x65, 0xb8, 0x42, + 0x80, 0xfc, 0xd0, 0x7a, + 0x80, 0xa4, 0xd0, 0x6a, 0xff, 0xa5, 0x4a, 0x19, 0xff, 0xa6, 0x4c, 0x21, 0xff, 0xa7, 0x4e, 0x21, 0xf8, 0xfc, 0x48, 0x09, 0xff, 0x6a, 0xaa, 0x08, - 0x04, 0xfc, 0xd6, 0x7a, + 0x04, 0xfc, 0xd8, 0x7a, 0x01, 0x55, 0xaa, 0x00, 0xff, 0x6a, 0x46, 0x09, - 0x04, 0x3b, 0xf0, 0x6a, + 0x04, 0x3b, 0xf2, 0x6a, 0x02, 0x93, 0x26, 0x01, - 0x01, 0x94, 0xda, 0x7a, - 0x01, 0x94, 0xda, 0x7a, - 0x01, 0x94, 0xda, 0x7a, - 0x01, 0x94, 0xda, 0x7a, - 0x01, 0x94, 0xda, 0x7a, - 0x01, 0xa4, 0xee, 0x7a, - 0x01, 0xfc, 0xe8, 0x7a, - 0x01, 0x94, 0xf0, 0x6a, - 0x00, 0x65, 0x8a, 0x42, - 0x01, 0x94, 0xee, 0x7a, - 0x10, 0x94, 0xf0, 0x6a, + 0x01, 0x94, 0xdc, 0x7a, + 0x01, 0x94, 0xdc, 0x7a, + 0x01, 0x94, 0xdc, 0x7a, + 0x01, 0x94, 0xdc, 0x7a, + 0x01, 0x94, 0xdc, 0x7a, + 0x01, 0xa4, 0xf0, 0x7a, + 0x01, 0xfc, 0xea, 0x7a, + 0x01, 0x94, 0xf2, 0x6a, + 0x00, 0x65, 0x8c, 0x42, + 0x01, 0x94, 0xf0, 0x7a, + 0x10, 0x94, 0xf2, 0x6a, 0xd7, 0x93, 0x26, 0x09, - 0x28, 0x93, 0xf4, 0x6a, + 0x28, 0x93, 0xf6, 0x6a, 0x01, 0x85, 0x0a, 0x01, - 0x02, 0xfc, 0xfc, 0x6a, + 0x02, 0xfc, 0xfe, 0x6a, 0x01, 0x14, 0x46, 0x31, 0xff, 0x6a, 0x10, 0x09, 0xfe, 0x85, 0x0a, 0x09, - 0xff, 0x38, 0x0a, 0x6b, - 0x80, 0xa3, 0x0a, 0x7b, - 0x80, 0x0b, 0x08, 0x7b, - 0x04, 0x3b, 0x0a, 0x7b, + 0xff, 0x38, 0x0c, 0x6b, + 0x80, 0xa3, 0x0c, 0x7b, + 0x80, 0x0b, 0x0a, 0x7b, + 0x04, 0x3b, 0x0c, 0x7b, 0xbf, 0x3b, 0x76, 0x08, 0x01, 0x3b, 0x26, 0x31, - 0x00, 0x65, 0x0c, 0x5a, - 0x01, 0x0b, 0x18, 0x6b, - 0x10, 0x0c, 0x0c, 0x7b, - 0x04, 0x93, 0x16, 0x6b, - 0x01, 0x94, 0x14, 0x7b, - 0x10, 0x94, 0x16, 0x6b, + 0x00, 0x65, 0x0e, 0x5a, + 0x01, 0x0b, 0x1a, 0x6b, + 0x10, 0x0c, 0x0e, 0x7b, + 0x04, 0x93, 0x18, 0x6b, + 0x01, 0x94, 0x16, 0x7b, + 0x10, 0x94, 0x18, 0x6b, 0xc7, 0x93, 0x26, 0x09, 0x01, 0x99, 0xd4, 0x30, - 0x38, 0x93, 0x1a, 0x6b, - 0xff, 0x08, 0x6c, 0x6b, - 0xff, 0x09, 0x6c, 0x6b, - 0xff, 0x0a, 0x6c, 0x6b, - 0xff, 0x38, 0x36, 0x7b, + 0x38, 0x93, 0x1c, 0x6b, + 0xff, 0x08, 0x6e, 0x6b, + 0xff, 0x09, 0x6e, 0x6b, + 0xff, 0x0a, 0x6e, 0x6b, + 0xff, 0x38, 0x38, 0x7b, 0x04, 0x14, 0x10, 0x31, 0x01, 0x38, 0x18, 0x31, 0x02, 0x6a, 0x1a, 0x31, 0x88, 0x6a, 0xcc, 0x00, - 0x14, 0x6a, 0x06, 0x5e, - 0x00, 0x38, 0xf2, 0x5d, + 0x14, 0x6a, 0x08, 0x5e, + 0x00, 0x38, 0xf4, 0x5d, 0xff, 0x6a, 0x70, 0x08, - 0x00, 0x65, 0x62, 0x43, - 0x80, 0xa3, 0x3c, 0x7b, + 0x00, 0x65, 0x64, 0x43, + 0x80, 0xa3, 0x3e, 0x7b, 0x01, 0xa4, 0x48, 0x01, - 0x00, 0x65, 0x6c, 0x43, - 0x08, 0xeb, 0x42, 0x7b, - 0x00, 0x65, 0x0c, 0x5a, - 0x08, 0xeb, 0x3e, 0x6b, + 0x00, 0x65, 0x6e, 0x43, + 0x08, 0xeb, 0x44, 0x7b, + 0x00, 0x65, 0x0e, 0x5a, + 0x08, 0xeb, 0x40, 0x6b, 0x07, 0xe9, 0x10, 0x31, 0x01, 0xe9, 0xca, 0x30, 0x01, 0x65, 0x46, 0x31, - 0x00, 0x6a, 0xcc, 0x5e, + 0x00, 0x6a, 0xce, 0x5e, 0x88, 0x6a, 0xcc, 0x00, - 0xa4, 0x6a, 0x06, 0x5e, - 0x08, 0x6a, 0xf2, 0x5d, + 0xa4, 0x6a, 0x08, 0x5e, + 0x08, 0x6a, 0xf4, 0x5d, 0x0d, 0x93, 0x26, 0x01, - 0x00, 0x65, 0xba, 0x5e, + 0x00, 0x65, 0xbc, 0x5e, 0x88, 0x6a, 0xcc, 0x00, - 0x00, 0x65, 0x9c, 0x5e, + 0x00, 0x65, 0x9e, 0x5e, 0x01, 0x99, 0x46, 0x31, - 0x00, 0xa3, 0xcc, 0x5e, + 0x00, 0xa3, 0xce, 0x5e, 0x01, 0x88, 0x10, 0x31, - 0x00, 0x65, 0x40, 0x5a, - 0x00, 0x65, 0xf8, 0x59, + 0x00, 0x65, 0x42, 0x5a, + 0x00, 0x65, 0xfa, 0x59, 0x03, 0x8c, 0x10, 0x30, - 0x00, 0x65, 0xf8, 0x5d, - 0x01, 0x8c, 0x6a, 0x7b, + 0x00, 0x65, 0xfa, 0x5d, + 0x01, 0x8c, 0x6c, 0x7b, 0x01, 0x55, 0xaa, 0x10, - 0x80, 0x0b, 0x8a, 0x6a, - 0x80, 0x0b, 0x74, 0x6b, - 0x01, 0x0c, 0x6e, 0x7b, - 0x10, 0x0c, 0x8a, 0x7a, - 0x03, 0x9e, 0x8a, 0x6a, - 0x00, 0x65, 0x02, 0x5a, - 0x00, 0x6a, 0xcc, 0x5e, - 0x01, 0xa4, 0x94, 0x6b, - 0xff, 0x38, 0x8a, 0x7b, + 0x80, 0x0b, 0x8c, 0x6a, + 0x80, 0x0b, 0x76, 0x6b, + 0x01, 0x0c, 0x70, 0x7b, + 0x10, 0x0c, 0x8c, 0x7a, + 0x03, 0x9e, 0x8c, 0x6a, + 0x00, 0x65, 0x04, 0x5a, + 0x00, 0x6a, 0xce, 0x5e, + 0x01, 0xa4, 0x96, 0x6b, + 0xff, 0x38, 0x8c, 0x7b, 0x01, 0x38, 0xc8, 0x30, 0x00, 0x08, 0x40, 0x19, 0xff, 0x6a, 0xc8, 0x08, 0x00, 0x09, 0x42, 0x21, 0x00, 0x0a, 0x44, 0x21, 0xff, 0x6a, 0x70, 0x08, - 0x00, 0x65, 0x8c, 0x43, + 0x00, 0x65, 0x8e, 0x43, 0x03, 0x08, 0x40, 0x31, 0x03, 0x08, 0x40, 0x31, 0x01, 0x08, 0x40, 0x31, @@ -467,19 +468,19 @@ 0xfd, 0xb4, 0x68, 0x09, 0x12, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x00, - 0x04, 0x3c, 0xca, 0x79, + 0x04, 0x3c, 0xcc, 0x79, 0xfb, 0x3c, 0x78, 0x08, 0x04, 0x93, 0x20, 0x79, - 0x01, 0x0c, 0xa0, 0x6b, + 0x01, 0x0c, 0xa2, 0x6b, 0x01, 0x55, 0x20, 0x79, 0x80, 0x04, 0x20, 0x79, - 0xe4, 0x6a, 0x80, 0x5d, - 0x23, 0x6a, 0x96, 0x5d, - 0x01, 0x6a, 0x96, 0x5d, + 0xe4, 0x6a, 0x82, 0x5d, + 0x23, 0x6a, 0x98, 0x5d, + 0x01, 0x6a, 0x98, 0x5d, 0x00, 0x65, 0x20, 0x41, - 0x00, 0x65, 0xca, 0x41, - 0x80, 0x3c, 0xb4, 0x7b, - 0x21, 0x6a, 0xea, 0x5e, + 0x00, 0x65, 0xcc, 0x41, + 0x80, 0x3c, 0xb6, 0x7b, + 0x21, 0x6a, 0xec, 0x5e, 0x01, 0xbc, 0x18, 0x31, 0x02, 0x6a, 0x1a, 0x31, 0x02, 0x6a, 0xf8, 0x01, @@ -489,16 +490,16 @@ 0xff, 0x6a, 0x12, 0x08, 0xff, 0x6a, 0x14, 0x08, 0xf3, 0xbc, 0xd4, 0x18, - 0xa0, 0x6a, 0xda, 0x53, + 0xa0, 0x6a, 0xdc, 0x53, 0x04, 0xa0, 0x10, 0x31, 0xac, 0x6a, 0x26, 0x01, 0x04, 0xa0, 0x10, 0x31, 0x03, 0x08, 0x18, 0x31, 0x88, 0x6a, 0xcc, 0x00, - 0xa0, 0x6a, 0x06, 0x5e, - 0x00, 0xbc, 0xf2, 0x5d, + 0xa0, 0x6a, 0x08, 0x5e, + 0x00, 0xbc, 0xf4, 0x5d, 0x3d, 0x6a, 0x26, 0x01, - 0x00, 0x65, 0xf2, 0x43, + 0x00, 0x65, 0xf4, 0x43, 0xff, 0x6a, 0x10, 0x09, 0xa4, 0x6a, 0x26, 0x01, 0x0c, 0xa0, 0x32, 0x31, @@ -508,128 +509,128 @@ 0x36, 0x6a, 0x26, 0x01, 0x02, 0x93, 0x26, 0x01, 0x35, 0x6a, 0x26, 0x01, - 0x00, 0x65, 0xae, 0x5e, - 0x00, 0x65, 0xae, 0x5e, + 0x00, 0x65, 0xb0, 0x5e, + 0x00, 0x65, 0xb0, 0x5e, 0x02, 0x93, 0x26, 0x01, 0xbf, 0x3c, 0x78, 0x08, - 0x04, 0x0b, 0xf8, 0x6b, - 0x10, 0x0c, 0xf4, 0x7b, - 0x01, 0x03, 0xf8, 0x6b, - 0x20, 0x93, 0xfa, 0x6b, - 0x04, 0x0b, 0x00, 0x6c, + 0x04, 0x0b, 0xfa, 0x6b, + 0x10, 0x0c, 0xf6, 0x7b, + 0x01, 0x03, 0xfa, 0x6b, + 0x20, 0x93, 0xfc, 0x6b, + 0x04, 0x0b, 0x02, 0x6c, 0x40, 0x3c, 0x78, 0x00, 0xc7, 0x93, 0x26, 0x09, - 0x38, 0x93, 0x02, 0x6c, - 0x00, 0x65, 0xca, 0x41, - 0x80, 0x3c, 0x68, 0x6c, + 0x38, 0x93, 0x04, 0x6c, + 0x00, 0x65, 0xcc, 0x41, + 0x80, 0x3c, 0x6a, 0x6c, 0x01, 0x06, 0x50, 0x31, 0x80, 0xb8, 0x70, 0x01, - 0x00, 0x65, 0xca, 0x41, + 0x00, 0x65, 0xcc, 0x41, 0x10, 0x3f, 0x06, 0x00, 0x10, 0x6a, 0x06, 0x00, 0x01, 0x3a, 0xca, 0x30, - 0x80, 0x65, 0x2e, 0x64, - 0x10, 0xb8, 0x52, 0x6c, + 0x80, 0x65, 0x30, 0x64, + 0x10, 0xb8, 0x54, 0x6c, 0xc0, 0xba, 0xca, 0x00, - 0x40, 0xb8, 0x1e, 0x6c, + 0x40, 0xb8, 0x20, 0x6c, 0xbf, 0x65, 0xca, 0x08, - 0x20, 0xb8, 0x32, 0x7c, + 0x20, 0xb8, 0x34, 0x7c, 0x01, 0x65, 0x0c, 0x30, - 0x00, 0x65, 0xea, 0x5d, - 0xa0, 0x3f, 0x3a, 0x64, + 0x00, 0x65, 0xec, 0x5d, + 0xa0, 0x3f, 0x3c, 0x64, 0x23, 0xb8, 0x0c, 0x08, - 0x00, 0x65, 0xea, 0x5d, - 0xa0, 0x3f, 0x3a, 0x64, - 0x00, 0xbb, 0x32, 0x44, - 0xff, 0x65, 0x32, 0x64, - 0x00, 0x65, 0x52, 0x44, + 0x00, 0x65, 0xec, 0x5d, + 0xa0, 0x3f, 0x3c, 0x64, + 0x00, 0xbb, 0x34, 0x44, + 0xff, 0x65, 0x34, 0x64, + 0x00, 0x65, 0x54, 0x44, 0x40, 0x6a, 0x18, 0x00, 0x01, 0x65, 0x0c, 0x30, - 0x00, 0x65, 0xea, 0x5d, - 0xa0, 0x3f, 0x0e, 0x74, + 0x00, 0x65, 0xec, 0x5d, + 0xa0, 0x3f, 0x10, 0x74, 0x40, 0x6a, 0x18, 0x00, 0x01, 0x3a, 0xa6, 0x30, 0x08, 0x6a, 0x74, 0x00, - 0x00, 0x65, 0xca, 0x41, - 0x64, 0x6a, 0x7a, 0x5d, - 0x80, 0x64, 0xea, 0x6c, - 0x04, 0x64, 0xac, 0x74, - 0x02, 0x64, 0xbc, 0x74, - 0x00, 0x6a, 0x72, 0x74, - 0x03, 0x64, 0xda, 0x74, - 0x23, 0x64, 0x5a, 0x74, - 0x08, 0x64, 0x6e, 0x74, - 0x61, 0x6a, 0xea, 0x5e, - 0x00, 0x65, 0xea, 0x5d, - 0x08, 0x51, 0xcc, 0x71, - 0x00, 0x65, 0x52, 0x44, - 0x80, 0x04, 0x6c, 0x7c, - 0x51, 0x6a, 0x70, 0x5d, - 0x01, 0x51, 0x6c, 0x64, - 0x01, 0xa4, 0x64, 0x7c, - 0x01, 0x55, 0x6e, 0x7c, - 0x41, 0x6a, 0xea, 0x5e, - 0x00, 0x65, 0x6e, 0x44, - 0x21, 0x6a, 0xea, 0x5e, - 0x00, 0x65, 0x6e, 0x44, - 0x07, 0x6a, 0x66, 0x5d, + 0x00, 0x65, 0xcc, 0x41, + 0x64, 0x6a, 0x7c, 0x5d, + 0x80, 0x64, 0xec, 0x6c, + 0x04, 0x64, 0xae, 0x74, + 0x02, 0x64, 0xbe, 0x74, + 0x00, 0x6a, 0x74, 0x74, + 0x03, 0x64, 0xdc, 0x74, + 0x23, 0x64, 0x5c, 0x74, + 0x08, 0x64, 0x70, 0x74, + 0x61, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0xec, 0x5d, + 0x08, 0x51, 0xce, 0x71, + 0x00, 0x65, 0x54, 0x44, + 0x80, 0x04, 0x6e, 0x7c, + 0x51, 0x6a, 0x72, 0x5d, + 0x01, 0x51, 0x6e, 0x64, + 0x01, 0xa4, 0x66, 0x7c, + 0x01, 0x55, 0x70, 0x7c, + 0x41, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0x70, 0x44, + 0x21, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0x70, 0x44, + 0x07, 0x6a, 0x68, 0x5d, 0x01, 0x06, 0xd4, 0x30, - 0x00, 0x65, 0xca, 0x41, - 0x80, 0xb8, 0x68, 0x7c, - 0xc0, 0x3c, 0x7c, 0x7c, - 0x80, 0x3c, 0x68, 0x6c, - 0xff, 0xa8, 0x7c, 0x6c, - 0x40, 0x3c, 0x68, 0x6c, - 0x10, 0xb8, 0x80, 0x7c, - 0xa1, 0x6a, 0xea, 0x5e, - 0x01, 0xb4, 0x86, 0x6c, - 0x02, 0xb4, 0x88, 0x6c, - 0x01, 0xa4, 0x88, 0x7c, - 0xff, 0xa8, 0x98, 0x7c, + 0x00, 0x65, 0xcc, 0x41, + 0x80, 0xb8, 0x6a, 0x7c, + 0xc0, 0x3c, 0x7e, 0x7c, + 0x80, 0x3c, 0x6a, 0x6c, + 0xff, 0xa8, 0x7e, 0x6c, + 0x40, 0x3c, 0x6a, 0x6c, + 0x10, 0xb8, 0x82, 0x7c, + 0xa1, 0x6a, 0xec, 0x5e, + 0x01, 0xb4, 0x88, 0x6c, + 0x02, 0xb4, 0x8a, 0x6c, + 0x01, 0xa4, 0x8a, 0x7c, + 0xff, 0xa8, 0x9a, 0x7c, 0x04, 0xb4, 0x68, 0x01, 0x01, 0x6a, 0x76, 0x00, - 0x00, 0xbb, 0x24, 0x5e, - 0xff, 0xa8, 0x98, 0x7c, - 0x71, 0x6a, 0xea, 0x5e, - 0x40, 0x51, 0x98, 0x64, - 0x00, 0x65, 0xc4, 0x5e, - 0x00, 0x65, 0xdc, 0x41, - 0x00, 0xbb, 0x9c, 0x5c, - 0x00, 0x65, 0xdc, 0x41, - 0x00, 0x65, 0xc4, 0x5e, + 0x00, 0xbb, 0x26, 0x5e, + 0xff, 0xa8, 0x9a, 0x7c, + 0x71, 0x6a, 0xec, 0x5e, + 0x40, 0x51, 0x9a, 0x64, + 0x00, 0x65, 0xc6, 0x5e, + 0x00, 0x65, 0xde, 0x41, + 0x00, 0xbb, 0x9e, 0x5c, + 0x00, 0x65, 0xde, 0x41, + 0x00, 0x65, 0xc6, 0x5e, 0x01, 0x65, 0xa2, 0x30, 0x01, 0xf8, 0xc8, 0x30, 0x01, 0x4e, 0xc8, 0x30, - 0x00, 0x6a, 0xc8, 0xdd, - 0x00, 0x51, 0xda, 0x5d, + 0x00, 0x6a, 0xca, 0xdd, + 0x00, 0x51, 0xdc, 0x5d, 0x01, 0x4e, 0x9c, 0x18, 0x02, 0x6a, 0x22, 0x05, - 0xc0, 0x3c, 0x68, 0x6c, + 0xc0, 0x3c, 0x6a, 0x6c, 0x04, 0xb8, 0x70, 0x01, - 0x00, 0x65, 0xe6, 0x5e, - 0x20, 0xb8, 0xdc, 0x69, + 0x00, 0x65, 0xe8, 0x5e, + 0x20, 0xb8, 0xde, 0x69, 0x01, 0xbb, 0xa2, 0x30, 0x01, 0xba, 0x7c, 0x30, - 0x00, 0xb9, 0xe0, 0x5c, - 0x00, 0x65, 0xdc, 0x41, + 0x00, 0xb9, 0xe2, 0x5c, + 0x00, 0x65, 0xde, 0x41, 0x01, 0x06, 0xd4, 0x30, - 0x20, 0x3c, 0xca, 0x79, - 0x20, 0x3c, 0x6e, 0x7c, - 0x01, 0xa4, 0xca, 0x7c, + 0x20, 0x3c, 0xcc, 0x79, + 0x20, 0x3c, 0x70, 0x7c, + 0x01, 0xa4, 0xcc, 0x7c, 0x01, 0xb4, 0x68, 0x01, - 0x00, 0x65, 0xca, 0x41, - 0x00, 0x65, 0x6e, 0x44, + 0x00, 0x65, 0xcc, 0x41, + 0x00, 0x65, 0x70, 0x44, 0x04, 0x14, 0x58, 0x31, 0x01, 0x06, 0xd4, 0x30, 0x08, 0xa0, 0x60, 0x31, 0xac, 0x6a, 0xcc, 0x00, - 0x14, 0x6a, 0x06, 0x5e, + 0x14, 0x6a, 0x08, 0x5e, 0x01, 0x06, 0xd4, 0x30, - 0xa0, 0x6a, 0xfe, 0x5d, - 0x00, 0x65, 0xca, 0x41, + 0xa0, 0x6a, 0x00, 0x5e, + 0x00, 0x65, 0xcc, 0x41, 0xdf, 0x3c, 0x78, 0x08, 0x12, 0x01, 0x02, 0x00, - 0x00, 0x65, 0x6e, 0x44, + 0x00, 0x65, 0x70, 0x44, 0x4c, 0x65, 0xcc, 0x28, 0x01, 0x3e, 0x20, 0x31, 0xd0, 0x66, 0xcc, 0x18, @@ -640,102 +641,102 @@ 0xd0, 0x65, 0xca, 0x18, 0x01, 0x3e, 0x20, 0x31, 0x30, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0xf8, 0x4c, + 0x00, 0x65, 0xfa, 0x4c, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0x20, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0x00, 0x55, + 0x00, 0x65, 0x02, 0x55, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0x20, 0x65, 0xca, 0x18, 0xe0, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0x0a, 0x4d, + 0x00, 0x65, 0x0c, 0x4d, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0xd0, 0x65, 0xd4, 0x18, - 0x00, 0x65, 0x12, 0x55, + 0x00, 0x65, 0x14, 0x55, 0xe1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, 0x01, 0x6c, 0xa2, 0x30, - 0xff, 0x51, 0x24, 0x75, - 0x00, 0x51, 0xa0, 0x5d, + 0xff, 0x51, 0x26, 0x75, + 0x00, 0x51, 0xa2, 0x5d, 0x01, 0x51, 0x20, 0x31, - 0x00, 0x65, 0x46, 0x45, + 0x00, 0x65, 0x48, 0x45, 0x01, 0xba, 0xc8, 0x30, - 0x00, 0x3e, 0x46, 0x75, - 0x00, 0x65, 0xc2, 0x5e, + 0x00, 0x3e, 0x48, 0x75, + 0x00, 0x65, 0xc4, 0x5e, 0x80, 0x3c, 0x78, 0x00, 0x01, 0x06, 0xd4, 0x30, - 0x00, 0x65, 0xea, 0x5d, + 0x00, 0x65, 0xec, 0x5d, 0x01, 0x3c, 0x78, 0x00, - 0xe0, 0x3f, 0x62, 0x65, + 0xe0, 0x3f, 0x64, 0x65, 0x02, 0x3c, 0x78, 0x00, - 0x20, 0x12, 0x62, 0x65, - 0x51, 0x6a, 0x70, 0x5d, - 0x00, 0x51, 0xa0, 0x5d, - 0x51, 0x6a, 0x70, 0x5d, + 0x20, 0x12, 0x64, 0x65, + 0x51, 0x6a, 0x72, 0x5d, + 0x00, 0x51, 0xa2, 0x5d, + 0x51, 0x6a, 0x72, 0x5d, 0x01, 0x51, 0x20, 0x31, 0x04, 0x3c, 0x78, 0x00, 0x01, 0xb9, 0xc8, 0x30, - 0x00, 0x3d, 0x60, 0x65, + 0x00, 0x3d, 0x62, 0x65, 0x08, 0x3c, 0x78, 0x00, 0x01, 0xba, 0xc8, 0x30, - 0x00, 0x3e, 0x60, 0x65, + 0x00, 0x3e, 0x62, 0x65, 0x10, 0x3c, 0x78, 0x00, - 0x04, 0xb8, 0x60, 0x7d, + 0x04, 0xb8, 0x62, 0x7d, 0xfb, 0xb8, 0x70, 0x09, - 0x20, 0xb8, 0x56, 0x6d, + 0x20, 0xb8, 0x58, 0x6d, 0x01, 0x90, 0xc8, 0x30, 0xff, 0x6a, 0xa2, 0x00, - 0x00, 0x3d, 0xe0, 0x5c, + 0x00, 0x3d, 0xe2, 0x5c, 0x01, 0x64, 0x20, 0x31, 0xff, 0x6a, 0x78, 0x08, 0x00, 0x65, 0xea, 0x58, - 0x10, 0xb8, 0x6e, 0x7c, - 0xff, 0x6a, 0x66, 0x5d, - 0x00, 0x65, 0x6e, 0x44, - 0x00, 0x65, 0xc2, 0x5e, - 0x31, 0x6a, 0xea, 0x5e, - 0x00, 0x65, 0x6e, 0x44, + 0x10, 0xb8, 0x70, 0x7c, + 0xff, 0x6a, 0x68, 0x5d, + 0x00, 0x65, 0x70, 0x44, + 0x00, 0x65, 0xc4, 0x5e, + 0x31, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0x70, 0x44, 0x10, 0x3f, 0x06, 0x00, 0x10, 0x6a, 0x06, 0x00, 0x01, 0x65, 0x74, 0x34, - 0x81, 0x6a, 0xea, 0x5e, - 0x00, 0x65, 0x72, 0x45, + 0x81, 0x6a, 0xec, 0x5e, + 0x00, 0x65, 0x74, 0x45, 0x01, 0x06, 0xd4, 0x30, - 0x01, 0x0c, 0x72, 0x7d, - 0x04, 0x0c, 0x6c, 0x6d, + 0x01, 0x0c, 0x74, 0x7d, + 0x04, 0x0c, 0x6e, 0x6d, 0xe0, 0x03, 0x7e, 0x08, - 0xe0, 0x3f, 0xca, 0x61, + 0xe0, 0x3f, 0xcc, 0x61, 0x01, 0x65, 0xcc, 0x30, 0x01, 0x12, 0xda, 0x34, 0x01, 0x06, 0xd4, 0x34, - 0x01, 0x03, 0x80, 0x6d, + 0x01, 0x03, 0x82, 0x6d, 0x40, 0x03, 0xcc, 0x08, 0x01, 0x65, 0x06, 0x30, 0x40, 0x65, 0xc8, 0x08, - 0x00, 0x66, 0x8e, 0x75, - 0x40, 0x65, 0x8e, 0x7d, - 0x00, 0x65, 0x8e, 0x5d, + 0x00, 0x66, 0x90, 0x75, + 0x40, 0x65, 0x90, 0x7d, + 0x00, 0x65, 0x90, 0x5d, 0xff, 0x6a, 0xd4, 0x08, 0xff, 0x6a, 0xd4, 0x08, 0xff, 0x6a, 0xd4, 0x08, 0xff, 0x6a, 0xd4, 0x0c, 0x08, 0x01, 0x02, 0x00, - 0x02, 0x0b, 0x98, 0x7d, + 0x02, 0x0b, 0x9a, 0x7d, 0x01, 0x65, 0x0c, 0x30, - 0x02, 0x0b, 0x9c, 0x7d, + 0x02, 0x0b, 0x9e, 0x7d, 0xf7, 0x01, 0x02, 0x0c, 0x01, 0x65, 0xc8, 0x30, - 0xff, 0x41, 0xc0, 0x75, + 0xff, 0x41, 0xc2, 0x75, 0x01, 0x41, 0x20, 0x31, 0xff, 0x6a, 0xa4, 0x00, - 0x00, 0x65, 0xb0, 0x45, - 0xff, 0xbf, 0xc0, 0x75, + 0x00, 0x65, 0xb2, 0x45, + 0xff, 0xbf, 0xc2, 0x75, 0x01, 0x90, 0xa4, 0x30, 0x01, 0xbf, 0x20, 0x31, - 0x00, 0xbb, 0xaa, 0x65, - 0xff, 0x52, 0xbe, 0x75, + 0x00, 0xbb, 0xac, 0x65, + 0xff, 0x52, 0xc0, 0x75, 0x01, 0xbf, 0xcc, 0x30, 0x01, 0x90, 0xca, 0x30, 0x01, 0x52, 0x20, 0x31, @@ -743,28 +744,28 @@ 0x01, 0x65, 0x20, 0x35, 0x01, 0xbf, 0x82, 0x34, 0x01, 0x64, 0xa2, 0x30, - 0x00, 0x6a, 0xd2, 0x5e, + 0x00, 0x6a, 0xd4, 0x5e, 0x0d, 0x6a, 0x76, 0x00, - 0x00, 0x51, 0x24, 0x46, + 0x00, 0x51, 0x26, 0x46, 0x01, 0x65, 0xa4, 0x30, 0xe0, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0x18, 0x5e, + 0x48, 0x6a, 0x1a, 0x5e, 0x01, 0x6a, 0xd0, 0x01, 0x01, 0x6a, 0xdc, 0x05, 0x88, 0x6a, 0xcc, 0x00, - 0x48, 0x6a, 0x18, 0x5e, - 0x01, 0x6a, 0xf2, 0x5d, + 0x48, 0x6a, 0x1a, 0x5e, + 0x01, 0x6a, 0xf4, 0x5d, 0x01, 0x6a, 0x26, 0x05, 0x01, 0x65, 0xd8, 0x31, 0x09, 0xee, 0xdc, 0x01, - 0x80, 0xee, 0xde, 0x7d, + 0x80, 0xee, 0xe0, 0x7d, 0xff, 0x6a, 0xdc, 0x0d, 0x01, 0x65, 0x32, 0x31, 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0xba, 0x46, - 0x81, 0x6a, 0xea, 0x5e, - 0x01, 0x0c, 0xea, 0x7d, - 0x04, 0x0c, 0xe8, 0x6d, + 0x00, 0x65, 0xbc, 0x46, + 0x81, 0x6a, 0xec, 0x5e, + 0x01, 0x0c, 0xec, 0x7d, + 0x04, 0x0c, 0xea, 0x6d, 0xe0, 0x03, 0x06, 0x08, 0xe0, 0x03, 0x7e, 0x0c, 0x01, 0x65, 0x18, 0x31, @@ -783,7 +784,7 @@ 0x01, 0x6c, 0xda, 0x34, 0x3d, 0x64, 0xa4, 0x28, 0x55, 0x64, 0xc8, 0x28, - 0x00, 0x65, 0x18, 0x46, + 0x00, 0x65, 0x1a, 0x46, 0x2e, 0x64, 0xa4, 0x28, 0x66, 0x64, 0xc8, 0x28, 0x00, 0x6c, 0xda, 0x18, @@ -794,63 +795,63 @@ 0x00, 0x6c, 0xda, 0x24, 0x01, 0x65, 0xc8, 0x30, 0xe0, 0x6a, 0xcc, 0x00, - 0x44, 0x6a, 0x14, 0x5e, + 0x44, 0x6a, 0x16, 0x5e, 0x01, 0x90, 0xe2, 0x31, - 0x04, 0x3b, 0x38, 0x7e, + 0x04, 0x3b, 0x3a, 0x7e, 0x30, 0x6a, 0xd0, 0x01, 0x20, 0x6a, 0xd0, 0x01, 0x1d, 0x6a, 0xdc, 0x01, - 0xdc, 0xee, 0x34, 0x66, - 0x00, 0x65, 0x50, 0x46, + 0xdc, 0xee, 0x36, 0x66, + 0x00, 0x65, 0x52, 0x46, 0x20, 0x6a, 0xd0, 0x01, 0x01, 0x6a, 0xdc, 0x01, 0x20, 0xa0, 0xd8, 0x31, 0x09, 0xee, 0xdc, 0x01, - 0x80, 0xee, 0x40, 0x7e, + 0x80, 0xee, 0x42, 0x7e, 0x11, 0x6a, 0xdc, 0x01, - 0x50, 0xee, 0x44, 0x66, + 0x50, 0xee, 0x46, 0x66, 0x20, 0x6a, 0xd0, 0x01, 0x09, 0x6a, 0xdc, 0x01, - 0x88, 0xee, 0x4a, 0x66, + 0x88, 0xee, 0x4c, 0x66, 0x19, 0x6a, 0xdc, 0x01, - 0xd8, 0xee, 0x4e, 0x66, + 0xd8, 0xee, 0x50, 0x66, 0xff, 0x6a, 0xdc, 0x09, - 0x18, 0xee, 0x52, 0x6e, + 0x18, 0xee, 0x54, 0x6e, 0xff, 0x6a, 0xd4, 0x0c, 0x88, 0x6a, 0xcc, 0x00, - 0x44, 0x6a, 0x14, 0x5e, - 0x20, 0x6a, 0xf2, 0x5d, + 0x44, 0x6a, 0x16, 0x5e, + 0x20, 0x6a, 0xf4, 0x5d, 0x01, 0x3b, 0x26, 0x31, - 0x04, 0x3b, 0x6c, 0x6e, + 0x04, 0x3b, 0x6e, 0x6e, 0xa0, 0x6a, 0xca, 0x00, 0x20, 0x65, 0xc8, 0x18, - 0x00, 0x65, 0xaa, 0x5e, - 0x00, 0x65, 0x64, 0x66, + 0x00, 0x65, 0xac, 0x5e, + 0x00, 0x65, 0x66, 0x66, 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0xba, 0x46, + 0x00, 0x65, 0xbc, 0x46, 0xa0, 0x6a, 0xcc, 0x00, 0xff, 0x6a, 0xc8, 0x08, - 0x20, 0x94, 0x70, 0x6e, - 0x10, 0x94, 0x72, 0x6e, - 0x08, 0x94, 0x8c, 0x6e, - 0x08, 0x94, 0x8c, 0x6e, - 0x08, 0x94, 0x8c, 0x6e, + 0x20, 0x94, 0x72, 0x6e, + 0x10, 0x94, 0x74, 0x6e, + 0x08, 0x94, 0x8e, 0x6e, + 0x08, 0x94, 0x8e, 0x6e, + 0x08, 0x94, 0x8e, 0x6e, 0xff, 0x8c, 0xc8, 0x10, 0xc1, 0x64, 0xc8, 0x18, 0xf8, 0x64, 0xc8, 0x08, 0x01, 0x99, 0xda, 0x30, - 0x00, 0x66, 0x80, 0x66, - 0xc0, 0x66, 0xbc, 0x76, + 0x00, 0x66, 0x82, 0x66, + 0xc0, 0x66, 0xbe, 0x76, 0x60, 0x66, 0xc8, 0x18, 0x3d, 0x64, 0xc8, 0x28, - 0x00, 0x65, 0x70, 0x46, + 0x00, 0x65, 0x72, 0x46, 0xf7, 0x93, 0x26, 0x09, - 0x08, 0x93, 0x8e, 0x6e, + 0x08, 0x93, 0x90, 0x6e, 0x00, 0x62, 0xc4, 0x18, - 0x00, 0x65, 0xba, 0x5e, - 0x00, 0x65, 0x9a, 0x5e, - 0x00, 0x65, 0x9a, 0x5e, - 0x00, 0x65, 0x9a, 0x5e, + 0x00, 0x65, 0xbc, 0x5e, + 0x00, 0x65, 0x9c, 0x5e, + 0x00, 0x65, 0x9c, 0x5e, + 0x00, 0x65, 0x9c, 0x5e, 0x01, 0x99, 0xda, 0x30, 0x01, 0x99, 0xda, 0x30, 0x01, 0x99, 0xda, 0x30, @@ -867,11 +868,11 @@ 0x01, 0x6c, 0x32, 0x31, 0x01, 0x6c, 0x32, 0x31, 0x01, 0x6c, 0x32, 0x35, - 0x08, 0x94, 0xba, 0x7e, + 0x08, 0x94, 0xbc, 0x7e, 0xf7, 0x93, 0x26, 0x09, - 0x08, 0x93, 0xbe, 0x6e, + 0x08, 0x93, 0xc0, 0x6e, 0xff, 0x6a, 0xd4, 0x0c, - 0x04, 0xb8, 0xe6, 0x6e, + 0x04, 0xb8, 0xe8, 0x6e, 0x01, 0x42, 0x7e, 0x31, 0xff, 0x6a, 0x76, 0x01, 0x01, 0x90, 0x84, 0x34, @@ -879,14 +880,14 @@ 0x01, 0x85, 0x0a, 0x01, 0x7f, 0x65, 0x10, 0x09, 0xfe, 0x85, 0x0a, 0x0d, - 0xff, 0x42, 0xe2, 0x66, - 0xff, 0x41, 0xda, 0x66, - 0xd1, 0x6a, 0xea, 0x5e, + 0xff, 0x42, 0xe4, 0x66, + 0xff, 0x41, 0xdc, 0x66, + 0xd1, 0x6a, 0xec, 0x5e, 0xff, 0x6a, 0xca, 0x04, 0x01, 0x41, 0x20, 0x31, 0x01, 0xbf, 0x82, 0x30, 0x01, 0x6a, 0x76, 0x00, - 0x00, 0xbb, 0x24, 0x46, + 0x00, 0xbb, 0x26, 0x46, 0x01, 0x42, 0x20, 0x31, 0x01, 0xbf, 0x84, 0x34, 0x01, 0x41, 0x7e, 0x31, @@ -1140,163 +1141,163 @@ { ahc_patch1_func, 119, 1, 2 }, { ahc_patch0_func, 120, 1, 1 }, { ahc_patch7_func, 121, 4, 1 }, - { ahc_patch7_func, 131, 94, 11 }, + { ahc_patch7_func, 131, 95, 11 }, { ahc_patch4_func, 151, 1, 1 }, - { ahc_patch1_func, 167, 1, 1 }, - { ahc_patch12_func, 172, 1, 2 }, - { ahc_patch0_func, 173, 1, 1 }, - { ahc_patch9_func, 184, 1, 2 }, - { ahc_patch0_func, 185, 1, 1 }, - { ahc_patch9_func, 194, 1, 2 }, - { ahc_patch0_func, 195, 1, 1 }, - { ahc_patch9_func, 211, 6, 2 }, - { ahc_patch0_func, 217, 6, 1 }, - { ahc_patch8_func, 225, 20, 2 }, - { ahc_patch1_func, 240, 1, 1 }, - { ahc_patch1_func, 247, 1, 2 }, - { ahc_patch0_func, 248, 2, 2 }, - { ahc_patch11_func, 249, 1, 1 }, - { ahc_patch9_func, 257, 31, 3 }, - { ahc_patch1_func, 273, 14, 2 }, - { ahc_patch13_func, 278, 1, 1 }, - { ahc_patch14_func, 288, 14, 1 }, - { ahc_patch1_func, 304, 1, 2 }, - { ahc_patch0_func, 305, 1, 1 }, - { ahc_patch9_func, 308, 1, 1 }, - { ahc_patch13_func, 313, 1, 1 }, - { ahc_patch9_func, 314, 2, 2 }, - { ahc_patch0_func, 316, 4, 1 }, - { ahc_patch14_func, 320, 1, 1 }, - { ahc_patch15_func, 323, 2, 3 }, - { ahc_patch9_func, 323, 1, 2 }, - { ahc_patch0_func, 324, 1, 1 }, - { ahc_patch6_func, 329, 1, 2 }, - { ahc_patch0_func, 330, 1, 1 }, - { ahc_patch1_func, 334, 50, 11 }, - { ahc_patch6_func, 343, 2, 4 }, - { ahc_patch7_func, 343, 1, 1 }, - { ahc_patch8_func, 344, 1, 1 }, - { ahc_patch0_func, 345, 1, 1 }, - { ahc_patch16_func, 346, 1, 1 }, - { ahc_patch6_func, 365, 6, 3 }, - { ahc_patch16_func, 365, 5, 1 }, - { ahc_patch0_func, 371, 5, 1 }, - { ahc_patch13_func, 379, 5, 1 }, - { ahc_patch0_func, 384, 54, 17 }, - { ahc_patch14_func, 384, 1, 1 }, - { ahc_patch7_func, 386, 2, 2 }, - { ahc_patch17_func, 387, 1, 1 }, - { ahc_patch9_func, 390, 1, 1 }, - { ahc_patch18_func, 397, 1, 1 }, - { ahc_patch14_func, 402, 9, 3 }, - { ahc_patch9_func, 403, 3, 2 }, - { ahc_patch0_func, 406, 3, 1 }, - { ahc_patch9_func, 414, 6, 2 }, - { ahc_patch0_func, 420, 9, 2 }, - { ahc_patch13_func, 420, 1, 1 }, - { ahc_patch13_func, 429, 2, 1 }, - { ahc_patch14_func, 431, 1, 1 }, - { ahc_patch9_func, 433, 1, 2 }, - { ahc_patch0_func, 434, 1, 1 }, - { ahc_patch7_func, 437, 1, 1 }, + { ahc_patch1_func, 168, 1, 1 }, + { ahc_patch12_func, 173, 1, 2 }, + { ahc_patch0_func, 174, 1, 1 }, + { ahc_patch9_func, 185, 1, 2 }, + { ahc_patch0_func, 186, 1, 1 }, + { ahc_patch9_func, 195, 1, 2 }, + { ahc_patch0_func, 196, 1, 1 }, + { ahc_patch9_func, 212, 6, 2 }, + { ahc_patch0_func, 218, 6, 1 }, + { ahc_patch8_func, 226, 20, 2 }, + { ahc_patch1_func, 241, 1, 1 }, + { ahc_patch1_func, 248, 1, 2 }, + { ahc_patch0_func, 249, 2, 2 }, + { ahc_patch11_func, 250, 1, 1 }, + { ahc_patch9_func, 258, 31, 3 }, + { ahc_patch1_func, 274, 14, 2 }, + { ahc_patch13_func, 279, 1, 1 }, + { ahc_patch14_func, 289, 14, 1 }, + { ahc_patch1_func, 305, 1, 2 }, + { ahc_patch0_func, 306, 1, 1 }, + { ahc_patch9_func, 309, 1, 1 }, + { ahc_patch13_func, 314, 1, 1 }, + { ahc_patch9_func, 315, 2, 2 }, + { ahc_patch0_func, 317, 4, 1 }, + { ahc_patch14_func, 321, 1, 1 }, + { ahc_patch15_func, 324, 2, 3 }, + { ahc_patch9_func, 324, 1, 2 }, + { ahc_patch0_func, 325, 1, 1 }, + { ahc_patch6_func, 330, 1, 2 }, + { ahc_patch0_func, 331, 1, 1 }, + { ahc_patch1_func, 335, 50, 11 }, + { ahc_patch6_func, 344, 2, 4 }, + { ahc_patch7_func, 344, 1, 1 }, + { ahc_patch8_func, 345, 1, 1 }, + { ahc_patch0_func, 346, 1, 1 }, + { ahc_patch16_func, 347, 1, 1 }, + { ahc_patch6_func, 366, 6, 3 }, + { ahc_patch16_func, 366, 5, 1 }, + { ahc_patch0_func, 372, 5, 1 }, + { ahc_patch13_func, 380, 5, 1 }, + { ahc_patch0_func, 385, 54, 17 }, + { ahc_patch14_func, 385, 1, 1 }, + { ahc_patch7_func, 387, 2, 2 }, + { ahc_patch17_func, 388, 1, 1 }, + { ahc_patch9_func, 391, 1, 1 }, + { ahc_patch18_func, 398, 1, 1 }, + { ahc_patch14_func, 403, 9, 3 }, + { ahc_patch9_func, 404, 3, 2 }, + { ahc_patch0_func, 407, 3, 1 }, + { ahc_patch9_func, 415, 6, 2 }, + { ahc_patch0_func, 421, 9, 2 }, + { ahc_patch13_func, 421, 1, 1 }, + { ahc_patch13_func, 430, 2, 1 }, + { ahc_patch14_func, 432, 1, 1 }, + { ahc_patch9_func, 434, 1, 2 }, + { ahc_patch0_func, 435, 1, 1 }, { ahc_patch7_func, 438, 1, 1 }, - { ahc_patch8_func, 439, 3, 3 }, - { ahc_patch6_func, 440, 1, 2 }, - { ahc_patch0_func, 441, 1, 1 }, - { ahc_patch9_func, 442, 1, 1 }, - { ahc_patch15_func, 443, 1, 2 }, - { ahc_patch13_func, 443, 1, 1 }, - { ahc_patch14_func, 445, 9, 4 }, - { ahc_patch9_func, 445, 1, 1 }, - { ahc_patch9_func, 452, 2, 1 }, - { ahc_patch0_func, 454, 4, 3 }, - { ahc_patch9_func, 454, 1, 2 }, - { ahc_patch0_func, 455, 3, 1 }, - { ahc_patch1_func, 459, 2, 1 }, - { ahc_patch7_func, 461, 10, 2 }, - { ahc_patch0_func, 471, 1, 1 }, - { ahc_patch8_func, 472, 118, 22 }, - { ahc_patch1_func, 474, 3, 2 }, - { ahc_patch0_func, 477, 5, 3 }, - { ahc_patch9_func, 477, 2, 2 }, - { ahc_patch0_func, 479, 3, 1 }, - { ahc_patch1_func, 484, 2, 2 }, - { ahc_patch0_func, 486, 6, 3 }, - { ahc_patch9_func, 486, 2, 2 }, - { ahc_patch0_func, 488, 3, 1 }, - { ahc_patch1_func, 494, 2, 2 }, - { ahc_patch0_func, 496, 9, 7 }, - { ahc_patch9_func, 496, 5, 6 }, - { ahc_patch19_func, 496, 1, 2 }, - { ahc_patch0_func, 497, 1, 1 }, - { ahc_patch19_func, 499, 1, 2 }, - { ahc_patch0_func, 500, 1, 1 }, - { ahc_patch0_func, 501, 4, 1 }, - { ahc_patch6_func, 506, 3, 2 }, - { ahc_patch0_func, 509, 1, 1 }, - { ahc_patch6_func, 519, 1, 2 }, - { ahc_patch0_func, 520, 1, 1 }, - { ahc_patch20_func, 557, 7, 1 }, - { ahc_patch3_func, 592, 1, 2 }, - { ahc_patch0_func, 593, 1, 1 }, - { ahc_patch21_func, 596, 1, 1 }, - { ahc_patch8_func, 598, 106, 33 }, - { ahc_patch4_func, 600, 1, 1 }, - { ahc_patch1_func, 606, 2, 2 }, - { ahc_patch0_func, 608, 1, 1 }, - { ahc_patch1_func, 611, 1, 2 }, - { ahc_patch0_func, 612, 1, 1 }, - { ahc_patch9_func, 613, 3, 3 }, - { ahc_patch15_func, 614, 1, 1 }, - { ahc_patch0_func, 616, 4, 1 }, - { ahc_patch19_func, 625, 2, 2 }, - { ahc_patch0_func, 627, 1, 1 }, - { ahc_patch19_func, 631, 10, 3 }, - { ahc_patch5_func, 633, 8, 1 }, - { ahc_patch0_func, 641, 9, 2 }, - { ahc_patch5_func, 642, 8, 1 }, - { ahc_patch4_func, 652, 1, 2 }, - { ahc_patch0_func, 653, 1, 1 }, - { ahc_patch19_func, 654, 1, 2 }, - { ahc_patch0_func, 655, 3, 2 }, - { ahc_patch4_func, 657, 1, 1 }, - { ahc_patch5_func, 658, 1, 1 }, - { ahc_patch5_func, 661, 1, 1 }, - { ahc_patch5_func, 663, 1, 1 }, - { ahc_patch4_func, 665, 2, 2 }, - { ahc_patch0_func, 667, 2, 1 }, - { ahc_patch5_func, 669, 1, 1 }, - { ahc_patch5_func, 672, 1, 1 }, - { ahc_patch5_func, 675, 1, 1 }, - { ahc_patch19_func, 679, 1, 1 }, - { ahc_patch19_func, 682, 1, 1 }, - { ahc_patch4_func, 688, 1, 1 }, - { ahc_patch6_func, 691, 1, 2 }, - { ahc_patch0_func, 692, 1, 1 }, - { ahc_patch7_func, 704, 16, 1 }, - { ahc_patch4_func, 720, 20, 1 }, - { ahc_patch9_func, 741, 4, 2 }, - { ahc_patch0_func, 745, 4, 1 }, - { ahc_patch9_func, 749, 4, 2 }, - { ahc_patch0_func, 753, 3, 1 }, - { ahc_patch6_func, 759, 1, 1 }, - { ahc_patch22_func, 761, 14, 1 }, - { ahc_patch7_func, 775, 3, 1 }, - { ahc_patch9_func, 787, 24, 8 }, - { ahc_patch19_func, 791, 1, 2 }, - { ahc_patch0_func, 792, 1, 1 }, - { ahc_patch15_func, 797, 4, 2 }, - { ahc_patch0_func, 801, 7, 3 }, - { ahc_patch23_func, 801, 5, 2 }, - { ahc_patch0_func, 806, 2, 1 }, - { ahc_patch0_func, 811, 42, 3 }, - { ahc_patch18_func, 823, 18, 2 }, - { ahc_patch0_func, 841, 1, 1 }, - { ahc_patch4_func, 865, 1, 1 }, - { ahc_patch4_func, 866, 3, 2 }, - { ahc_patch0_func, 869, 1, 1 }, - { ahc_patch13_func, 870, 3, 1 }, - { ahc_patch4_func, 873, 12, 1 } + { ahc_patch7_func, 439, 1, 1 }, + { ahc_patch8_func, 440, 3, 3 }, + { ahc_patch6_func, 441, 1, 2 }, + { ahc_patch0_func, 442, 1, 1 }, + { ahc_patch9_func, 443, 1, 1 }, + { ahc_patch15_func, 444, 1, 2 }, + { ahc_patch13_func, 444, 1, 1 }, + { ahc_patch14_func, 446, 9, 4 }, + { ahc_patch9_func, 446, 1, 1 }, + { ahc_patch9_func, 453, 2, 1 }, + { ahc_patch0_func, 455, 4, 3 }, + { ahc_patch9_func, 455, 1, 2 }, + { ahc_patch0_func, 456, 3, 1 }, + { ahc_patch1_func, 460, 2, 1 }, + { ahc_patch7_func, 462, 10, 2 }, + { ahc_patch0_func, 472, 1, 1 }, + { ahc_patch8_func, 473, 118, 22 }, + { ahc_patch1_func, 475, 3, 2 }, + { ahc_patch0_func, 478, 5, 3 }, + { ahc_patch9_func, 478, 2, 2 }, + { ahc_patch0_func, 480, 3, 1 }, + { ahc_patch1_func, 485, 2, 2 }, + { ahc_patch0_func, 487, 6, 3 }, + { ahc_patch9_func, 487, 2, 2 }, + { ahc_patch0_func, 489, 3, 1 }, + { ahc_patch1_func, 495, 2, 2 }, + { ahc_patch0_func, 497, 9, 7 }, + { ahc_patch9_func, 497, 5, 6 }, + { ahc_patch19_func, 497, 1, 2 }, + { ahc_patch0_func, 498, 1, 1 }, + { ahc_patch19_func, 500, 1, 2 }, + { ahc_patch0_func, 501, 1, 1 }, + { ahc_patch0_func, 502, 4, 1 }, + { ahc_patch6_func, 507, 3, 2 }, + { ahc_patch0_func, 510, 1, 1 }, + { ahc_patch6_func, 520, 1, 2 }, + { ahc_patch0_func, 521, 1, 1 }, + { ahc_patch20_func, 558, 7, 1 }, + { ahc_patch3_func, 593, 1, 2 }, + { ahc_patch0_func, 594, 1, 1 }, + { ahc_patch21_func, 597, 1, 1 }, + { ahc_patch8_func, 599, 106, 33 }, + { ahc_patch4_func, 601, 1, 1 }, + { ahc_patch1_func, 607, 2, 2 }, + { ahc_patch0_func, 609, 1, 1 }, + { ahc_patch1_func, 612, 1, 2 }, + { ahc_patch0_func, 613, 1, 1 }, + { ahc_patch9_func, 614, 3, 3 }, + { ahc_patch15_func, 615, 1, 1 }, + { ahc_patch0_func, 617, 4, 1 }, + { ahc_patch19_func, 626, 2, 2 }, + { ahc_patch0_func, 628, 1, 1 }, + { ahc_patch19_func, 632, 10, 3 }, + { ahc_patch5_func, 634, 8, 1 }, + { ahc_patch0_func, 642, 9, 2 }, + { ahc_patch5_func, 643, 8, 1 }, + { ahc_patch4_func, 653, 1, 2 }, + { ahc_patch0_func, 654, 1, 1 }, + { ahc_patch19_func, 655, 1, 2 }, + { ahc_patch0_func, 656, 3, 2 }, + { ahc_patch4_func, 658, 1, 1 }, + { ahc_patch5_func, 659, 1, 1 }, + { ahc_patch5_func, 662, 1, 1 }, + { ahc_patch5_func, 664, 1, 1 }, + { ahc_patch4_func, 666, 2, 2 }, + { ahc_patch0_func, 668, 2, 1 }, + { ahc_patch5_func, 670, 1, 1 }, + { ahc_patch5_func, 673, 1, 1 }, + { ahc_patch5_func, 676, 1, 1 }, + { ahc_patch19_func, 680, 1, 1 }, + { ahc_patch19_func, 683, 1, 1 }, + { ahc_patch4_func, 689, 1, 1 }, + { ahc_patch6_func, 692, 1, 2 }, + { ahc_patch0_func, 693, 1, 1 }, + { ahc_patch7_func, 705, 16, 1 }, + { ahc_patch4_func, 721, 20, 1 }, + { ahc_patch9_func, 742, 4, 2 }, + { ahc_patch0_func, 746, 4, 1 }, + { ahc_patch9_func, 750, 4, 2 }, + { ahc_patch0_func, 754, 3, 1 }, + { ahc_patch6_func, 760, 1, 1 }, + { ahc_patch22_func, 762, 14, 1 }, + { ahc_patch7_func, 776, 3, 1 }, + { ahc_patch9_func, 788, 24, 8 }, + { ahc_patch19_func, 792, 1, 2 }, + { ahc_patch0_func, 793, 1, 1 }, + { ahc_patch15_func, 798, 4, 2 }, + { ahc_patch0_func, 802, 7, 3 }, + { ahc_patch23_func, 802, 5, 2 }, + { ahc_patch0_func, 807, 2, 1 }, + { ahc_patch0_func, 812, 42, 3 }, + { ahc_patch18_func, 824, 18, 2 }, + { ahc_patch0_func, 842, 1, 1 }, + { ahc_patch4_func, 866, 1, 1 }, + { ahc_patch4_func, 867, 3, 2 }, + { ahc_patch0_func, 870, 1, 1 }, + { ahc_patch13_func, 871, 3, 1 }, + { ahc_patch4_func, 874, 12, 1 } }; static struct cs { @@ -1305,11 +1306,11 @@ } critical_sections[] = { { 11, 18 }, { 21, 30 }, - { 720, 736 }, - { 866, 869 }, - { 873, 879 }, - { 881, 883 }, - { 883, 885 } + { 721, 737 }, + { 867, 870 }, + { 874, 880 }, + { 882, 884 }, + { 884, 886 } }; static const int num_critical_sections = sizeof(critical_sections) diff -Nru a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c --- a/drivers/scsi/aic7xxx/aiclib.c Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/aic7xxx/aiclib.c Sun Feb 9 21:13:32 2003 @@ -1230,3 +1230,106 @@ */ return (10000000 / (period_factor * 4 * 10)); } + +/* + * Return speed in KB/s. + */ +u_int +aic_calc_speed(u_int width, u_int period, u_int offset, u_int min_rate) +{ + u_int freq; + + if (offset != 0 && period < min_rate) + freq = aic_calc_syncsrate(period); + else + /* Roughly 3.3MB/s for async */ + freq = 3300; + freq <<= width; + return (freq); +} + +uint32_t +aic_error_action(struct scsi_cmnd *cmd, struct scsi_inquiry_data *inq_data, + cam_status status, u_int scsi_status) +{ + aic_sense_action err_action; + int sense; + + sense = (cmd->result >> 24) == DRIVER_SENSE; + + switch (status) { + case CAM_REQ_CMP: + err_action = SS_NOP; + break; + case CAM_AUTOSENSE_FAIL: + case CAM_SCSI_STATUS_ERROR: + + switch (scsi_status) { + case SCSI_STATUS_OK: + case SCSI_STATUS_COND_MET: + case SCSI_STATUS_INTERMED: + case SCSI_STATUS_INTERMED_COND_MET: + err_action = SS_NOP; + break; + case SCSI_STATUS_CMD_TERMINATED: + case SCSI_STATUS_CHECK_COND: + if (sense != 0) { + struct scsi_sense_data *sense; + + sense = (struct scsi_sense_data *) + &cmd->sense_buffer; + err_action = + aic_sense_error_action(sense, inq_data, 0); + + } else { + err_action = SS_RETRY|SSQ_FALLBACK + | SSQ_DECREMENT_COUNT|EIO; + } + break; + case SCSI_STATUS_QUEUE_FULL: + case SCSI_STATUS_BUSY: + err_action = SS_RETRY|SSQ_DELAY|SSQ_MANY + | SSQ_DECREMENT_COUNT|EBUSY; + break; + case SCSI_STATUS_RESERV_CONFLICT: + default: + err_action = SS_FAIL|EBUSY; + break; + } + break; + case CAM_CMD_TIMEOUT: + case CAM_REQ_CMP_ERR: + case CAM_UNEXP_BUSFREE: + case CAM_UNCOR_PARITY: + case CAM_DATA_RUN_ERR: + err_action = SS_RETRY|SSQ_FALLBACK|EIO; + break; + case CAM_UA_ABORT: + case CAM_UA_TERMIO: + case CAM_MSG_REJECT_REC: + case CAM_SEL_TIMEOUT: + err_action = SS_FAIL|EIO; + break; + case CAM_REQ_INVALID: + case CAM_PATH_INVALID: + case CAM_DEV_NOT_THERE: + case CAM_NO_HBA: + case CAM_PROVIDE_FAIL: + case CAM_REQ_TOO_BIG: + case CAM_RESRC_UNAVAIL: + case CAM_BUSY: + default: + /* panic?? These should never occur in our application. */ + err_action = SS_FAIL|EIO; + break; + case CAM_SCSI_BUS_RESET: + case CAM_BDR_SENT: + case CAM_REQUEUE_REQ: + /* Unconditional requeue */ + err_action = SS_RETRY; + break; + } + + return (err_action); +} + diff -Nru a/drivers/scsi/aic7xxx/aiclib.h b/drivers/scsi/aic7xxx/aiclib.h --- a/drivers/scsi/aic7xxx/aiclib.h Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/aic7xxx/aiclib.h Sun Feb 9 21:13:28 2003 @@ -861,11 +861,13 @@ #define aic_sense_desc AIC_LIB_ENTRY(_sense_desc) #define aic_sense_error_action AIC_LIB_ENTRY(_sense_error_action) +#define aic_error_action AIC_LIB_ENTRY(_error_action) #define aic_op_desc AIC_LIB_ENTRY(_op_desc) #define aic_cdb_string AIC_LIB_ENTRY(_cdb_string) #define aic_print_inquiry AIC_LIB_ENTRY(_print_inquiry) #define aic_calc_syncsrate AIC_LIB_ENTRY(_calc_syncrate) #define aic_calc_syncparam AIC_LIB_ENTRY(_calc_syncparam) +#define aic_calc_speed AIC_LIB_ENTRY(_calc_speed) #define aic_inquiry_match AIC_LIB_ENTRY(_inquiry_match) #define aic_static_inquiry_match AIC_LIB_ENTRY(_static_inquiry_match) @@ -878,6 +880,9 @@ aic_sense_action aic_sense_error_action(struct scsi_sense_data*, struct scsi_inquiry_data*, uint32_t /*sense_flags*/); +uint32_t aic_error_action(struct scsi_cmnd *, + struct scsi_inquiry_data *, + cam_status, u_int); #define SF_RETRY_UA 0x01 #define SF_NO_PRINT 0x02 @@ -892,6 +897,8 @@ u_int aic_calc_syncsrate(u_int /*period_factor*/); u_int aic_calc_syncparam(u_int /*period*/); +u_int aic_calc_speed(u_int width, u_int period, u_int offset, + u_int min_rate); int aic_inquiry_match(caddr_t /*inqbuffer*/, caddr_t /*table_entry*/); diff -Nru a/drivers/scsi/aic7xxx/scsi_iu.h b/drivers/scsi/aic7xxx/scsi_iu.h --- a/drivers/scsi/aic7xxx/scsi_iu.h Sun Feb 9 21:13:31 2003 +++ b/drivers/scsi/aic7xxx/scsi_iu.h Sun Feb 9 21:13:31 2003 @@ -28,4 +28,12 @@ (12 + (((siu)->flags & SIU_RSPVALID) \ ? scsi_4btoul((siu)->pkt_failures_length) \ : 0)) + +#define SIU_TASKMGMT_NONE 0x00 +#define SIU_TASKMGMT_ABORT_TASK 0x01 +#define SIU_TASKMGMT_ABORT_TASK_SET 0x02 +#define SIU_TASKMGMT_CLEAR_TASK_SET 0x04 +#define SIU_TASKMGMT_LUN_RESET 0x08 +#define SIU_TASKMGMT_TARGET_RESET 0x20 +#define SIU_TASKMGMT_CLEAR_ACA 0x40 #endif /*_SCSI_SCSI_IU_H*/ diff -Nru a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c --- a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c Sun Feb 9 21:13:35 2003 +++ b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c Sun Feb 9 21:13:35 2003 @@ -313,7 +313,7 @@ p->user[tindex].options); if(sdptr->simple_tags) { - size += sprintf(BLS, " Tagged Command Queueing Enabled, Ordered Tags %s, Depth %d/%d\n", sdptr->ordered_tags ? "Enabled" : "Disabled", sdptr->new_queue_depth, aic_dev->max_q_depth); + size += sprintf(BLS, " Tagged Command Queueing Enabled, Ordered Tags %s, Depth %d/%d\n", sdptr->ordered_tags ? "Enabled" : "Disabled", sdptr->queue_depth, aic_dev->max_q_depth); } if(aic_dev->barrier_total) size += sprintf(BLS, " Total transfers %ld:\n (%ld/%ld/%ld/%ld reads/writes/REQ_BARRIER/Ordered Tags)\n", diff -Nru a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c --- a/drivers/scsi/aic7xxx_old.c Sun Feb 9 21:13:31 2003 +++ b/drivers/scsi/aic7xxx_old.c Sun Feb 9 21:13:31 2003 @@ -1040,11 +1040,11 @@ (((scb->hscb)->target_channel_lun >> 4) & 0xf), \ ((scb->hscb)->target_channel_lun & 0x07) -#define CTL_OF_CMD(cmd) ((cmd->channel) & 0x01), \ - ((cmd->target) & 0x0f), \ - ((cmd->lun) & 0x07) +#define CTL_OF_CMD(cmd) ((cmd->device->channel) & 0x01), \ + ((cmd->device->id) & 0x0f), \ + ((cmd->device->lun) & 0x07) -#define TARGET_INDEX(cmd) ((cmd)->target | ((cmd)->channel << 3)) +#define TARGET_INDEX(cmd) ((cmd)->device->id | ((cmd)->device->channel << 3)) /* * A nice little define to make doing our printks a little easier @@ -2557,7 +2557,7 @@ * than the right hand side. If the number of SG array elements * is changed, this function may not be near so efficient any more. * - * Since the DMA'able buffers are now allocated in a seperate + * Since the DMA'able buffers are now allocated in a separate * chunk this algorithm has been modified to match. The '12' * and '6' factors in scb_size are for the DMA'able command byte * and sensebuffers respectively. -DaveM @@ -4068,7 +4068,7 @@ * normal. */ scsi_adjust_queue_depth(scb->cmd->device, MSG_SIMPLE_TAG, - scb->cmd->device->new_queue_depth); + scb->cmd->device->queue_depth); scb->tag_action = MSG_SIMPLE_Q_TAG; scb->hscb->control &= ~SCB_TAG_TYPE; scb->hscb->control |= MSG_SIMPLE_Q_TAG; @@ -4284,7 +4284,7 @@ memcpy(scb->sense_cmd, &generic_sense[0], sizeof(generic_sense)); - scb->sense_cmd[1] = (cmd->lun << 5); + scb->sense_cmd[1] = (cmd->device->lun << 5); scb->sense_cmd[4] = sizeof(cmd->sense_buffer); scb->sg_list[0].length = @@ -4935,9 +4935,9 @@ struct aic7xxx_syncrate *syncrate; struct aic_dev_data *aic_dev; - target = scb->cmd->target; - channel = scb->cmd->channel; - lun = scb->cmd->lun; + target = scb->cmd->device->id; + channel = scb->cmd->device->channel; + lun = scb->cmd->device->lun; reply = reject = done = FALSE; tindex = TARGET_INDEX(scb->cmd); aic_dev = AIC_DEV(scb->cmd); @@ -6026,11 +6026,11 @@ */ aic_dev = AIC_DEV(scb->cmd); aic_dev->needppr = aic_dev->needppr_copy = 0; - aic7xxx_set_width(p, scb->cmd->target, scb->cmd->channel, scb->cmd->lun, + aic7xxx_set_width(p, scb->cmd->device->id, scb->cmd->device->channel, scb->cmd->device->lun, MSG_EXT_WDTR_BUS_8_BIT, (AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE), aic_dev); - aic7xxx_set_syncrate(p, NULL, scb->cmd->target, scb->cmd->channel, 0, 0, + aic7xxx_set_syncrate(p, NULL, scb->cmd->device->id, scb->cmd->device->channel, 0, 0, 0, AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE, aic_dev); aic_dev->goal.options = 0; @@ -6307,8 +6307,8 @@ unpause_sequencer(p, FALSE); continue; } - aic7xxx_reset_device(p, scb->cmd->target, scb->cmd->channel, - scb->cmd->lun, scb->hscb->tag); + aic7xxx_reset_device(p, scb->cmd->device->id, scb->cmd->device->channel, + scb->cmd->device->lun, scb->hscb->tag); scb->flags &= ~(SCB_QUEUED_FOR_DONE | SCB_RESET | SCB_ABORT | SCB_QUEUED_ABORT); unpause_sequencer(p, FALSE); @@ -10201,8 +10201,8 @@ } scb->flags |= SCB_DTR_SCB; } - hscb->target_channel_lun = ((cmd->target << 4) & 0xF0) | - ((cmd->channel & 0x01) << 3) | (cmd->lun & 0x07); + hscb->target_channel_lun = ((cmd->device->id << 4) & 0xF0) | + ((cmd->device->channel & 0x01) << 3) | (cmd->device->lun & 0x07); /* * The interpretation of request_buffer and request_bufflen @@ -10298,7 +10298,7 @@ struct aic7xxx_scb *scb; struct aic_dev_data *aic_dev; - p = (struct aic7xxx_host *) cmd->host->hostdata; + p = (struct aic7xxx_host *) cmd->device->host->hostdata; aic_dev = cmd->device->hostdata; #ifdef AIC7XXX_VERBOSE_DEBUGGING @@ -10379,7 +10379,7 @@ printk(KERN_ERR "aic7xxx_bus_device_reset: called with NULL cmd!\n"); return FAILED; } - p = (struct aic7xxx_host *)cmd->host->hostdata; + p = (struct aic7xxx_host *)cmd->device->host->hostdata; aic_dev = AIC_DEV(cmd); if(aic7xxx_position(cmd) < p->scb_data->numscbs) scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]); @@ -10441,7 +10441,7 @@ aic_inb(p, STCNT)); } - channel = cmd->channel; + channel = cmd->device->channel; /* * Send a Device Reset Message: @@ -10508,7 +10508,7 @@ * Check to see if the command is on the qinfifo. If it is, then we will * not need to queue the command again since the card should start it soon */ - if (aic7xxx_search_qinfifo(p, cmd->channel, cmd->target, cmd->lun, hscb->tag, + if (aic7xxx_search_qinfifo(p, cmd->device->channel, cmd->device->id, cmd->device->lun, hscb->tag, 0, TRUE, NULL) == 0) { disconnected = TRUE; @@ -10604,7 +10604,7 @@ printk(KERN_ERR "aic7xxx_abort: called with NULL cmd!\n"); return FAILED; } - p = (struct aic7xxx_host *)cmd->host->hostdata; + p = (struct aic7xxx_host *)cmd->device->host->hostdata; aic_dev = AIC_DEV(cmd); if(aic7xxx_position(cmd) < p->scb_data->numscbs) scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]); @@ -10664,8 +10664,8 @@ /* * We just checked the waiting_q, now for the QINFIFO */ - if ( ((found = aic7xxx_search_qinfifo(p, cmd->target, cmd->channel, - cmd->lun, scb->hscb->tag, SCB_ABORT | SCB_QUEUED_FOR_DONE, + if ( ((found = aic7xxx_search_qinfifo(p, cmd->device->id, cmd->device->channel, + cmd->device->lun, scb->hscb->tag, SCB_ABORT | SCB_QUEUED_FOR_DONE, FALSE, NULL)) != 0) && (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)) { @@ -10825,7 +10825,7 @@ struct aic7xxx_host *p; struct aic_dev_data *aic_dev; - p = (struct aic7xxx_host *) cmd->host->hostdata; + p = (struct aic7xxx_host *) cmd->device->host->hostdata; aic_dev = AIC_DEV(cmd); if(aic7xxx_position(cmd) < p->scb_data->numscbs) { @@ -10872,10 +10872,10 @@ * By this point, we want to already know what we are going to do and * only have the following code implement our course of action. */ - aic7xxx_reset_channel(p, cmd->channel, TRUE); + aic7xxx_reset_channel(p, cmd->device->channel, TRUE); if (p->features & AHC_TWIN) { - aic7xxx_reset_channel(p, cmd->channel ^ 0x01, TRUE); + aic7xxx_reset_channel(p, cmd->device->channel ^ 0x01, TRUE); restart_sequencer(p); } aic_outb(p, aic_inb(p, SIMODE1) & ~(ENREQINIT|ENBUSFREE), SIMODE1); diff -Nru a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c --- a/drivers/scsi/atp870u.c Sun Feb 9 21:13:31 2003 +++ b/drivers/scsi/atp870u.c Sun Feb 9 21:13:31 2003 @@ -492,17 +492,17 @@ struct Scsi_Host *host; struct atp_unit *dev; - if (req_p->channel != 0) { + if (req_p->device->channel != 0) { req_p->result = 0x00040000; done(req_p); return 0; }; - host = req_p->host; + host = req_p->device->host; dev = (struct atp_unit *)&host->hostdata; m = 1; - m = m << req_p->target; + m = m << req_p->device->id; /* * Fake a timeout for missing targets @@ -600,9 +600,9 @@ dev->quhdu = 0; } workrequ = dev->querequ[dev->quhdu]; - if (dev->id[workrequ->target].curr_req == 0) { - dev->id[workrequ->target].curr_req = workrequ; - dev->last_cmd = workrequ->target; + if (dev->id[workrequ->device->id].curr_req == 0) { + dev->id[workrequ->device->id].curr_req = workrequ; + dev->last_cmd = workrequ->device->id; goto cmd_subp; } dev->quhdu = j; @@ -638,7 +638,7 @@ tmport = workportu + 0x1b; j = 0; - target_id = workrequ->target; + target_id = workrequ->device->id; /* * Wide ? @@ -665,7 +665,7 @@ outb(dev->ata_cdbu[i], tmport++); } tmport = workportu + 0x0f; - outb(workrequ->lun, tmport); + outb(workrequ->device->lun, tmport); tmport += 0x02; /* * Write the target @@ -2606,7 +2606,7 @@ unsigned char j, k; Scsi_Cmnd *workrequ; unsigned int tmport; - struct atp_unit *dev = (struct atp_unit *)&SCpnt->host->hostdata; + struct atp_unit *dev = (struct atp_unit *)&SCpnt->device->host->hostdata; printk(KERN_DEBUG "working=%x last_cmd=%x ", dev->working, dev->last_cmd); printk(" quhdu=%x quendu=%x ", dev->quhdu, dev->quendu); diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c --- a/drivers/scsi/constants.c Sun Feb 9 21:13:34 2003 +++ b/drivers/scsi/constants.c Sun Feb 9 21:13:34 2003 @@ -1118,9 +1118,9 @@ void print_Scsi_Cmnd (Scsi_Cmnd *cmd) { printk("scsi%d : destination target %d, lun %d\n", - cmd->host->host_no, - cmd->target, - cmd->lun); + cmd->device->host->host_no, + cmd->device->id, + cmd->device->lun); printk(" command = "); print_command (cmd->cmnd); } diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c --- a/drivers/scsi/cpqfcTSinit.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/cpqfcTSinit.c Sun Feb 9 21:13:28 2003 @@ -730,9 +730,12 @@ case CPQFC_IOCTL_FC_TARGET_ADDRESS: // can we find an FC device mapping to this SCSI target? - DumCmnd.channel = ScsiDev->channel; // For searching - DumCmnd.target = ScsiDev->id; - DumCmnd.lun = ScsiDev->lun; +/* DumCmnd.channel = ScsiDev->channel; */ // For searching +/* DumCmnd.target = ScsiDev->id; */ +/* DumCmnd.lun = ScsiDev->lun; */ + + DumCmnd.device = ScsiDev; + pLoggedInPort = fcFindLoggedInPort( fcChip, &DumCmnd, // search Scsi Nexus 0, // DON'T search linked list for FC port id @@ -1297,7 +1300,7 @@ int cpqfcTS_queuecommand(Scsi_Cmnd *Cmnd, void (* done)(Scsi_Cmnd *)) { - struct Scsi_Host *HostAdapter = Cmnd->host; + struct Scsi_Host *HostAdapter = Cmnd->device->host; CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; PTACHYON fcChip = &cpqfcHBAdata->fcChip; TachFCHDR_GCMND fchs; // only use for FC destination id field @@ -1353,9 +1356,9 @@ // printk(" @Q bad targ cmnd %p@ ", Cmnd); QueBadTargetCmnd( cpqfcHBAdata, Cmnd); } - else if (Cmnd->lun >= CPQFCTS_MAX_LUN) + else if (Cmnd->device->lun >= CPQFCTS_MAX_LUN) { - printk(KERN_WARNING "cpqfc: Invalid LUN: %d\n", Cmnd->lun); + printk(KERN_WARNING "cpqfc: Invalid LUN: %d\n", Cmnd->device->lun); QueBadTargetCmnd( cpqfcHBAdata, Cmnd); } @@ -1475,7 +1478,7 @@ int cpqfcTS_eh_abort(Scsi_Cmnd *Cmnd) { - struct Scsi_Host *HostAdapter = Cmnd->host; + struct Scsi_Host *HostAdapter = Cmnd->device->host; // get the pointer to our Scsi layer HBA buffer CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; PTACHYON fcChip = &cpqfcHBAdata->fcChip; @@ -1601,8 +1604,7 @@ scsi_cdb[0] = RELEASE; - // allocate with wait = true, interruptible = false - SCpnt = scsi_allocate_device(ScsiDev, 1); + SCpnt = scsi_get_command(ScsiDev, GFP_KERNEL); { CPQFC_DECLARE_COMPLETION(wait); @@ -1651,7 +1653,7 @@ result = SCpnt->result; SDpnt = SCpnt->device; - scsi_release_command(SCpnt); + scsi_put_command(SCpnt); SCpnt = NULL; // if (!SDpnt->was_reset && SDpnt->scsi_request_fn) @@ -1668,9 +1670,9 @@ int retval; Scsi_Device *SDpnt = Cmnd->device; // printk(" ENTERING cpqfcTS_eh_device_reset() \n"); - spin_unlock_irq(Cmnd->host->host_lock); + spin_unlock_irq(Cmnd->device->host->host_lock); retval = cpqfcTS_TargetDeviceReset( SDpnt, 0); - spin_lock_irq(Cmnd->host->host_lock); + spin_lock_irq(Cmnd->device->host->host_lock); return retval; } diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c --- a/drivers/scsi/dpt_i2o.c Sun Feb 9 21:13:35 2003 +++ b/drivers/scsi/dpt_i2o.c Sun Feb 9 21:13:35 2003 @@ -391,7 +391,7 @@ return 0; } - pHba = (adpt_hba*)cmd->host->hostdata[0]; + pHba = (adpt_hba*)cmd->device->host->hostdata[0]; if (!pHba) { return FAILED; } @@ -424,7 +424,7 @@ * to the device structure. This should be a TEST_UNIT_READY * command from scan_scsis_single. */ - if ((pDev = adpt_find_device(pHba, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun)) == NULL) { + if ((pDev = adpt_find_device(pHba, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun)) == NULL) { // TODO: if any luns are at this bus, scsi id then fake a TEST_UNIT_READY and INQUIRY response // with type 7F (for all luns less than the max for this bus,id) so the lun scan will continue. cmd->result = (DID_NO_CONNECT << 16); @@ -647,7 +647,7 @@ if(cmd->serial_number == 0){ return FAILED; } - pHba = (adpt_hba*) cmd->host->hostdata[0]; + pHba = (adpt_hba*) cmd->device->host->hostdata[0]; printk(KERN_INFO"%s: Trying to Abort cmd=%ld\n",pHba->name, cmd->serial_number); if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) { printk(KERN_ERR "%s: Unable to abort: No device in cmnd\n",pHba->name); @@ -685,7 +685,7 @@ int old_state; struct adpt_device* d = (void*) cmd->device->hostdata; - pHba = (void*) cmd->host->hostdata[0]; + pHba = (void*) cmd->device->host->hostdata[0]; printk(KERN_INFO"%s: Trying to reset device\n",pHba->name); if (!d) { printk(KERN_INFO"%s: Reset Device: Device Not found\n",pHba->name); @@ -722,11 +722,11 @@ adpt_hba* pHba; u32 msg[4]; - pHba = (adpt_hba*)cmd->host->hostdata[0]; + pHba = (adpt_hba*)cmd->device->host->hostdata[0]; memset(msg, 0, sizeof(msg)); - printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->channel,pHba->channel[cmd->channel].tid ); + printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->device->channel,pHba->channel[cmd->device->channel].tid ); msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0; - msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->channel].tid); + msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid); msg[2] = 0; msg[3] = 0; if(adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER) ){ @@ -743,8 +743,8 @@ { adpt_hba* pHba; int rcode; - pHba = (adpt_hba*)cmd->host->hostdata[0]; - printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->channel,pHba->channel[cmd->channel].tid ); + pHba = (adpt_hba*)cmd->device->host->hostdata[0]; + printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->device->channel,pHba->channel[cmd->device->channel].tid ); rcode = adpt_hba_reset(pHba); if(rcode == 0){ printk(KERN_WARNING"%s: HBA reset complete\n",pHba->name); @@ -2216,7 +2216,7 @@ // calculate resid for sg cmd->resid = cmd->request_bufflen - readl(reply+5); - pHba = (adpt_hba*) cmd->host->hostdata[0]; + pHba = (adpt_hba*) cmd->device->host->hostdata[0]; cmd->sense_buffer[0] = '\0'; // initialize sense valid flag to false @@ -2240,7 +2240,7 @@ case I2O_SCSI_DSC_NO_ADAPTER: case I2O_SCSI_DSC_RESOURCE_UNAVAILABLE: printk(KERN_WARNING"%s: SCSI Timeout-Device (%d,%d,%d) hba status=0x%x, dev status=0x%x, cmd=0x%x\n", - pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd->lun, hba_status, dev_status, cmd->cmnd[0]); + pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun, hba_status, dev_status, cmd->cmnd[0]); cmd->result = (DID_TIME_OUT << 16); break; case I2O_SCSI_DSC_ADAPTER_BUSY: @@ -2280,7 +2280,7 @@ case I2O_SCSI_DSC_REQUEST_INVALID: default: printk(KERN_WARNING"%s: SCSI error %0x-Device(%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n", - pHba->name, detailed_status & I2O_SCSI_DSC_MASK, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun, + pHba->name, detailed_status & I2O_SCSI_DSC_MASK, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun, hba_status, dev_status, cmd->cmnd[0]); cmd->result = (DID_ERROR << 16); break; @@ -2298,7 +2298,7 @@ /* This is to handle an array failed */ cmd->result = (DID_TIME_OUT << 16); printk(KERN_WARNING"%s: SCSI Data Protect-Device (%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n", - pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd->lun, + pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun, hba_status, dev_status, cmd->cmnd[0]); } @@ -2310,7 +2310,7 @@ */ cmd->result = (DID_TIME_OUT << 16); printk(KERN_WARNING"%s: I2O MSG_FAIL - Device (%d,%d,%d) tid=%d, cmd=0x%x\n", - pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun, + pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun, ((struct adpt_device*)(cmd->device->hostdata))->tid, cmd->cmnd[0]); } @@ -2510,13 +2510,16 @@ Scsi_Device* d = NULL; list_for_each_entry(d, &pHba->host->my_devices, siblings) { - for(cmd = d->device_queue; cmd ; cmd = cmd->next){ + unsigned long flags; + spin_lock_irqsave(&d->list_lock, flags); + list_for_each_entry(cmd, &d->cmd_list, list) { if(cmd->serial_number == 0){ continue; } cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1); cmd->scsi_done(cmd); } + spin_unlock_irqrestore(&d->list_lock, flags); } } diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c --- a/drivers/scsi/eata.c Sun Feb 9 21:13:35 2003 +++ b/drivers/scsi/eata.c Sun Feb 9 21:13:35 2003 @@ -895,7 +895,7 @@ tag_suffix = ""; } - if (TLDEV(dev->type) && linked_comm && dev->new_queue_depth > 2) + if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2) link_suffix = ", sorted"; else if (TLDEV(dev->type)) link_suffix = ", unsorted"; @@ -904,7 +904,7 @@ printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n", BN(j), host->host_no, dev->channel, dev->id, dev->lun, - dev->new_queue_depth, link_suffix, tag_suffix); + dev->queue_depth, link_suffix, tag_suffix); return FALSE; } @@ -1640,7 +1640,7 @@ struct mscp *cpp; /* j is the board number */ - j = ((struct hostdata *) SCpnt->host->hostdata)->board_number; + j = ((struct hostdata *) SCpnt->device->host->hostdata)->board_number; if (SCpnt->host_scribble) panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", @@ -1678,8 +1678,8 @@ SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index; if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n", - BN(j), i, SCpnt->channel, SCpnt->target, - SCpnt->lun, SCpnt->pid); + BN(j), i, SCpnt->device->channel, SCpnt->device->id, + SCpnt->device->lun, SCpnt->pid); cpp->reqsen = TRUE; cpp->dispri = TRUE; @@ -1687,9 +1687,9 @@ if (SCpnt->device->type == TYPE_TAPE) cpp->hbaci = TRUE; #endif cpp->one = TRUE; - cpp->channel = SCpnt->channel; - cpp->target = SCpnt->target; - cpp->lun = SCpnt->lun; + cpp->channel = SCpnt->device->channel; + cpp->target = SCpnt->device->id; + cpp->lun = SCpnt->device->lun; cpp->SCpnt = SCpnt; memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len); @@ -1699,7 +1699,7 @@ /* Map DMA buffers and SG list */ map_dma(i, j); - if (linked_comm && SCpnt->device->new_queue_depth > 2 + if (linked_comm && SCpnt->device->queue_depth > 2 && TLDEV(SCpnt->device->type)) { HD(j)->cp_stat[i] = READY; flush_dev(SCpnt->device, SCpnt->request->sector, j, FALSE); @@ -1711,7 +1711,7 @@ unmap_dma(i, j); SCpnt->host_scribble = NULL; printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n", - BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid); + BN(j), SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid); return 1; } @@ -1722,17 +1722,17 @@ static int eata2x_eh_abort(Scsi_Cmnd *SCarg) { unsigned int i, j; - j = ((struct hostdata *) SCarg->host->hostdata)->board_number; + j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number; if (SCarg->host_scribble == NULL) { printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n", - BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); + BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); return SUCCESS; } i = *(unsigned int *)SCarg->host_scribble; printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n", - BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); + BN(j), i, SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); if (i >= sh[j]->can_queue) panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j)); @@ -1798,9 +1798,9 @@ int arg_done = FALSE; Scsi_Cmnd *SCpnt; - j = ((struct hostdata *) SCarg->host->hostdata)->board_number; + j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number; printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n", - BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); + BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); if (SCarg->host_scribble == NULL) printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); @@ -2056,8 +2056,8 @@ k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"\ " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", - (ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target, - SCpnt->lun, SCpnt->pid, k, flushcount, n_ready, + (ihdlr ? "ihdlr" : "qcomm"), SCpnt->device->channel, SCpnt->device->id, + SCpnt->device->lun, SCpnt->pid, k, flushcount, n_ready, SCpnt->request->sector, SCpnt->request->nr_sectors, cursec, YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only), YESNO(overlap), cpp->din); @@ -2093,7 +2093,7 @@ if (do_dma(sh[j]->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) { printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\ " busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"), - SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, k); + SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, k); HD(j)->cp_stat[k] = ABORTING; continue; } @@ -2207,7 +2207,7 @@ sync_dma(i, j); - if (linked_comm && SCpnt->device->new_queue_depth > 2 + if (linked_comm && SCpnt->device->queue_depth > 2 && TLDEV(SCpnt->device->type)) flush_dev(SCpnt->device, SCpnt->request->sector, j, TRUE); @@ -2227,7 +2227,7 @@ /* If there was a bus reset, redo operation on each target */ else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK - && HD(j)->target_redo[SCpnt->target][SCpnt->channel]) + && HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel]) status = DID_BUS_BUSY << 16; /* Works around a flaw in scsi.c */ @@ -2240,18 +2240,18 @@ status = DID_OK << 16; if (tstatus == GOOD) - HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE; + HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel] = FALSE; if (spp->target_status && SCpnt->device->type == TYPE_DISK && (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 && (SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\ "target_status 0x%x, sense key 0x%x.\n", BN(j), - SCpnt->channel, SCpnt->target, SCpnt->lun, + SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, spp->target_status, SCpnt->sense_buffer[2]); - HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0; + HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] = 0; if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0; @@ -2259,11 +2259,11 @@ case ASST: /* Selection Time Out */ case 0x02: /* Command Time Out */ - if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1) + if (HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] > 1) status = DID_ERROR << 16; else { status = DID_TIME_OUT << 16; - HD(j)->target_to[SCpnt->target][SCpnt->channel]++; + HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel]++; } break; @@ -2318,7 +2318,7 @@ printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\ " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n", BN(j), i, spp->adapter_status, spp->target_status, - SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, + SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, reg, HD(j)->iocount); unmap_dma(i, j); diff -Nru a/drivers/scsi/eata_dma.c b/drivers/scsi/eata_dma.c --- a/drivers/scsi/eata_dma.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/eata_dma.c Sun Feb 9 21:13:28 2003 @@ -270,7 +270,7 @@ } cmd = ccb->cmd; - base = (uint) cmd->host->base; + base = (uint) cmd->device->host->base; hba_stat = sp->hba_stat; scsi_stat = (sp->scsi_stat >> 1) & 0x1f; @@ -299,8 +299,8 @@ eata_stat = inb(base + HA_RSTATUS); DBG(DBG_INTR, printk("IRQ %d received, base %#.4x, pid %ld, " "target: %x, lun: %x, ea_s: %#.2x, hba_s: " - "%#.2x \n", irq, base, cmd->pid, cmd->target, - cmd->lun, eata_stat, hba_stat)); + "%#.2x \n", irq, base, cmd->pid, cmd->device->id, + cmd->device->lun, eata_stat, hba_stat)); switch (hba_stat) { case HA_NO_ERROR: /* NO Error */ @@ -337,7 +337,7 @@ break; case HA_CP_RESET_NA: case HA_CP_RESET: - HD(cmd)->resetlevel[cmd->channel] = 0; + HD(cmd)->resetlevel[cmd->device->channel] = 0; result = DID_RESET << 16; DBG(DBG_STATUS, printk(KERN_WARNING "scsi%d: reseted cmd " "pid %ldreturned\n", @@ -478,7 +478,7 @@ queue_counter++; hd = HD(cmd); - sh = cmd->host; + sh = cmd->device->host; if (cmd->cmnd[0] == REQUEST_SENSE && cmd->sense_buffer[0] != 0) { DBG(DBG_REQSENSE, printk(KERN_DEBUG "Tried to REQUEST SENSE\n")); @@ -517,7 +517,7 @@ restore_flags(flags); DBG(DBG_QUEUE, printk("eata_queue pid %ld, target: %x, lun: %x, y %d\n", - cmd->pid, cmd->target, cmd->lun, y)); + cmd->pid, cmd->device->id, cmd->device->lun, y)); DBG(DBG_QUEUE && DBG_DELAY, DELAY(1)); if(hd->do_latency == TRUE) @@ -547,7 +547,7 @@ /* FIXME: This will will have to be changed once the midlevel driver * allows different HBA IDs on every channel. */ - if (cmd->target == sh->this_id) + if (cmd->device->id == sh->this_id) ccb->Interpret = TRUE; /* Interpret command */ if (cmd->use_sg) { @@ -586,9 +586,9 @@ ccb->cp_reqDMA = htonl(virt_to_bus(cmd->sense_buffer)); ccb->reqlen = sizeof(cmd->sense_buffer); - ccb->cp_id = cmd->target; - ccb->cp_channel = cmd->channel; - ccb->cp_lun = cmd->lun; + ccb->cp_id = cmd->device->id; + ccb->cp_channel = cmd->device->channel; + ccb->cp_lun = cmd->device->lun; ccb->cp_dispri = TRUE; ccb->cp_identify = TRUE; memcpy(ccb->cp_cdb, cmd->cmnd, cmd->cmd_len); @@ -604,14 +604,14 @@ cmd->result = DID_BUS_BUSY << 16; DBG(DBG_QUEUE && DBG_ABNORM, printk("eata_queue target %d, pid %ld, HBA busy, " - "returning DID_BUS_BUSY\n",cmd->target, cmd->pid)); + "returning DID_BUS_BUSY\n",cmd->device->id, cmd->pid)); ccb->status = FREE; done(cmd); return(0); } DBG(DBG_QUEUE, printk("Queued base %#.4x pid: %ld target: %x lun: %x " "slot %d irq %d\n", (s32)sh->base, cmd->pid, - cmd->target, cmd->lun, y, sh->irq)); + cmd->device->id, cmd->device->lun, y, sh->irq)); DBG(DBG_QUEUE && DBG_DELAY, DELAY(1)); return(0); @@ -629,7 +629,7 @@ cli(); DBG(DBG_ABNORM, printk("eata_abort called pid: %ld target: %x lun: %x" - " reason %x\n", cmd->pid, cmd->target, cmd->lun, + " reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason)); DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); @@ -642,7 +642,7 @@ } } - while (inb((u32)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY) { + while (inb((u32)(cmd->device->host->base) + HA_RAUXSTAT) & HA_ABUSY) { if (--loop == 0) { printk("eata_dma: abort, timeout error.\n"); DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); @@ -690,7 +690,7 @@ cli(); DBG(DBG_ABNORM, printk("eata_reset called pid:%ld target: %x lun: %x" - " reason %x\n", cmd->pid, cmd->target, cmd->lun, + " reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason)); for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) { @@ -708,7 +708,7 @@ return (SCSI_RESET_ERROR); } - while (inb((u32)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY) + while (inb((u32)(cmd->device->host->base) + HA_RAUXSTAT) & HA_ABUSY) if (--loop == 0) { printk("eata_reset: exit, timeout error.\n"); restore_flags(flags); @@ -716,7 +716,7 @@ return (SCSI_RESET_ERROR); } - for (x = 0; x < cmd->host->can_queue; x++) { + for (x = 0; x < cmd->device->host->can_queue; x++) { if (HD(cmd)->ccb[x].status == FREE) continue; @@ -743,8 +743,8 @@ } /* hard reset the HBA */ - inb((u32) (cmd->host->base) + HA_RSTATUS); /* This might cause trouble */ - eata_send_command(0, (u32) cmd->host->base, EATA_CMD_RESET); + inb((u32) (cmd->device->host->base) + HA_RSTATUS); /* This might cause trouble */ + eata_send_command(0, (u32) cmd->device->host->base, EATA_CMD_RESET); HD(cmd)->state = RESET; @@ -757,7 +757,7 @@ DBG(DBG_ABNORM, printk("eata_reset: interrupts disabled again.\n")); DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - for (x = 0; x < cmd->host->can_queue; x++) { + for (x = 0; x < cmd->device->host->can_queue; x++) { /* Skip slots already set free by interrupt and those that * are still LOCKED from the last reset */ diff -Nru a/drivers/scsi/eata_generic.h b/drivers/scsi/eata_generic.h --- a/drivers/scsi/eata_generic.h Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/eata_generic.h Sun Feb 9 21:13:32 2003 @@ -90,7 +90,7 @@ #define WRITE 1 #define OTHER 2 -#define HD(cmd) ((hostdata *)&(cmd->host->hostdata)) +#define HD(cmd) ((hostdata *)&(cmd->device->host->hostdata)) #define CD(cmd) ((struct eata_ccb *)(cmd->host_scribble)) #define SD(host) ((hostdata *)&(host->hostdata)) diff -Nru a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c --- a/drivers/scsi/eata_pio.c Sun Feb 9 21:13:33 2003 +++ b/drivers/scsi/eata_pio.c Sun Feb 9 21:13:33 2003 @@ -157,7 +157,7 @@ cp = &hd->ccb[0]; cmd = cp->cmd; - base = (uint) cmd->host->base; + base = (uint) cmd->device->host->base; do { stat = inb(base + HA_RSTATUS); @@ -286,7 +286,7 @@ queue_counter++; hd = HD(cmd); - sh = cmd->host; + sh = cmd->device->host; base = (uint) sh->base; /* use only slot 0, as 2001 can handle only one cmd at a time */ @@ -310,7 +310,7 @@ cp->status = USED; /* claim free slot */ - DBG(DBG_QUEUE, printk(KERN_DEBUG "eata_pio_queue pid %ld, target: %x, lun:" " %x, y %d\n", cmd->pid, cmd->target, cmd->lun, y)); + DBG(DBG_QUEUE, printk(KERN_DEBUG "eata_pio_queue pid %ld, target: %x, lun:" " %x, y %d\n", cmd->pid, cmd->device->id, cmd->device->lun, y)); cmd->scsi_done = (void *) done; @@ -319,14 +319,14 @@ else cp->DataIn = TRUE; /* Input mode */ - cp->Interpret = (cmd->target == hd->hostid); + cp->Interpret = (cmd->device->id == hd->hostid); cp->cp_datalen = htonl((unsigned long) cmd->request_bufflen); cp->Auto_Req_Sen = FALSE; cp->cp_reqDMA = htonl(0); cp->reqlen = 0; - cp->cp_id = cmd->target; - cp->cp_lun = cmd->lun; + cp->cp_id = cmd->device->id; + cp->cp_lun = cmd->device->lun; cp->cp_dispri = FALSE; cp->cp_identify = TRUE; memcpy(cp->cp_cdb, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); @@ -353,7 +353,7 @@ if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) { cmd->result = DID_BUS_BUSY << 16; - printk(KERN_NOTICE "eata_pio_queue target %d, pid %ld, HBA busy, " "returning DID_BUS_BUSY, done.\n", cmd->target, cmd->pid); + printk(KERN_NOTICE "eata_pio_queue target %d, pid %ld, HBA busy, " "returning DID_BUS_BUSY, done.\n", cmd->device->id, cmd->pid); done(cmd); cp->status = FREE; return (0); @@ -366,7 +366,7 @@ for (x = 0; x < hd->cppadlen; x++) outw(0, base + HA_RDATA); - DBG(DBG_QUEUE, printk(KERN_DEBUG "Queued base %#.4lx pid: %ld target: %x " "lun: %x slot %d irq %d\n", (long) sh->base, cmd->pid, cmd->target, cmd->lun, y, sh->irq)); + DBG(DBG_QUEUE, printk(KERN_DEBUG "Queued base %#.4lx pid: %ld target: %x " "lun: %x slot %d irq %d\n", (long) sh->base, cmd->pid, cmd->device->id, cmd->device->lun, y, sh->irq)); return (0); } @@ -375,10 +375,10 @@ { uint loop = HZ; - DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld " "target: %x lun: %x reason %x\n", cmd->pid, cmd->target, cmd->lun, cmd->abort_reason)); + DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld " "target: %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason)); - while (inb(cmd->host->base + HA_RAUXSTAT) & HA_ABUSY) + while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY) if (--loop == 0) { printk(KERN_WARNING "eata_pio: abort, timeout error.\n"); return FAILED; @@ -408,9 +408,9 @@ uint x, limit = 0; unsigned char success = FALSE; Scsi_Cmnd *sp; - struct Scsi_Host *host = cmd->host; + struct Scsi_Host *host = cmd->device->host; - DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->target, cmd->lun, cmd->abort_reason)); + DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason)); if (HD(cmd)->state == RESET) { printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n"); @@ -419,7 +419,7 @@ /* force all slots to be free */ - for (x = 0; x < cmd->host->can_queue; x++) { + for (x = 0; x < cmd->device->host->can_queue; x++) { if (HD(cmd)->ccb[x].status == FREE) continue; @@ -433,7 +433,7 @@ } /* hard reset the HBA */ - outb(EATA_CMD_RESET, (uint) cmd->host->base + HA_WCOMMAND); + outb(EATA_CMD_RESET, (uint) cmd->device->host->base + HA_WCOMMAND); DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: board reset done.\n")); HD(cmd)->state = RESET; @@ -445,7 +445,7 @@ DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: interrupts disabled, " "loops %d.\n", limit)); - for (x = 0; x < cmd->host->can_queue; x++) { + for (x = 0; x < cmd->device->host->can_queue; x++) { /* Skip slots already set free by interrupt */ if (HD(cmd)->ccb[x].status != RESET) diff -Nru a/drivers/scsi/esp.c b/drivers/scsi/esp.c --- a/drivers/scsi/esp.c Sun Feb 9 21:13:37 2003 +++ b/drivers/scsi/esp.c Sun Feb 9 21:13:37 2003 @@ -453,7 +453,7 @@ Scsi_Cmnd *ptr, *prev; for (ptr = *SC, prev = NULL; - ptr && ((ptr->target != target) || (ptr->lun != lun)); + ptr && ((ptr->device->id != target) || (ptr->device->lun != lun)); prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble) ; if (ptr) { @@ -1447,7 +1447,7 @@ static void esp_restore_pointers(struct esp *esp, Scsi_Cmnd *sp) { - struct esp_pointers *ep = &esp->data_pointers[sp->target]; + struct esp_pointers *ep = &esp->data_pointers[sp->device->id]; sp->SCp.ptr = ep->saved_ptr; sp->SCp.buffer = ep->saved_buffer; @@ -1457,7 +1457,7 @@ static void esp_save_pointers(struct esp *esp, Scsi_Cmnd *sp) { - struct esp_pointers *ep = &esp->data_pointers[sp->target]; + struct esp_pointers *ep = &esp->data_pointers[sp->device->id]; ep->saved_ptr = sp->SCp.ptr; ep->saved_buffer = sp->SCp.buffer; @@ -1559,8 +1559,8 @@ SDptr = SCptr->device; esp_dev = SDptr->hostdata; - lun = SCptr->lun; - target = SCptr->target; + lun = SCptr->device->lun; + target = SCptr->device->id; esp->snip = 0; esp->msgout_len = 0; @@ -1621,7 +1621,7 @@ * disconnect. */ ESPMISC(("esp: Selecting device for first time. target=%d " - "lun=%d\n", target, SCptr->lun)); + "lun=%d\n", target, SCptr->device->lun)); if (!SDptr->borken && !esp_dev->disconnect) esp_dev->disconnect = 1; @@ -1731,7 +1731,7 @@ SDptr->removable == 0) || cdrom_hwbug_wkaround || SDptr->borken) { ESPMISC((KERN_INFO "esp%d: Disabling DISCONNECT for target %d " - "lun %d\n", esp->esp_id, SCptr->target, SCptr->lun)); + "lun %d\n", esp->esp_id, SCptr->device->id, SCptr->device->lun)); esp_dev->disconnect = 0; *cmdp++ = IDENTIFY(0, lun); } else { @@ -1822,10 +1822,10 @@ SCpnt->SCp.phase = not_issued; /* We use the scratch area. */ - ESPQUEUE(("esp_queue: target=%d lun=%d ", SCpnt->target, SCpnt->lun)); - ESPDISC(("N<%02x,%02x>", SCpnt->target, SCpnt->lun)); + ESPQUEUE(("esp_queue: target=%d lun=%d ", SCpnt->device->id, SCpnt->device->lun)); + ESPDISC(("N<%02x,%02x>", SCpnt->device->id, SCpnt->device->lun)); - esp = (struct esp *) SCpnt->host->hostdata; + esp = (struct esp *) SCpnt->device->host->hostdata; esp_get_dmabufs(esp, SCpnt); esp_save_pointers(esp, SCpnt); /* FIXME for tag queueing */ @@ -1852,7 +1852,7 @@ /* Only queuing supported in this ESP driver. */ static int esp_command(Scsi_Cmnd *SCpnt) { - struct esp *esp = (struct esp *) SCpnt->host->hostdata; + struct esp *esp = (struct esp *) SCpnt->device->host->hostdata; ESPLOG(("esp%d: esp_command() called...\n", esp->esp_id)); return -1; @@ -1863,7 +1863,7 @@ { ESPLOG(("[tgt<%02x> lun<%02x> " "pphase<%s> cphase<%s>]", - SCptr->target, SCptr->lun, + SCptr->device->id, SCptr->device->lun, phase_string(SCptr->SCp.sent_command), phase_string(SCptr->SCp.phase))); } @@ -1917,7 +1917,7 @@ /* Abort a command. The host_lock is acquired by caller. */ static int esp_abort(Scsi_Cmnd *SCptr) { - struct esp *esp = (struct esp *) SCptr->host->hostdata; + struct esp *esp = (struct esp *) SCptr->device->host->hostdata; int don; ESPLOG(("esp%d: Aborting command\n", esp->esp_id)); @@ -2049,7 +2049,7 @@ */ static int esp_reset(Scsi_Cmnd *SCptr) { - struct esp *esp = (struct esp *) SCptr->host->hostdata; + struct esp *esp = (struct esp *) SCptr->device->host->hostdata; (void) esp_do_resetbus(esp); @@ -2474,13 +2474,13 @@ if (esp->prev_soff != esp_dev->sync_max_offset || esp->prev_stp != esp_dev->sync_min_period || (esp->erev > esp100a && - esp->prev_cfg3 != esp->config3[sp->target])) { + esp->prev_cfg3 != esp->config3[sp->device->id])) { esp->prev_soff = esp_dev->sync_max_offset; esp->prev_stp = esp_dev->sync_min_period; sbus_writeb(esp->prev_soff, esp->eregs + ESP_SOFF); sbus_writeb(esp->prev_stp, esp->eregs + ESP_STP); if (esp->erev > esp100a) { - esp->prev_cfg3 = esp->config3[sp->target]; + esp->prev_cfg3 = esp->config3[sp->device->id]; sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3); } } @@ -2736,7 +2736,7 @@ esp->esp_id, SCptr->use_sg, SCptr->SCp.ptr, SCptr->SCp.this_residual)); ESPLOG(("esp%d: Forcing async for target %d\n", esp->esp_id, - SCptr->target)); + SCptr->device->id)); SCptr->device->borken = 1; esp_dev->sync = 0; bytes_sent = 0; @@ -2842,7 +2842,7 @@ if (SCptr->SCp.Status != GOOD && SCptr->SCp.Status != CONDITION_GOOD && - ((1<target) & esp->targets_present) && + ((1<device->id) & esp->targets_present) && esp_dev->sync && esp_dev->sync_max_offset) { /* SCSI standard says that the synchronous capabilities @@ -2853,7 +2853,7 @@ * state. */ ESPMISC(("esp: Status <%d> for target %d lun %d\n", - SCptr->SCp.Status, SCptr->target, SCptr->lun)); + SCptr->SCp.Status, SCptr->device->id, SCptr->device->lun)); /* But don't do this when spinning up a disk at * boot time while we poll for completion as it @@ -2864,14 +2864,14 @@ if (esp_should_clear_sync(SCptr) != 0) esp_dev->sync = 0; } - ESPDISC(("F<%02x,%02x>", SCptr->target, SCptr->lun)); + ESPDISC(("F<%02x,%02x>", SCptr->device->id, SCptr->device->lun)); esp_done(esp, ((SCptr->SCp.Status & 0xff) | ((SCptr->SCp.Message & 0xff)<<8) | (DID_OK << 16))); } else if (esp->prevmsgin == DISCONNECT) { /* Normal disconnect. */ esp_cmd(esp, ESP_CMD_ESEL); - ESPDISC(("D<%02x,%02x>", SCptr->target, SCptr->lun)); + ESPDISC(("D<%02x,%02x>", SCptr->device->id, SCptr->device->lun)); append_SC(&esp->disconnected_SC, SCptr); esp->current_SC = NULL; if (esp->issue_SC) @@ -2901,21 +2901,21 @@ sp = esp->issue_SC; ESPLOG(("esp%d: issue_SC[", esp->esp_id)); while (sp) { - ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); + ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun)); sp = (Scsi_Cmnd *) sp->host_scribble; } ESPLOG(("]\n")); sp = esp->current_SC; ESPLOG(("esp%d: current_SC[", esp->esp_id)); if (sp) - ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); + ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun)); else ESPLOG(("")); ESPLOG(("]\n")); sp = esp->disconnected_SC; ESPLOG(("esp%d: disconnected_SC[", esp->esp_id)); while (sp) { - ESPLOG(("<%02x,%02x>", sp->target, sp->lun)); + ESPLOG(("<%02x,%02x>", sp->device->id, sp->device->lun)); sp = (Scsi_Cmnd *) sp->host_scribble; } ESPLOG(("]\n")); @@ -2959,7 +2959,7 @@ esp_cmd(esp, ESP_CMD_MOK); if (esp->erev == fashme) - sbus_writeb(((SCptr->target & 0xf) | + sbus_writeb(((SCptr->device->id & 0xf) | (ESP_BUSID_RESELID | ESP_BUSID_CTR32BIT)), esp->eregs + ESP_BUSID); @@ -3246,7 +3246,7 @@ */ if (esp->ireg == (ESP_INTR_FDONE | ESP_INTR_BSERV)) { /* target speaks... */ - esp->targets_present |= (1<target); + esp->targets_present |= (1<device->id); /* What if the target ignores the sdtr? */ if (esp->snip) @@ -3275,7 +3275,7 @@ * XXX for synchronous transfers. */ ESPLOG(("esp%d: STEP_ASEL for tgt %d\n", - esp->esp_id, SCptr->target)); + esp->esp_id, SCptr->device->id)); case ESP_STEP_SID: /* Arbitration won, target selected, went @@ -3395,7 +3395,7 @@ if (esp->disconnected_SC) esp_cmd(esp, ESP_CMD_ESEL); - if (((1<target) & esp->targets_present) && + if (((1<device->id) & esp->targets_present) && esp->seqreg != 0 && (esp->cur_msgout[0] == EXTENDED_MESSAGE) && (SCptr->SCp.phase == in_slct_msg || @@ -3403,7 +3403,7 @@ /* shit */ esp->snip = 0; ESPLOG(("esp%d: Failed synchronous negotiation for target %d " - "lun %d\n", esp->esp_id, SCptr->target, SCptr->lun)); + "lun %d\n", esp->esp_id, SCptr->device->id, SCptr->device->lun)); esp_dev->sync_max_offset = 0; esp_dev->sync_min_period = 0; esp_dev->sync = 1; /* so we don't negotiate again */ @@ -3429,9 +3429,9 @@ * or whenever when we are scanning the bus for targets. * But first make sure that is really what is happening. */ - if (((1<target) & esp->targets_present)) { + if (((1<device->id) & esp->targets_present)) { ESPLOG(("esp%d: Warning, live target %d not responding to " - "selection.\n", esp->esp_id, SCptr->target)); + "selection.\n", esp->esp_id, SCptr->device->id)); /* This _CAN_ happen. The SCSI standard states that * the target is to _not_ respond to selection if @@ -3444,7 +3444,7 @@ /* Else, there really isn't anyone there. */ ESPMISC(("esp: selection failure, maybe nobody there?\n")); ESPMISC(("esp: target %d lun %d\n", - SCptr->target, SCptr->lun)); + SCptr->device->id, SCptr->device->lun)); esp_done(esp, (DID_BAD_TARGET << 16)); } return do_intr_end; @@ -3517,7 +3517,7 @@ case NOP: ESPLOG(("esp%d: target %d sends a nop\n", esp->esp_id, - esp->current_SC->target)); + esp->current_SC->device->id)); return 0; case RESTORE_POINTERS: @@ -3600,7 +3600,7 @@ int integer = hz / 1000000; int fraction = (hz - (integer * 1000000)) / 10000; if ((esp->erev == fashme) && - (esp->config3[esp->current_SC->target] & ESP_CONFIG3_EWIDE)) { + (esp->config3[esp->current_SC->device->id] & ESP_CONFIG3_EWIDE)) { type = "FAST-WIDE"; integer <<= 1; fraction <<= 1; @@ -3615,7 +3615,7 @@ * sibling call optimization. -DaveM */ ESPLOG((KERN_INFO "esp%d: target %d ", - esp->esp_id, esp->current_SC->target)); + esp->esp_id, esp->current_SC->device->id)); ESPLOG(("[period %dns offset %d %d.%02dMHz ", (int) msg3 * 4, (int) msg4, integer, fraction)); @@ -3623,7 +3623,7 @@ (((msg3 * 4) < 200) ? "-II" : ""))); } else { ESPLOG((KERN_INFO "esp%d: target %d asynchronous\n", - esp->esp_id, esp->current_SC->target)); + esp->esp_id, esp->current_SC->device->id)); } } @@ -3707,11 +3707,11 @@ */ if (esp->erev == fashme) esp_dev->sync_max_offset &= ~esp->radelay; - esp->config3[SCptr->target] |= bit; + esp->config3[SCptr->device->id] |= bit; } else { - esp->config3[SCptr->target] &= ~bit; + esp->config3[SCptr->device->id] &= ~bit; } - esp->prev_cfg3 = esp->config3[SCptr->target]; + esp->prev_cfg3 = esp->config3[SCptr->device->id]; sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3); } esp->prev_soff = esp_dev->sync_max_offset; @@ -3721,7 +3721,7 @@ ESPSDTR(("soff=%2x stp=%2x cfg3=%2x\n", esp_dev->sync_max_offset, esp_dev->sync_min_period, - esp->config3[SCptr->target])); + esp->config3[SCptr->device->id])); esp->snip = 0; } else if (esp_dev->sync_max_offset) { @@ -3740,8 +3740,8 @@ bit = ESP_CONFIG3_FAST; else bit = ESP_CONFIG3_FSCSI; - esp->config3[SCptr->target] &= ~bit; - esp->prev_cfg3 = esp->config3[SCptr->target]; + esp->config3[SCptr->device->id] &= ~bit; + esp->prev_cfg3 = esp->config3[SCptr->device->id]; sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3); } } @@ -3778,7 +3778,7 @@ /* Things look good; let's see what we got. */ if (size == 16) { /* Set config 3 register for this target. */ - esp->config3[SCptr->target] |= ESP_CONFIG3_EWIDE; + esp->config3[SCptr->device->id] |= ESP_CONFIG3_EWIDE; } else { /* Just make sure it was one byte sized. */ if (size != 8) { @@ -3788,9 +3788,9 @@ goto finish; } /* Pure paranoia. */ - esp->config3[SCptr->target] &= ~(ESP_CONFIG3_EWIDE); + esp->config3[SCptr->device->id] &= ~(ESP_CONFIG3_EWIDE); } - esp->prev_cfg3 = esp->config3[SCptr->target]; + esp->prev_cfg3 = esp->config3[SCptr->device->id]; sbus_writeb(esp->prev_cfg3, esp->eregs + ESP_CFG3); /* Regardless, next try for sync transfers. */ @@ -4258,7 +4258,7 @@ * a nexus is alive on the bus. */ ESPLOG(("esp%d: Forcing async and disabling disconnect for " - "target %d\n", esp->esp_id, SCptr->target)); + "target %d\n", esp->esp_id, SCptr->device->id)); SCptr->device->borken = 1; /* foo on you */ } diff -Nru a/drivers/scsi/fcal.c b/drivers/scsi/fcal.c --- a/drivers/scsi/fcal.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/fcal.c Sun Feb 9 21:13:28 2003 @@ -292,11 +292,12 @@ if (SCpnt->cmnd[1] & 0xe0) return -EINVAL; /* FC-PLDA tells us... */ memset(addr, 0, 8); - f = (struct fcal *)SCpnt->host->hostdata; - if (!f->map[SCpnt->target]) return -EINVAL; + f = (struct fcal *)SCpnt->device->host->hostdata; + if (!f->map[SCpnt->device->id]) + return -EINVAL; /* Now, determine DID: It will be Native Identifier, so we zero upper 2 bytes of the 3 byte DID, lowest byte will be AL-PA */ - fcmd->did = target2alpa[SCpnt->target]; + fcmd->did = target2alpa[SCpnt->device->id]; FCALD(("trying DID %06x\n", fcmd->did)) return 0; } diff -Nru a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c --- a/drivers/scsi/fdomain.c Sun Feb 9 21:13:34 2003 +++ b/drivers/scsi/fdomain.c Sun Feb 9 21:13:34 2003 @@ -1252,9 +1252,9 @@ #if EVERY_ACCESS printk( " AFAIL " ); #endif - spin_lock_irqsave(current_SC->host->host_lock, flags); + spin_lock_irqsave(current_SC->device->host->host_lock, flags); my_done( DID_BUS_BUSY << 16 ); - spin_unlock_irqrestore(current_SC->host->host_lock, flags); + spin_unlock_irqrestore(current_SC->device->host->host_lock, flags); return; } current_SC->SCp.phase = in_selection; @@ -1262,7 +1262,7 @@ outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port ); outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */ - outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port ); + outb( adapter_mask | (1 << current_SC->device->id), SCSI_Data_NoACK_port ); /* Stop arbitration and enable parity */ outb( 0x10 | PARITY_MASK, TMC_Cntl_port ); @@ -1274,13 +1274,13 @@ status = inb( SCSI_Status_port ); if (!(status & 0x01)) { /* Try again, for slow devices */ - if (fdomain_select( current_SC->target )) { + if (fdomain_select( current_SC->device->id )) { #if EVERY_ACCESS printk( " SFAIL " ); #endif - spin_lock_irqsave(current_SC->host->host_lock, flags); + spin_lock_irqsave(current_SC->device->host->host_lock, flags); my_done( DID_NO_CONNECT << 16 ); - spin_unlock_irqrestore(current_SC->host->host_lock, flags); + spin_unlock_irqrestore(current_SC->device->host->host_lock, flags); return; } else { #if EVERY_ACCESS @@ -1337,7 +1337,7 @@ && current_SC->SCp.Status != 2 && current_SC->SCp.Status != 8) { printk( "scsi: target = %d, command = %x, status = %x\n", - current_SC->target, + current_SC->device->id, current_SC->cmnd[0], current_SC->SCp.Status ); } @@ -1476,10 +1476,10 @@ #if EVERY_ACCESS printk( "BEFORE MY_DONE. . ." ); #endif - spin_lock_irqsave(current_SC->host->host_lock, flags); + spin_lock_irqsave(current_SC->device->host->host_lock, flags); my_done( (current_SC->SCp.Status & 0xff) | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) ); - spin_unlock_irqrestore(current_SC->host->host_lock, flags); + spin_unlock_irqrestore(current_SC->device->host->host_lock, flags); #if EVERY_ACCESS printk( "RETURNING.\n" ); #endif @@ -1580,13 +1580,13 @@ unsigned int irr; unsigned int isr; - if (!SCpnt || !SCpnt->host) { + if (!SCpnt || !SCpnt->device || !SCpnt->device->host) { printk(KERN_WARNING "scsi: Cannot provide detailed information\n"); return; } - printk(KERN_INFO "%s\n", fdomain_16x0_info( SCpnt->host ) ); - print_banner(SCpnt->host); + printk(KERN_INFO "%s\n", fdomain_16x0_info( SCpnt->device->host ) ); + print_banner(SCpnt->device->host); switch (SCpnt->SCp.phase) { case in_arbitration: printk("arbitration"); break; case in_selection: printk("selection"); break; @@ -1596,7 +1596,7 @@ printk( " (%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n", SCpnt->SCp.phase, - SCpnt->target, + SCpnt->device->id, *(unsigned char *)SCpnt->cmnd, SCpnt->use_sg, SCpnt->request_bufflen ); diff -Nru a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c --- a/drivers/scsi/g_NCR5380.c Sun Feb 9 21:13:29 2003 +++ b/drivers/scsi/g_NCR5380.c Sun Feb 9 21:13:29 2003 @@ -746,7 +746,7 @@ static int sprint_Scsi_Cmnd(char *buffer, int len, Scsi_Cmnd * cmd) { int start = len; - PRINTP("host number %d destination target %d, lun %d\n" ANDP cmd->host->host_no ANDP cmd->target ANDP cmd->lun); + PRINTP("host number %d destination target %d, lun %d\n" ANDP cmd->device->host->host_no ANDP cmd->device->id ANDP cmd->device->lun); PRINTP(" command = "); len += sprint_command(buffer, len, cmd->cmnd); return len - start; diff -Nru a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c --- a/drivers/scsi/gdth.c Sun Feb 9 21:13:33 2003 +++ b/drivers/scsi/gdth.c Sun Feb 9 21:13:33 2003 @@ -2313,8 +2313,8 @@ GDTH_LOCK_HA(ha, flags); scp->SCp.this_residual = (int)priority; - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; - t = scp->target; + b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; + t = scp->device->id; #if LINUX_VERSION_CODE >= 0x010300 if (priority >= DEFAULT_PRI) { if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || @@ -2375,8 +2375,8 @@ for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) pscp = (Scsi_Cmnd *)pscp->SCp.ptr; - b = virt_ctr ? NUMDATA(nscp->host)->busnum : nscp->channel; - t = nscp->target; + b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel; + t = nscp->device->id; if (nscp->SCp.this_residual >= DEFAULT_PRI) { if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) @@ -2407,13 +2407,13 @@ b, t, nscp->lun)); /* TEST_UNIT_READY -> set scan mode */ if ((ha->scan_mode & 0x0f) == 0) { - if (b == 0 && t == 0 && nscp->lun == 0) { + if (b == 0 && t == 0 && nscp->device->lun == 0) { ha->scan_mode |= 1; TRACE2(("Scan mode: 0x%x\n", ha->scan_mode)); } } else if ((ha->scan_mode & 0x0f) == 1) { - if (b == 0 && ((t == 0 && nscp->lun == 1) || - (t == 1 && nscp->lun == 0))) { + if (b == 0 && ((t == 0 && nscp->device->lun == 1) || + (t == 1 && nscp->device->lun == 0))) { nscp->SCp.sent_command = GDT_SCAN_START; nscp->SCp.phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) | SCSIRAWSERVICE; @@ -2483,7 +2483,7 @@ this_cmd = FALSE; else ha->raw[BUS_L2P(ha,b)].io_cnt[t]++; - } else if (t >= MAX_HDRIVES || !ha->hdr[t].present || nscp->lun != 0) { + } else if (t >= MAX_HDRIVES || !ha->hdr[t].present || nscp->device->lun != 0) { TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n", nscp->cmnd[0], b, t, nscp->lun)); nscp->result = DID_BAD_TARGET << 16; @@ -2682,7 +2682,7 @@ gdth_modep_data mpd; ha = HADATA(gdth_ctr_tab[hanum]); - t = scp->target; + t = scp->device->id; TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", scp->cmnd[0],t)); @@ -2900,8 +2900,8 @@ unchar t,l; ha = HADATA(gdth_ctr_tab[hanum]); - t = scp->target; - l = scp->lun; + t = scp->device->id; + l = scp->device->lun; cmdp = ha->pccb; TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n", scp->cmnd[0],b,t,l)); @@ -3372,7 +3372,7 @@ if (rval == 2) { gdth_putq(hanum,scp,scp->SCp.this_residual); } else if (rval == 1) { - GDTH_LOCK_SCSI_DONE(scp->host, flags); + GDTH_LOCK_SCSI_DONE(scp->device->host, flags); scp->scsi_done(scp); GDTH_UNLOCK_SCSI_DONE(scp->host,flags); } @@ -3461,9 +3461,9 @@ printk("\n"); } else { - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; + b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; if (scp->SCp.sent_command == -1 && b != ha->virt_bus) { - ha->raw[BUS_L2P(ha,b)].io_cnt[scp->target]--; + ha->raw[BUS_L2P(ha,b)].io_cnt[scp->device->id]--; } /* cache or raw service */ if (ha->status == S_OK) { @@ -3474,12 +3474,12 @@ scp->SCp.sent_command)); /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */ if (scp->SCp.sent_command == GDT_CLUST_INFO) { - ha->hdr[scp->target].cluster_type = (unchar)ha->info; - if (!(ha->hdr[scp->target].cluster_type & + ha->hdr[scp->device->id].cluster_type = (unchar)ha->info; + if (!(ha->hdr[scp->device->id].cluster_type & CLUSTER_MOUNTED)) { /* NOT MOUNTED -> MOUNT */ scp->SCp.sent_command = GDT_MOUNT; - if (ha->hdr[scp->target].cluster_type & + if (ha->hdr[scp->device->id].cluster_type & CLUSTER_RESERVED) { /* cluster drive RESERVED (on the other node) */ scp->SCp.phase = -2; /* reservation conflict */ @@ -3489,11 +3489,11 @@ } } else { if (scp->SCp.sent_command == GDT_MOUNT) { - ha->hdr[scp->target].cluster_type |= CLUSTER_MOUNTED; - ha->hdr[scp->target].media_changed = TRUE; + ha->hdr[scp->device->id].cluster_type |= CLUSTER_MOUNTED; + ha->hdr[scp->device->id].media_changed = TRUE; } else if (scp->SCp.sent_command == GDT_UNMOUNT) { - ha->hdr[scp->target].cluster_type &= ~CLUSTER_MOUNTED; - ha->hdr[scp->target].media_changed = TRUE; + ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_MOUNTED; + ha->hdr[scp->device->id].media_changed = TRUE; } scp->SCp.sent_command = -1; } @@ -3503,9 +3503,9 @@ } else { /* RESERVE/RELEASE ? */ if (scp->cmnd[0] == RESERVE) { - ha->hdr[scp->target].cluster_type |= CLUSTER_RESERVED; + ha->hdr[scp->device->id].cluster_type |= CLUSTER_RESERVED; } else if (scp->cmnd[0] == RELEASE) { - ha->hdr[scp->target].cluster_type &= ~CLUSTER_RESERVED; + ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_RESERVED; } scp->result = DID_OK << 16; scp->sense_buffer[0] = 0; @@ -3538,10 +3538,10 @@ scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); } else if (service == CACHESERVICE) { if (ha->status == S_CACHE_UNKNOWN && - (ha->hdr[scp->target].cluster_type & + (ha->hdr[scp->device->id].cluster_type & CLUSTER_RESERVE_STATE) == CLUSTER_RESERVE_STATE) { /* bus reset -> force GDT_CLUST_INFO */ - ha->hdr[scp->target].cluster_type &= ~CLUSTER_RESERVED; + ha->hdr[scp->device->id].cluster_type &= ~CLUSTER_RESERVED; } memset((char*)scp->sense_buffer,0,16); if (ha->status == (ushort)S_CACHE_RESERV) { @@ -3560,7 +3560,7 @@ ha->dvr.eu.sync.service = service; ha->dvr.eu.sync.status = ha->status; ha->dvr.eu.sync.info = ha->info; - ha->dvr.eu.sync.hostdrive = scp->target; + ha->dvr.eu.sync.hostdrive = scp->device->id; if (ha->status >= 0x8000) gdth_store_event(ha, ES_SYNC, 0, &ha->dvr); else @@ -4507,15 +4507,15 @@ unchar b; TRACE2(("gdth_eh_bus_reset()\n")); - hanum = NUMDATA(scp->host)->hanum; - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; + hanum = NUMDATA(scp->device->host)->hanum; + b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; ha = HADATA(gdth_ctr_tab[hanum]); /* clear command tab */ GDTH_LOCK_HA(ha, flags); for (i = 0; i < GDTH_MAXCMDS; ++i) { cmnd = ha->cmd_tab[i].cmnd; - if (!SPECIAL_SCP(cmnd) && cmnd->channel == b) + if (!SPECIAL_SCP(cmnd) && cmnd->device->channel == b) ha->cmd_tab[i].cmnd = UNUSED_CMND; } GDTH_UNLOCK_HA(ha, flags); @@ -4593,13 +4593,13 @@ int priority; TRACE(("gdth_queuecommand() cmd 0x%x id %d lun %d\n", - scp->cmnd[0],scp->target,scp->lun)); + scp->cmnd[0],scp->device->id,scp->lun)); scp->scsi_done = (void *)done; scp->SCp.have_data_in = 1; scp->SCp.phase = -1; scp->SCp.sent_command = -1; - hanum = NUMDATA(scp->host)->hanum; + hanum = NUMDATA(scp->device->host)->hanum; #ifdef GDTH_STATISTICS ++act_ios; #endif @@ -4637,7 +4637,7 @@ #if LINUX_VERSION_CODE >= 0x020322 sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); - scp = scsi_allocate_device(sdev, 1); + scp = scsi_get_command(sdev, GFP_KERNEL); scp->cmd_len = 12; scp->use_sg = 0; #else @@ -4665,7 +4665,7 @@ } } #if LINUX_VERSION_CODE >= 0x020322 - scsi_release_command(scp); + scsi_put_command(scp); scsi_free_host_dev(sdev); #endif } @@ -4711,7 +4711,7 @@ memset(cmnd, 0xff, MAX_COMMAND_SIZE); #if LINUX_VERSION_CODE >= 0x020322 sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]); - scp = scsi_allocate_device(sdev, 1); + scp = scsi_get_command(sdev, GFP_KERNEL); scp->cmd_len = 12; scp->use_sg = 0; #else @@ -4728,7 +4728,7 @@ TRACE2(("gdth_halt(): reset controller %d\n", hanum)); #if LINUX_VERSION_CODE >= 0x020322 gdth_do_cmd(scp, &gdtcmd, cmnd, 10); - scsi_release_command(scp); + scsi_put_command(scp); scsi_free_host_dev(sdev); #else gdth_do_cmd(&scp, &gdtcmd, cmnd, 10); diff -Nru a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c --- a/drivers/scsi/gdth_proc.c Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/gdth_proc.c Sun Feb 9 21:13:32 2003 @@ -48,7 +48,7 @@ #if LINUX_VERSION_CODE >= 0x020322 sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]); - scp = scsi_allocate_device(sdev, 1); + scp = scsi_get_command(sdev, GFP_KERNEL); if (!scp) return -ENOMEM; scp->cmd_len = 12; @@ -81,7 +81,7 @@ ret_val = -EINVAL; } #if LINUX_VERSION_CODE >= 0x020322 - scsi_release_command(scp); + scsi_put_command(scp); scsi_free_host_dev(sdev); #endif return ret_val; @@ -447,8 +447,8 @@ piord->size = sizeof(gdth_iord_str); memcpy(cmnd, piowr->iu.scsi.cmd, 12); #if LINUX_VERSION_CODE >= 0x020322 - scp->target = piowr->iu.scsi.target; - scp->channel = virt_ctr ? 0 : piowr->iu.scsi.bus; + scp->device->id = piowr->iu.scsi.target; + scp->device->channel = virt_ctr ? 0 : piowr->iu.scsi.bus; scp->cmd_len = piowr->iu.scsi.cmd_len; gdth_do_cmd(scp, pcmd, cmnd, piowr->timeout); piord->status = (scp->SCp.Message<<16)|scp->SCp.Status; @@ -467,7 +467,7 @@ piord = (gdth_iord_str *)ha->pscratch; piord->size = sizeof(gdth_iord_str); #if LINUX_VERSION_CODE >= 0x020322 - scp->channel = virt_ctr ? 0 : piowr->iu.scsi.bus; + scp->device->channel = virt_ctr ? 0 : piowr->iu.scsi.bus; piord->status = (ulong32)gdth_eh_bus_reset( scp ); if (piord->status == SUCCESS) piord->status = S_OK; @@ -712,7 +712,7 @@ #if LINUX_VERSION_CODE >= 0x020322 sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]); - scp = scsi_allocate_device(sdev, 1); + scp = scsi_get_command(sdev, GFP_KERNEL); if (!scp) return -ENOMEM; scp->cmd_len = 12; @@ -1234,7 +1234,7 @@ stop_output: #if LINUX_VERSION_CODE >= 0x020322 - scsi_release_command(scp); + scsi_put_command(scp); scsi_free_host_dev(sdev); #endif *start = buffer +(offset-begin); @@ -1383,8 +1383,8 @@ for (i = 0; i < GDTH_MAXCMDS; ++i) { scp = ha->cmd_tab[i].cmnd; - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; - if (!SPECIAL_SCP(scp) && scp->target == (unchar)id && + b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; + if (!SPECIAL_SCP(scp) && scp->device->id == (unchar)id && b == (unchar)busnum) { scp->SCp.have_data_in = 0; GDTH_UNLOCK_HA(ha, flags); @@ -1410,8 +1410,8 @@ GDTH_LOCK_HA(ha, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; - if (scp->target == (unchar)id && b == (unchar)busnum) { + b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; + if (scp->device->id == (unchar)id && b == (unchar)busnum) { TRACE2(("gdth_stop_timeout(): update_timeout()\n")); scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); } @@ -1430,8 +1430,8 @@ GDTH_LOCK_HA(ha, flags); for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { - b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel; - if (scp->target == (unchar)id && b == (unchar)busnum) { + b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; + if (scp->device->id == (unchar)id && b == (unchar)busnum) { TRACE2(("gdth_start_timeout(): update_timeout()\n")); gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual); } diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c --- a/drivers/scsi/hosts.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/hosts.c Sun Feb 9 21:13:28 2003 @@ -205,13 +205,15 @@ { struct Scsi_Host *shost = sdev->host; struct scsi_cmnd *scmd; + unsigned long flags; /* * Loop over all of the commands associated with the * device. If any of them are busy, then set the state * back to inactive and bail. */ - for (scmd = sdev->device_queue; scmd; scmd = scmd->next) { + spin_lock_irqsave(&sdev->list_lock, flags); + list_for_each_entry(scmd, &sdev->cmd_list, list) { if (scmd->request && scmd->request->rq_status != RQ_INACTIVE) goto active; @@ -223,22 +225,24 @@ if (scmd->request) scmd->request->rq_status = RQ_SCSI_DISCONNECTING; } + spin_unlock_irqrestore(&sdev->list_lock, flags); return 0; active: printk(KERN_ERR "SCSI device not inactive - rq_status=%d, target=%d, " "pid=%ld, state=%d, owner=%d.\n", - scmd->request->rq_status, scmd->target, + scmd->request->rq_status, scmd->device->id, scmd->pid, scmd->state, scmd->owner); list_for_each_entry(sdev, &shost->my_devices, siblings) { - for (scmd = sdev->device_queue; scmd; scmd = scmd->next) { + list_for_each_entry(scmd, &sdev->cmd_list, list) { if (scmd->request->rq_status == RQ_SCSI_DISCONNECTING) scmd->request->rq_status = RQ_INACTIVE; } } + spin_unlock_irqrestore(&sdev->list_lock, flags); printk(KERN_ERR "Device busy???\n"); return 1; } @@ -285,7 +289,15 @@ return 0; } -int __scsi_add_host(struct Scsi_Host *shost) +/** + * scsi_add_host - add a scsi host + * @shost: scsi host pointer to add + * @dev: a struct device of type scsi class + * + * Return value: + * 0 on success / != 0 for error + **/ +int scsi_add_host(struct Scsi_Host *shost, struct device *dev) { Scsi_Host_Template *sht = shost->hostt; struct scsi_device *sdev; @@ -294,6 +306,11 @@ printk(KERN_INFO "scsi%d : %s\n", shost->host_no, sht->info ? sht->info(shost) : sht->name); + if (dev) { + dev->class_data = shost; + shost->host_gendev = dev; + } + scsi_scan_host(shost); list_for_each_entry (sdev, &shost->my_devices, siblings) { @@ -306,23 +323,6 @@ } /** - * scsi_add_host - add a scsi host - * @shost: scsi host pointer to add - * @dev: a struct device of type scsi class - * - * Return value: - * 0 on success / != 0 for error - **/ -int scsi_add_host(struct Scsi_Host *shost, struct device *dev) -{ - if (dev) { - dev->class_data = shost; - shost->host_gendev = dev; - } - return __scsi_add_host(shost); -} - -/** * scsi_unregister - unregister a scsi host * @shost: scsi host to be unregistered **/ @@ -346,10 +346,8 @@ } shost->hostt->present--; - - /* Cleanup proc */ scsi_proc_host_rm(shost); - + scsi_destroy_command_freelist(shost); kfree(shost); } @@ -370,7 +368,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes) { struct Scsi_Host *shost, *shost_scr; - int gfp_mask; + int gfp_mask, rval; DECLARE_COMPLETION(sem); /* Check to see if this host has any error handling facilities */ @@ -398,7 +396,6 @@ spin_lock_init(&shost->default_lock); scsi_assign_lock(shost, &shost->default_lock); - atomic_set(&shost->host_active,0); INIT_LIST_HEAD(&shost->my_devices); init_waitqueue_head(&shost->host_wait); @@ -437,7 +434,7 @@ shost->unchecked_isa_dma = shost_tp->unchecked_isa_dma; shost->use_clustering = shost_tp->use_clustering; if (!blk_nohighio) - shost->highmem_io = shost_tp->highmem_io; + shost->highmem_io = shost_tp->highmem_io; shost->max_sectors = shost_tp->max_sectors; shost->use_blk_tcq = shost_tp->use_blk_tcq; @@ -459,6 +456,9 @@ found: spin_unlock(&scsi_host_list_lock); + rval = scsi_setup_command_freelist(shost); + if (rval) + goto fail; scsi_proc_host_add(shost); shost->eh_notify = &sem; @@ -469,10 +469,15 @@ */ wait_for_completion(&sem); shost->eh_notify = NULL; - shost->hostt->present++; - return shost; + +fail: + spin_lock(&scsi_host_list_lock); + list_del(&shost->sh_list); + spin_unlock(&scsi_host_list_lock); + kfree(shost); + return NULL; } /** @@ -505,7 +510,7 @@ */ list_for_each_entry(shost, &scsi_host_list, sh_list) if (shost->hostt == shost_tp) - if (__scsi_add_host(shost)) + if (scsi_add_host(shost, NULL)) goto out_of_space; return 0; diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h --- a/drivers/scsi/hosts.h Sun Feb 9 21:13:30 2003 +++ b/drivers/scsi/hosts.h Sun Feb 9 21:13:30 2003 @@ -29,6 +29,9 @@ #include #include +struct scsi_host_cmd_pool; + + /* It is senseless to set SG_ALL any higher than this - the performance * does not get any better, and it wastes memory */ @@ -375,6 +378,10 @@ struct list_head sh_list; struct list_head my_devices; + struct scsi_host_cmd_pool *cmd_pool; + spinlock_t free_list_lock; + struct list_head free_list; /* backup store of cmd structs */ + spinlock_t default_lock; spinlock_t *host_lock; @@ -389,7 +396,6 @@ unsigned int eh_kill:1; /* set when killing the eh thread */ wait_queue_head_t host_wait; Scsi_Host_Template * hostt; - atomic_t host_active; /* commands checked out */ volatile unsigned short host_busy; /* commands actually active on low-level */ volatile unsigned short host_failed; /* commands that failed. */ @@ -605,8 +611,8 @@ list_for_each_entry (sdev, &shost->my_devices, siblings) if (sdev->channel == channel && sdev->id == pun && sdev->lun ==lun) - break; - return sdev; + return sdev; + return NULL; } /* diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c --- a/drivers/scsi/ide-scsi.c Sun Feb 9 21:13:33 2003 +++ b/drivers/scsi/ide-scsi.c Sun Feb 9 21:13:33 2003 @@ -96,9 +96,18 @@ unsigned long flags; /* Status/Action flags */ unsigned long transform; /* SCSI cmd translation layer */ unsigned long log; /* log flags */ - int id; } idescsi_scsi_t; +static inline idescsi_scsi_t *scsihost_to_idescsi(struct Scsi_Host *host) +{ + return (idescsi_scsi_t*) (&host[1]); +} + +static inline idescsi_scsi_t *drive_to_idescsi(ide_drive_t *ide_drive) +{ + return scsihost_to_idescsi(ide_drive->driver_data); +} + /* * Per ATAPI device status bits. */ @@ -262,7 +271,7 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_command) { - idescsi_scsi_t *scsi = drive->driver_data; + idescsi_scsi_t *scsi = drive_to_idescsi(drive); idescsi_pc_t *pc; struct request *rq; u8 *buf; @@ -299,7 +308,7 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) { - idescsi_scsi_t *scsi = drive->driver_data; + idescsi_scsi_t *scsi = drive_to_idescsi(drive); struct request *rq = HWGROUP(drive)->rq; idescsi_pc_t *pc = (idescsi_pc_t *) rq->special; int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); @@ -348,7 +357,7 @@ } else printk("\n"); } } - host = pc->scsi_cmd->host; + host = pc->scsi_cmd->device->host; spin_lock_irqsave(host->host_lock, flags); pc->done(pc->scsi_cmd); spin_unlock_irqrestore(host->host_lock, flags); @@ -369,7 +378,7 @@ */ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) { - idescsi_scsi_t *scsi = drive->driver_data; + idescsi_scsi_t *scsi = drive_to_idescsi(drive); idescsi_pc_t *pc=scsi->pc; struct request *rq = pc->rq; atapi_bcount_t bcount; @@ -463,7 +472,7 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive) { - idescsi_scsi_t *scsi = drive->driver_data; + idescsi_scsi_t *scsi = drive_to_idescsi(drive); idescsi_pc_t *pc = scsi->pc; atapi_ireason_t ireason; ide_startstop_t startstop; @@ -493,7 +502,7 @@ */ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc) { - idescsi_scsi_t *scsi = drive->driver_data; + idescsi_scsi_t *scsi = drive_to_idescsi(drive); atapi_feature_t feature; atapi_bcount_t bcount; struct request *rq = pc->rq; @@ -555,11 +564,9 @@ return ide_stopped; } -static ide_drive_t *idescsi_drives[MAX_HWIFS * MAX_DRIVES]; - static void idescsi_add_settings(ide_drive_t *drive) { - idescsi_scsi_t *scsi = drive->driver_data; + idescsi_scsi_t *scsi = drive_to_idescsi(drive); /* * drive setting name read/write ioctl ioctl data type min max mul_factor div_factor data pointer set function @@ -574,15 +581,10 @@ /* * Driver initialization. */ -static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi, int id) +static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) { DRIVER(drive)->busy++; - idescsi_drives[id] = drive; - drive->driver_data = scsi; drive->ready_stat = 0; - memset (scsi, 0, sizeof (idescsi_scsi_t)); - scsi->drive = drive; - scsi->id = id; if (drive->id && (drive->id->config & 0x0060) == 0x20) set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags); set_bit(IDESCSI_TRANSFORM, &scsi->transform); @@ -596,13 +598,17 @@ static int idescsi_cleanup (ide_drive_t *drive) { - idescsi_scsi_t *scsi = drive->driver_data; + struct Scsi_Host *scsihost = drive->driver_data; if (ide_unregister_subdriver(drive)) return 1; + + /* FIXME?: Are these two statements necessary? */ drive->driver_data = NULL; drive->disk->fops = ide_fops; - kfree(scsi); + + scsi_remove_host(scsihost); + scsi_unregister(scsihost); return 0; } @@ -654,52 +660,23 @@ .ioctl = idescsi_ide_ioctl, }; -static int idescsi_attach(ide_drive_t *drive) -{ - idescsi_scsi_t *scsi; - int id; - - if (!strstr("ide-scsi", drive->driver_req)) - goto failed; - if (!drive->present) - goto failed; - /* we accept everything except ide-disk */ - if (drive->media == ide_disk) - goto failed; - if ((scsi = (idescsi_scsi_t *) kmalloc (sizeof (idescsi_scsi_t), GFP_KERNEL)) == NULL) { - printk (KERN_ERR "ide-scsi: %s: Can't allocate a scsi structure\n", drive->name); - goto failed; - } - if (ide_register_subdriver (drive, &idescsi_driver, IDE_SUBDRIVER_VERSION)) { - printk (KERN_ERR "ide-scsi: %s: Failed to register the driver with ide.c\n", drive->name); - kfree (scsi); - goto failed; - } - for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++) - ; - idescsi_setup (drive, scsi, id); - drive->disk->fops = &idescsi_ops; - return 0; -failed: - return 1; -} +static int idescsi_attach(ide_drive_t *drive); -int idescsi_slave_configure(Scsi_Device * sdp) +static int idescsi_slave_configure(Scsi_Device * sdp) { /* Configure detected device */ scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun); return 0; } -const char *idescsi_info (struct Scsi_Host *host) +static const char *idescsi_info (struct Scsi_Host *host) { return "SCSI host adapter emulation for IDE ATAPI devices"; } -int idescsi_ioctl (Scsi_Device *dev, int cmd, void *arg) +static int idescsi_ioctl (Scsi_Device *dev, int cmd, void *arg) { - ide_drive_t *drive = idescsi_drives[dev->id]; - idescsi_scsi_t *scsi = drive->driver_data; + idescsi_scsi_t *scsi = scsihost_to_idescsi(dev->host); if (cmd == SG_SET_TRANSFORM) { if (arg) @@ -789,7 +766,7 @@ static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd) { - idescsi_scsi_t *scsi = drive->driver_data; + idescsi_scsi_t *scsi = drive_to_idescsi(drive); struct gendisk *disk = cmd->request->rq_disk; if (disk) { @@ -800,18 +777,18 @@ return test_bit(IDESCSI_TRANSFORM, &scsi->transform); } -int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) +static int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) { - ide_drive_t *drive = idescsi_drives[cmd->target]; - idescsi_scsi_t *scsi; + idescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host); + ide_drive_t *drive = scsi->drive; struct request *rq = NULL; idescsi_pc_t *pc = NULL; if (!drive) { - printk (KERN_ERR "ide-scsi: drive id %d not present\n", cmd->target); + printk (KERN_ERR "ide-scsi: drive id %d not present\n", cmd->device->id); goto abort; } - scsi = drive->driver_data; + scsi = drive_to_idescsi(drive); pc = kmalloc (sizeof (idescsi_pc_t), GFP_ATOMIC); rq = kmalloc (sizeof (struct request), GFP_ATOMIC); if (rq == NULL || pc == NULL) { @@ -853,9 +830,9 @@ rq->special = (char *) pc; rq->bio = idescsi_dma_bio (drive, pc); rq->flags = REQ_SPECIAL; - spin_unlock_irq(cmd->host->host_lock); + spin_unlock_irq(cmd->device->host->host_lock); (void) ide_do_drive_cmd (drive, rq, ide_end); - spin_lock_irq(cmd->host->host_lock); + spin_lock_irq(cmd->device->host->host_lock); return 0; abort: if (pc) kfree (pc); @@ -865,43 +842,43 @@ return 1; } -int idescsi_abort (Scsi_Cmnd *cmd) +static int idescsi_abort (Scsi_Cmnd *cmd) { int countdown = 8; unsigned long flags; - ide_drive_t *drive = idescsi_drives[cmd->target]; - idescsi_scsi_t *scsi; + idescsi_scsi_t *scsi = scsihost_to_idescsi(cmd->device->host); + ide_drive_t *drive = scsi->drive; printk (KERN_ERR "ide-scsi: abort called for %lu\n", cmd->serial_number); - if (drive && (scsi = drive->driver_data)) - while (countdown--) { - /* is cmd active? - * need to lock so this stuff doesn't change under us */ - spin_lock_irqsave(&ide_lock, flags); - if (scsi->pc && scsi->pc->scsi_cmd && - scsi->pc->scsi_cmd->serial_number == cmd->serial_number) { - /* yep - let's give it some more time - - * we can do that, we're in _our_ error kernel thread */ - spin_unlock_irqrestore(&ide_lock, flags); - scsi_sleep(HZ); - continue; - } - /* no, but is it queued in the ide subsystem? */ - if (elv_queue_empty(&drive->queue)) { - spin_unlock_irqrestore(&ide_lock, flags); - return SUCCESS; - } + while (countdown--) { + /* is cmd active? + * need to lock so this stuff doesn't change under us */ + spin_lock_irqsave(&ide_lock, flags); + if (scsi->pc && scsi->pc->scsi_cmd && + scsi->pc->scsi_cmd->serial_number == cmd->serial_number) { + /* yep - let's give it some more time - + * we can do that, we're in _our_ error kernel thread */ + spin_unlock_irqrestore(&ide_lock, flags); + scsi_sleep(HZ); + continue; + } + /* no, but is it queued in the ide subsystem? */ + if (elv_queue_empty(&drive->queue)) { spin_unlock_irqrestore(&ide_lock, flags); - schedule_timeout(HZ/10); + return SUCCESS; } + spin_unlock_irqrestore(&ide_lock, flags); + schedule_timeout(HZ/10); + } return FAILED; } -int idescsi_reset (Scsi_Cmnd *cmd) +static int idescsi_reset (Scsi_Cmnd *cmd) { unsigned long flags; struct request *req; - ide_drive_t *drive = idescsi_drives[cmd->target]; + idescsi_scsi_t *idescsi = scsihost_to_idescsi(cmd->device->host); + ide_drive_t *drive = idescsi->drive; printk (KERN_ERR "ide-scsi: reset called for %lu\n", cmd->serial_number); /* first null the handler for the drive and let any process @@ -919,7 +896,8 @@ } /* FIXME - this will probably leak memory */ HWGROUP(drive)->rq = NULL; - if (drive->driver_data) ((idescsi_scsi_t *)drive->driver_data)->pc = NULL; + if (drive_to_idescsi(drive)) + drive_to_idescsi(drive)->pc = NULL; spin_unlock_irqrestore(&ide_lock, flags); /* finally, reset the drive (and its partner on the bus...) */ ide_do_reset (drive); @@ -929,7 +907,8 @@ static int idescsi_bios(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int *parm) { - ide_drive_t *drive = idescsi_drives[sdev->id]; + idescsi_scsi_t *idescsi = scsihost_to_idescsi(sdev->host); + ide_drive_t *drive = idescsi->drive; if (drive->bios_cyl && drive->bios_head && drive->bios_sect) { parm[0] = drive->bios_head; @@ -956,10 +935,9 @@ .max_sectors = 128, .use_clustering = DISABLE_CLUSTERING, .emulated = 1, + .proc_name = "ide-scsi", }; -static struct Scsi_Host *idescsi_host; - static struct device idescsi_primary = { .name = "Ide-scsi Parent", .bus_id = "ide-scsi", @@ -968,39 +946,60 @@ .name = "ide-scsi", }; -static int __init init_idescsi_module(void) +static int idescsi_attach(ide_drive_t *drive) { - int id; - int last_lun = 0; + idescsi_scsi_t *idescsi; + struct Scsi_Host *host; + int err; - ide_register_driver(&idescsi_driver); - device_register(&idescsi_primary); - bus_register (&idescsi_emu_bus); - idescsi_template.proc_name = "ide-scsi"; - idescsi_host = scsi_register(&idescsi_template, 0); - if(idescsi_host == NULL) + if (!strstr("ide-scsi", drive->driver_req) || + !drive->present || + drive->media == ide_disk || + !(host = scsi_register(&idescsi_template,sizeof(idescsi_scsi_t)))) return 1; - - for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++) - last_lun = IDE_MAX(last_lun, idescsi_drives[id]->last_lun); - idescsi_host->max_id = id; - idescsi_host->max_lun = last_lun + 1; - scsi_add_host(idescsi_host, &idescsi_primary); - return 0; + + host->max_id = 1; + host->max_lun = 1; + drive->driver_data = host; + idescsi = scsihost_to_idescsi(host); + idescsi->drive = drive; + err = ide_register_subdriver (drive, &idescsi_driver, + IDE_SUBDRIVER_VERSION); + if (!err) { + idescsi_setup (drive, idescsi); + drive->disk->fops = &idescsi_ops; + err = scsi_add_host(host, &idescsi_primary); + if (!err) + return 0; + /* fall through on error */ + ide_unregister_subdriver(drive); + } + + scsi_unregister(host); + return err; } -static void __exit exit_idescsi_module(void) +static int __init init_idescsi_module(void) { - ide_drive_t *drive; - int id; + int err; - scsi_remove_host(idescsi_host); - for (id = 0; id < MAX_HWIFS * MAX_DRIVES; id++) { - drive = idescsi_drives[id]; - if (drive) - DRIVER(drive)->busy = 0; + err = bus_register(&idescsi_emu_bus); + if (!err) { + err = device_register(&idescsi_primary); + if (!err) { + err = ide_register_driver(&idescsi_driver); + if (!err) + return 0; + + device_unregister(&idescsi_primary); + } + bus_unregister(&idescsi_emu_bus); } - scsi_unregister (idescsi_host); + return err; +} + +static void __exit exit_idescsi_module(void) +{ device_unregister(&idescsi_primary); bus_unregister (&idescsi_emu_bus); ide_unregister_driver(&idescsi_driver); diff -Nru a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c --- a/drivers/scsi/in2000.c Sun Feb 9 21:13:34 2003 +++ b/drivers/scsi/in2000.c Sun Feb 9 21:13:34 2003 @@ -343,10 +343,10 @@ struct IN2000_hostdata *hostdata; Scsi_Cmnd *tmp; - instance = cmd->host; + instance = cmd->device->host; hostdata = (struct IN2000_hostdata *) instance->hostdata; - DB(DB_QUEUE_COMMAND, printk("Q-%d-%02x-%ld(", cmd->target, cmd->cmnd[0], cmd->pid)) + DB(DB_QUEUE_COMMAND, printk("Q-%d-%02x-%ld(", cmd->device->id, cmd->cmnd[0], cmd->pid)) /* Set up a few fields in the Scsi_Cmnd structure for our own use: * - host_scribble is the pointer to the next cmd in the input queue @@ -428,7 +428,7 @@ * Go see if any of them are runnable! */ - in2000_execute(cmd->host); + in2000_execute(cmd->device->host); DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->pid)) return 0; @@ -473,7 +473,7 @@ cmd = (Scsi_Cmnd *) hostdata->input_Q; prev = 0; while (cmd) { - if (!(hostdata->busy[cmd->target] & (1 << cmd->lun))) + if (!(hostdata->busy[cmd->device->id] & (1 << cmd->device->lun))) break; prev = cmd; cmd = (Scsi_Cmnd *) cmd->host_scribble; @@ -496,7 +496,7 @@ hostdata->input_Q = (Scsi_Cmnd *) cmd->host_scribble; #ifdef PROC_STATISTICS - hostdata->cmd_cnt[cmd->target]++; + hostdata->cmd_cnt[cmd->device->id]++; #endif /* @@ -504,9 +504,9 @@ */ if (is_dir_out(cmd)) - write_3393(hostdata, WD_DESTINATION_ID, cmd->target); + write_3393(hostdata, WD_DESTINATION_ID, cmd->device->id); else - write_3393(hostdata, WD_DESTINATION_ID, cmd->target | DSTID_DPD); + write_3393(hostdata, WD_DESTINATION_ID, cmd->device->id | DSTID_DPD); /* Now we need to figure out whether or not this command is a good * candidate for disconnect/reselect. We guess to the best of our @@ -543,7 +543,7 @@ if (!(hostdata->input_Q)) /* input_Q empty? */ goto no; for (prev = (Scsi_Cmnd *) hostdata->input_Q; prev; prev = (Scsi_Cmnd *) prev->host_scribble) { - if ((prev->target != cmd->target) || (prev->lun != cmd->lun)) { + if ((prev->device->id != cmd->device->id) || (prev->device->lun != cmd->device->lun)) { for (prev = (Scsi_Cmnd *) hostdata->input_Q; prev; prev = (Scsi_Cmnd *) prev->host_scribble) prev->SCp.phase = 1; goto yes; @@ -555,17 +555,17 @@ cmd->SCp.phase = 1; #ifdef PROC_STATISTICS - hostdata->disc_allowed_cnt[cmd->target]++; + hostdata->disc_allowed_cnt[cmd->device->id]++; #endif no: write_3393(hostdata, WD_SOURCE_ID, ((cmd->SCp.phase) ? SRCID_ER : 0)); - write_3393(hostdata, WD_TARGET_LUN, cmd->lun); - write_3393(hostdata, WD_SYNCHRONOUS_TRANSFER, hostdata->sync_xfer[cmd->target]); - hostdata->busy[cmd->target] |= (1 << cmd->lun); + write_3393(hostdata, WD_TARGET_LUN, cmd->device->lun); + write_3393(hostdata, WD_SYNCHRONOUS_TRANSFER, hostdata->sync_xfer[cmd->device->id]); + hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); - if ((hostdata->level2 <= L2_NONE) || (hostdata->sync_stat[cmd->target] == SS_UNSET)) { + if ((hostdata->level2 <= L2_NONE) || (hostdata->sync_stat[cmd->device->id] == SS_UNSET)) { /* * Do a 'Select-With-ATN' command. This will end with @@ -587,11 +587,11 @@ * unless we don't want to even _try_ synchronous transfers: In this * case we set SS_SET to make the defaults final. */ - if (hostdata->sync_stat[cmd->target] == SS_UNSET) { - if (hostdata->sync_off & (1 << cmd->target)) - hostdata->sync_stat[cmd->target] = SS_SET; + if (hostdata->sync_stat[cmd->device->id] == SS_UNSET) { + if (hostdata->sync_off & (1 << cmd->device->id)) + hostdata->sync_stat[cmd->device->id] = SS_SET; else - hostdata->sync_stat[cmd->target] = SS_FIRST; + hostdata->sync_stat[cmd->device->id] = SS_FIRST; } hostdata->state = S_SELECTING; write_3393_count(hostdata, 0); /* this guarantees a DATA_PHASE interrupt */ @@ -753,7 +753,7 @@ unsigned short f; int i; - hostdata = (struct IN2000_hostdata *) cmd->host->hostdata; + hostdata = (struct IN2000_hostdata *) cmd->device->host->hostdata; /* Normally, you'd expect 'this_residual' to be non-zero here. * In a series of scatter-gather transfers, however, this @@ -772,7 +772,7 @@ /* Set up hardware registers */ - write_3393(hostdata, WD_SYNCHRONOUS_TRANSFER, hostdata->sync_xfer[cmd->target]); + write_3393(hostdata, WD_SYNCHRONOUS_TRANSFER, hostdata->sync_xfer[cmd->device->id]); write_3393_count(hostdata, cmd->SCp.this_residual); write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_BUS); write1_io(0, IO_FIFO_WRITE); /* zero counter, assume write */ @@ -1077,7 +1077,7 @@ } cmd->result = DID_NO_CONNECT << 16; - hostdata->busy[cmd->target] &= ~(1 << cmd->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); hostdata->state = S_UNCONNECTED; cmd->scsi_done(cmd); @@ -1099,16 +1099,16 @@ /* construct an IDENTIFY message with correct disconnect bit */ - hostdata->outgoing_msg[0] = (0x80 | 0x00 | cmd->lun); + hostdata->outgoing_msg[0] = (0x80 | 0x00 | cmd->device->lun); if (cmd->SCp.phase) hostdata->outgoing_msg[0] |= 0x40; - if (hostdata->sync_stat[cmd->target] == SS_FIRST) { + if (hostdata->sync_stat[cmd->device->id] == SS_FIRST) { #ifdef SYNC_DEBUG printk(" sending SDTR "); #endif - hostdata->sync_stat[cmd->target] = SS_WAITING; + hostdata->sync_stat[cmd->device->id] = SS_WAITING; /* tack on a 2nd message to ask about synchronous transfers */ @@ -1227,8 +1227,8 @@ #ifdef SYNC_DEBUG printk("-REJ-"); #endif - if (hostdata->sync_stat[cmd->target] == SS_WAITING) - hostdata->sync_stat[cmd->target] = SS_SET; + if (hostdata->sync_stat[cmd->device->id] == SS_WAITING) + hostdata->sync_stat[cmd->device->id] = SS_SET; write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK); hostdata->state = S_CONNECTED; break; @@ -1248,7 +1248,7 @@ switch (ucp[2]) { /* what's the EXTENDED code? */ case EXTENDED_SDTR: id = calc_sync_xfer(ucp[3], ucp[4]); - if (hostdata->sync_stat[cmd->target] != SS_WAITING) { + if (hostdata->sync_stat[cmd->device->id] != SS_WAITING) { /* A device has sent an unsolicited SDTR message; rather than go * through the effort of decoding it and then figuring out what @@ -1266,14 +1266,14 @@ hostdata->outgoing_msg[3] = hostdata->default_sx_per / 4; hostdata->outgoing_msg[4] = 0; hostdata->outgoing_len = 5; - hostdata->sync_xfer[cmd->target] = calc_sync_xfer(hostdata->default_sx_per / 4, 0); + hostdata->sync_xfer[cmd->device->id] = calc_sync_xfer(hostdata->default_sx_per / 4, 0); } else { - hostdata->sync_xfer[cmd->target] = id; + hostdata->sync_xfer[cmd->device->id] = id; } #ifdef SYNC_DEBUG - printk("sync_xfer=%02x", hostdata->sync_xfer[cmd->target]); + printk("sync_xfer=%02x", hostdata->sync_xfer[cmd->device->id]); #endif - hostdata->sync_stat[cmd->target] = SS_SET; + hostdata->sync_stat[cmd->device->id] = SS_SET; write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK); hostdata->state = S_CONNECTED; break; @@ -1335,7 +1335,7 @@ lun = read_3393(hostdata, WD_TARGET_LUN); DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun)) hostdata->connected = NULL; - hostdata->busy[cmd->target] &= ~(1 << cmd->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); hostdata->state = S_UNCONNECTED; if (cmd->SCp.Status == ILLEGAL_STATUS_BYTE) cmd->SCp.Status = lun; @@ -1420,7 +1420,7 @@ } DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->pid)) hostdata->connected = NULL; - hostdata->busy[cmd->target] &= ~(1 << cmd->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); hostdata->state = S_UNCONNECTED; if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD) cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); @@ -1451,7 +1451,7 @@ switch (hostdata->state) { case S_PRE_CMP_DISC: hostdata->connected = NULL; - hostdata->busy[cmd->target] &= ~(1 << cmd->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); hostdata->state = S_UNCONNECTED; DB(DB_INTR, printk(":%d", cmd->SCp.Status)) if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != GOOD) @@ -1468,7 +1468,7 @@ hostdata->state = S_UNCONNECTED; #ifdef PROC_STATISTICS - hostdata->disc_done_cnt[cmd->target]++; + hostdata->disc_done_cnt[cmd->device->id]++; #endif break; @@ -1496,7 +1496,7 @@ if (hostdata->selecting) { cmd = (Scsi_Cmnd *) hostdata->selecting; hostdata->selecting = NULL; - hostdata->busy[cmd->target] &= ~(1 << cmd->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); cmd->host_scribble = (uchar *) hostdata->input_Q; hostdata->input_Q = cmd; } @@ -1506,7 +1506,7 @@ if (cmd) { if (phs == 0x00) { - hostdata->busy[cmd->target] &= ~(1 << cmd->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); cmd->host_scribble = (uchar *) hostdata->input_Q; hostdata->input_Q = cmd; } else { @@ -1538,7 +1538,7 @@ cmd = (Scsi_Cmnd *) hostdata->disconnected_Q; patch = NULL; while (cmd) { - if (id == cmd->target && lun == cmd->lun) + if (id == cmd->device->id && lun == cmd->device->lun) break; patch = cmd; cmd = (Scsi_Cmnd *) cmd->host_scribble; @@ -1565,9 +1565,9 @@ */ if (is_dir_out(cmd)) - write_3393(hostdata, WD_DESTINATION_ID, cmd->target); + write_3393(hostdata, WD_DESTINATION_ID, cmd->device->id); else - write_3393(hostdata, WD_DESTINATION_ID, cmd->target | DSTID_DPD); + write_3393(hostdata, WD_DESTINATION_ID, cmd->device->id | DSTID_DPD); if (hostdata->level2 >= L2_RESELECT) { write_3393_count(hostdata, 0); /* we want a DATA_PHASE interrupt */ write_3393(hostdata, WD_COMMAND_PHASE, 0x45); @@ -1648,7 +1648,7 @@ struct IN2000_hostdata *hostdata; int x; - instance = cmd->host; + instance = cmd->device->host; hostdata = (struct IN2000_hostdata *) instance->hostdata; printk(KERN_WARNING "scsi%d: Reset. ", instance->host_no); @@ -1693,7 +1693,7 @@ uchar sr, asr; unsigned long timeout; - instance = cmd->host; + instance = cmd->device->host; hostdata = (struct IN2000_hostdata *) instance->hostdata; printk(KERN_DEBUG "scsi%d: Abort-", instance->host_no); @@ -1767,7 +1767,7 @@ sr = read_3393(hostdata, WD_SCSI_STATUS); printk("asr=%02x, sr=%02x.", asr, sr); - hostdata->busy[cmd->target] &= ~(1 << cmd->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); hostdata->connected = NULL; hostdata->state = S_UNCONNECTED; cmd->result = DID_ABORT << 16; @@ -2263,7 +2263,7 @@ strcat(bp, "\nconnected: "); if (hd->connected) { cmd = (Scsi_Cmnd *) hd->connected; - sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]); + sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); strcat(bp, tbuf); } } @@ -2271,7 +2271,7 @@ strcat(bp, "\ninput_Q: "); cmd = (Scsi_Cmnd *) hd->input_Q; while (cmd) { - sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]); + sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); strcat(bp, tbuf); cmd = (Scsi_Cmnd *) cmd->host_scribble; } @@ -2280,7 +2280,7 @@ strcat(bp, "\ndisconnected_Q:"); cmd = (Scsi_Cmnd *) hd->disconnected_Q; while (cmd) { - sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->target, cmd->lun, cmd->cmnd[0]); + sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); strcat(bp, tbuf); cmd = (Scsi_Cmnd *) cmd->host_scribble; } diff -Nru a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c --- a/drivers/scsi/ini9100u.c Sun Feb 9 21:13:30 2003 +++ b/drivers/scsi/ini9100u.c Sun Feb 9 21:13:30 2003 @@ -466,9 +466,9 @@ pSCB->SCB_Srb = SCpnt; pSCB->SCB_Opcode = ExecSCSI; pSCB->SCB_Flags = SCF_POST; /* After SCSI done, call post routine */ - pSCB->SCB_Target = SCpnt->target; - pSCB->SCB_Lun = SCpnt->lun; - pSCB->SCB_Ident = SCpnt->lun | DISC_ALLOW; + pSCB->SCB_Target = SCpnt->device->id; + pSCB->SCB_Lun = SCpnt->device->lun; + pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW; pSCB->SCB_Flags |= SCF_SENSE; /* Turn on auto request sense */ pSCB->SCB_SensePtr = (U32) VIRT_TO_BUS(SCpnt->sense_buffer); @@ -522,13 +522,13 @@ register SCB *pSCB; HCS *pHCB; /* Point to Host adapter control block */ - if (SCpnt->lun > 16) { /* 07/22/98 */ + if (SCpnt->device->lun > 16) { /* 07/22/98 */ SCpnt->result = (DID_TIME_OUT << 16); done(SCpnt); /* Notify system DONE */ return (0); } - pHCB = (HCS *) SCpnt->host->base; + pHCB = (HCS *) SCpnt->device->host->base; SCpnt->scsi_done = done; /* Get free SCSI control block */ @@ -558,7 +558,7 @@ { HCS *pHCB; - pHCB = (HCS *) SCpnt->host->base; + pHCB = (HCS *) SCpnt->device->host->base; return tul_abort_srb(pHCB, SCpnt); } @@ -570,12 +570,12 @@ { /* I need Host Control Block Information */ HCS *pHCB; - pHCB = (HCS *) SCpnt->host->base; + pHCB = (HCS *) SCpnt->device->host->base; if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET)) return tul_reset_scsi_bus(pHCB); else - return tul_device_reset(pHCB, (ULONG) SCpnt, SCpnt->target, reset_flags); + return tul_device_reset(pHCB, (ULONG) SCpnt, SCpnt->device->id, reset_flags); } /* diff -Nru a/drivers/scsi/inia100.c b/drivers/scsi/inia100.c --- a/drivers/scsi/inia100.c Sun Feb 9 21:13:30 2003 +++ b/drivers/scsi/inia100.c Sun Feb 9 21:13:30 2003 @@ -459,8 +459,8 @@ pSCB->SCB_Opcode = ORC_EXECSCSI; pSCB->SCB_Flags = SCF_NO_DCHK; /* Clear done bit */ - pSCB->SCB_Target = SCpnt->target; - pSCB->SCB_Lun = SCpnt->lun; + pSCB->SCB_Target = SCpnt->device->id; + pSCB->SCB_Lun = SCpnt->device->lun; pSCB->SCB_Reserved0 = 0; pSCB->SCB_Reserved1 = 0; pSCB->SCB_SGLen = 0; @@ -501,7 +501,7 @@ printk("max cdb length= %x\b", SCpnt->cmd_len); pSCB->SCB_CDBLen = IMAX_CDB; } - pSCB->SCB_Ident = SCpnt->lun | DISC_ALLOW; + pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW; if (SCpnt->device->tagged_supported) { /* Tag Support */ pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG; /* Do simple tag only */ } else { @@ -523,7 +523,7 @@ register ORC_SCB *pSCB; ORC_HCS *pHCB; /* Point to Host adapter control block */ - pHCB = (ORC_HCS *) SCpnt->host->hostdata; + pHCB = (ORC_HCS *) SCpnt->device->host->hostdata; SCpnt->scsi_done = done; /* Get free SCSI control block */ if ((pSCB = orc_alloc_scb(pHCB)) == NULL) { @@ -549,7 +549,7 @@ { ORC_HCS *hcsp; - hcsp = (ORC_HCS *) SCpnt->host->hostdata; + hcsp = (ORC_HCS *) SCpnt->device->host->hostdata; return orc_abort_srb(hcsp, SCpnt); } @@ -564,7 +564,7 @@ static int inia100_bus_reset(Scsi_Cmnd * SCpnt) { /* I need Host Control Block Information */ ORC_HCS *pHCB; - pHCB = (ORC_HCS *) SCpnt->host->hostdata; + pHCB = (ORC_HCS *) SCpnt->device->host->hostdata; return orc_reset_scsi_bus(pHCB); } @@ -578,8 +578,8 @@ static int inia100_device_reset(Scsi_Cmnd * SCpnt) { /* I need Host Control Block Information */ ORC_HCS *pHCB; - pHCB = (ORC_HCS *) SCpnt->host->hostdata; - return orc_device_reset(pHCB, SCpnt, SCpnt->target); + pHCB = (ORC_HCS *) SCpnt->device->host->hostdata; + return orc_device_reset(pHCB, SCpnt, SCpnt->device->id); } diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c --- a/drivers/scsi/ips.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/ips.c Sun Feb 9 21:13:28 2003 @@ -6,7 +6,7 @@ /* David Jeffery, Adaptec, Inc. */ /* */ /* Copyright (C) 2000 IBM Corporation */ -/* Copyright (C) 2002 Adaptec, Inc. */ +/* Copyright (C) 2002,2003 Adaptec, Inc. */ /* */ /* 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 */ @@ -127,6 +127,9 @@ /* - Get rid on IOCTL_NEW_COMMAND code */ /* - Add Extended DCDB Commands for Tape Support in 5I */ /* 5.10.12 - use pci_dma interfaces, update for 2.5 kernel changes */ +/* 5.10.15 - remove unused code (sem, macros, etc.) */ +/* 5.30.00 - use __devexit_p() */ +/* 6.00.00 - Add 6x Adapters and Battery Flash */ /*****************************************************************************/ /* @@ -191,14 +194,16 @@ /* * DRIVER_VER */ -#define IPS_VERSION_HIGH "5.10" -#define IPS_VERSION_LOW ".13-BETA " +#define IPS_VERSION_HIGH "5.99" +#define IPS_VERSION_LOW ".00-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) + #include "sd.h" #define IPS_SG_ADDRESS(sg) ((sg)->address) #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags) #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags) @@ -241,34 +246,23 @@ static int ips_force_memio = 1; /* Always use Memory Mapped I/O */ static int ips_force_i2o = 1; /* Always use I2O command delivery */ static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */ -static int ips_cd_boot = 0; /* Booting from ServeRAID Manager CD */ +static int ips_cd_boot = 0; /* Booting from Manager CD */ static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */ -static long ips_FlashDataInUse = 0; /* CD Boot - Flash Data In Use Flag */ +static long ips_FlashDataInUse = 0; /* CD Boot - Flash Data In Use Flag */ static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */ +static Scsi_Host_Template ips_driver_template = IPS; IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */ - /* This table describes any / all ServeRAID Adapters */ + /* This table describes all ServeRAID Adapters */ static struct pci_device_id ips_pci_table[] __devinitdata = { { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, + { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, { 0, } }; - /* This table describes only Sarasota ( ServeRAID 5i ) Adapters */ - static struct pci_device_id ips_pci_table_5i[] __devinitdata = { - { 0x1014, 0x01BD, PCI_ANY_ID, 0x259, 0, 0 }, - { 0x1014, 0x01BD, PCI_ANY_ID, 0x258, 0, 0 }, - { 0, } - }; - - /* This table describes all i960 Adapters */ - static struct pci_device_id ips_pci_table_i960[] __devinitdata = { - { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, - { 0, } - }; - MODULE_DEVICE_TABLE( pci, ips_pci_table ); static char ips_hot_plug_name[] = "ips"; @@ -283,27 +277,13 @@ .remove = __devexit_p(ips_remove_device), }; - struct pci_driver ips_pci_driver_5i = { - .name = ips_hot_plug_name, - .id_table = ips_pci_table_5i, - .probe = ips_insert_device, - .remove = __devexit_p(ips_remove_device), - }; - - struct pci_driver ips_pci_driver_i960 = { - .name = ips_hot_plug_name, - .id_table = ips_pci_table_i960, - .probe = ips_insert_device, - .remove = __devexit_p(ips_remove_device), - }; - /* * Necessary forward function protoypes */ static int ips_halt(struct notifier_block *nb, ulong event, void *buf); -#define MAX_ADAPTER_NAME 11 +#define MAX_ADAPTER_NAME 15 static char ips_adapter_name[][30] = { "ServeRAID", @@ -318,9 +298,12 @@ "ServeRAID 4Mx", "ServeRAID 4Lx", "ServeRAID 5i", - "ServeRAID 5i" + "ServeRAID 5i", + "ServeRAID 00", + "ServeRAID 00" }; + static struct notifier_block ips_notifier = { ips_halt, NULL, 0 }; @@ -390,9 +373,6 @@ int ips_eh_abort(Scsi_Cmnd *); int ips_eh_reset(Scsi_Cmnd *); int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *)); -int ips_biosparam(struct scsi_device *, struct block_device *, - sector_t, int *); -int ips_slave_configure(Scsi_Device *); const char * ips_info(struct Scsi_Host *); void do_ipsintr(int, void *, struct pt_regs *); static int ips_hainit(ips_ha_t *); @@ -441,7 +421,6 @@ static void ips_free_flash_copperhead(ips_ha_t *ha); static void ips_get_bios_version(ips_ha_t *, int); static void ips_identify_controller(ips_ha_t *); -//static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *); static void ips_chkstatus(ips_ha_t *, IPS_STATUS *); static void ips_enable_int_copperhead(ips_ha_t *); static void ips_enable_int_copperhead_memio(ips_ha_t *); @@ -482,6 +461,8 @@ static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int); static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *); static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *); +static void ips_scmd_buf_write(Scsi_Cmnd *scmd, void *data, unsigned int count); +static void ips_scmd_buf_read(Scsi_Cmnd *scmd, void *data, unsigned int count); int ips_proc_info(char *, char **, off_t, int, int, int); static int ips_host_info(ips_ha_t *, char *, off_t, int); @@ -489,11 +470,11 @@ static int copy_info(IPS_INFOSTR *, char *, ...); static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr ); static void ips_version_check(ips_ha_t *ha, int intr); -static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index); +static int ips_abort_init(ips_ha_t *ha, int index); static int ips_init_phase2( int index ); static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ); - +static int ips_register_scsi(int index); /*--------------------------------------------------------------------------*/ /* Exported Functions */ /*--------------------------------------------------------------------------*/ @@ -562,6 +543,7 @@ /****************************************************************************/ int ips_detect(Scsi_Host_Template *SHT) { + int i; METHOD_TRACE("ips_detect", 1); @@ -570,36 +552,26 @@ ips_setup(ips); #endif - /* If Booting from the ServeRAID Manager CD, Allocate a large Flash */ - /* Buffer ( so we won't need to allocate one for each adapter ). */ + /* If Booting from the Manager CD, Allocate a large Flash */ + /* Buffer ( so we won't need to allocate one for each adapter ). */ if ( ips_cd_boot ) { - ips_FlashData = ( char * ) __get_free_pages( GFP_KERNEL, 7 ); + ips_FlashData = ( char * ) __get_free_pages( IPS_INIT_GFP, 7 ); if (ips_FlashData == NULL) { /* The validity of this pointer is checked in ips_make_passthru() before it is used */ printk( KERN_WARNING "ERROR: Can't Allocate Large Buffer for Flashing\n" ); } } + if (!pci_present()) + return (0); SHT->proc_info = ips_proc_info; SHT->proc_name = "ips"; - #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) - spin_unlock_irq(&io_request_lock); - #endif - /* By definition, a Sarasota ( 5i ) Adapter MUST be enumerated first or the */ - /* server may not boot properly. The adapters must be enumerated in exactly */ - /* the same order as ServeRAID BIOS for the machine to come up properly. */ - - pci_module_init(&ips_pci_driver_5i); /* Ask for 5i Adapters First */ - if (ips_num_controllers) /* If there is a 5i Adapter */ - pci_module_init(&ips_pci_driver_i960); /* Get all i960's next */ - pci_module_init(&ips_pci_driver); /* Get all remaining Adapters */ - /* ( in normal BUS order ) */ - #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) - spin_lock_irq(&io_request_lock); - #endif - if (ips_num_controllers > 0) - register_reboot_notifier(&ips_notifier); + for(i = 0; i < ips_num_controllers; i++){ + if ( ips_register_scsi(i) ) + ips_free(ips_ha[i]); + ips_released_controllers++; + } return (ips_num_controllers); } @@ -614,7 +586,7 @@ /* * Setup Functions */ - if (IPS_IS_MORPHEUS(ha)) { + if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) { /* morpheus / marco / sebring */ ha->func.isintr = ips_isintr_morpheus; ha->func.isinit = ips_isinit_morpheus; @@ -734,10 +706,6 @@ ips_released_controllers++; - if (ips_num_controllers == ips_released_controllers){ - unregister_reboot_notifier(&ips_notifier); - pci_unregister_driver(&ips_pci_driver); - } return (FALSE); } @@ -817,7 +785,7 @@ if (!SC) return (FAILED); - ha = (ips_ha_t *) SC->host->hostdata; + ha = (ips_ha_t *) SC->device->host->hostdata; if (!ha) return (FAILED); @@ -884,7 +852,7 @@ return (FAILED); } - ha = (ips_ha_t *) SC->host->hostdata; + ha = (ips_ha_t *) SC->device->host->hostdata; if (!ha) { DEBUG(1, "Reset called with NULL ha struct"); @@ -1072,7 +1040,7 @@ METHOD_TRACE("ips_queue", 1); - ha = (ips_ha_t *) SC->host->hostdata; + ha = (ips_ha_t *) SC->device->host->hostdata; if (!ha) return (1); @@ -1100,12 +1068,12 @@ ips_name, ha->host_num, SC->cmnd[0], - SC->channel, - SC->target, - SC->lun); + SC->device->channel, + SC->device->id, + SC->device->lun); /* Check for command to initiator IDs */ - if ((SC->channel > 0) && (SC->target == ha->ha_id[SC->channel])) { + if ((SC->device->channel > 0) && (SC->device->id == ha->ha_id[SC->device->channel])) { SC->result = DID_NO_CONNECT << 16; done(SC); @@ -1155,13 +1123,6 @@ ips_next(ha, IPS_INTR_IORL); - /* If We were using the CD Boot Flash Buffer, Restore the Old Values */ - if ( ips_FlashData == ha->ioctl_data ) { - ha->ioctl_data = ha->flash_data; - ha->ioctl_order = ha->flash_order; - ha->ioctl_datasize = ha->flash_datasize; - ips_FlashDataInUse = 0; - } return (0); } @@ -1174,7 +1135,7 @@ /* Set bios geometry for the controller */ /* */ /****************************************************************************/ -int +static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]) { ips_ha_t *ha; @@ -1308,6 +1269,12 @@ if (!ha) return; host = ips_sh[ha->host_num]; + /* interrupt during initialization */ + if(!host){ + (*ha->func.intr)(ha); + return; + } + IPS_LOCK_SAVE(host->host_lock, cpu_flags); if (!ha->active) { @@ -1478,7 +1445,8 @@ bp = &buffer[0]; memset(bp, 0, sizeof(buffer)); - sprintf(bp, "%s%s%s", "IBM PCI ServeRAID ", IPS_VERSION_HIGH, IPS_VERSION_LOW ); + sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ", + IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT ); if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) { @@ -1556,9 +1524,9 @@ return (0); if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) && - (SC->channel == 0) && - (SC->target == IPS_ADAPTER_ID) && - (SC->lun == 0) && + (SC->device->channel == 0) && + (SC->device->id == IPS_ADAPTER_ID) && + (SC->device->lun == 0) && SC->request_buffer){ if((!SC->use_sg) && SC->request_bufflen && (((char *) SC->request_buffer)[0] == 'C') && @@ -1579,6 +1547,39 @@ /****************************************************************************/ /* */ +/* Routine Name: ips_alloc_passthru_buffer */ +/* */ +/* Routine Description: */ +/* allocate a buffer large enough for the ioctl data if the ioctl buffer */ +/* is too small or doesn't exist */ +/****************************************************************************/ +static int +ips_alloc_passthru_buffer(ips_ha_t *ha, int length){ + void *bigger_buf; + int count; + int order; + + if(ha->ioctl_data && length <= (PAGE_SIZE << ha->ioctl_order)) + return 0; + /* there is no buffer or it's not big enough, allocate a new one */ + for (count = PAGE_SIZE, order = 0; + count < length; + order++, count <<= 1); + bigger_buf = (void *) __get_free_pages(IPS_ATOMIC_GFP, order); + if (bigger_buf) { + /* free the old memory */ + free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order); + /* use the new memory */ + ha->ioctl_data = (char *) bigger_buf; + ha->ioctl_order = order; + } else { + return -1; + } + return 0; +} + +/****************************************************************************/ +/* */ /* Routine Name: ips_make_passthru */ /* */ /* Routine Description: */ @@ -1589,73 +1590,42 @@ static int ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) { ips_passthru_t *pt; - char *buffer; int length = 0; + int ret; METHOD_TRACE("ips_make_passthru", 1); if(!SC->use_sg){ - buffer = SC->request_buffer; length = SC->request_bufflen; }else{ struct scatterlist *sg = SC->request_buffer; int i; for(i = 0; i < SC->use_sg; i++) length += sg[i].length; - - if (length < sizeof(ips_passthru_t)) { - /* wrong size */ - DEBUG_VAR(1, "(%s%d) Passthru structure wrong size", - ips_name, ha->host_num); - return (IPS_FAILURE); - }else if(!ha->ioctl_data || length > (PAGE_SIZE << ha->ioctl_order)){ - void *bigger_buf; - int count; - int order; - /* try to allocate a bigger buffer */ - for (count = PAGE_SIZE, order = 0; - count < length; - order++, count <<= 1); - bigger_buf = (void *) __get_free_pages(GFP_ATOMIC, order); - if (bigger_buf) { - /* free the old memory */ - free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order); - /* use the new memory */ - ha->ioctl_data = (char *) bigger_buf; - ha->ioctl_order = order; - ha->ioctl_datasize = count; - } else { - pt = (ips_passthru_t*)IPS_SG_ADDRESS(sg); - pt->BasicStatus = 0x0B; - pt->ExtendedStatus = 0x00; - SC->result = DID_ERROR << 16; - return (IPS_FAILURE); - } - } - ha->ioctl_datasize = length; - length = 0; - for(i = 0; i < SC->use_sg; i++){ - memcpy(&ha->ioctl_data[length], IPS_SG_ADDRESS(&sg[i]), sg[i].length); - length += sg[i].length; - } - pt = (ips_passthru_t *)ha->ioctl_data; - buffer = ha->ioctl_data; - } - if (!length || !buffer) { - /* no data */ - DEBUG_VAR(1, "(%s%d) No passthru structure", - ips_name, ha->host_num); - - return (IPS_FAILURE); } if (length < sizeof(ips_passthru_t)) { /* wrong size */ DEBUG_VAR(1, "(%s%d) Passthru structure wrong size", - ips_name, ha->host_num); - + ips_name, ha->host_num); return (IPS_FAILURE); } - pt = (ips_passthru_t*) buffer; + if(ips_alloc_passthru_buffer(ha, length)){ + /* allocation failure! If ha->ioctl_data exists, use it to return + some error codes. Return a failed command to the scsi layer. */ + if(ha->ioctl_data){ + pt = (ips_passthru_t *)ha->ioctl_data; + ips_scmd_buf_read(SC, pt, sizeof(ips_passthru_t)); + pt->BasicStatus = 0x0B; + pt->ExtendedStatus = 0x00; + ips_scmd_buf_write(SC, pt, sizeof(ips_passthru_t)); + } + return IPS_FAILURE; + } + ha->ioctl_datasize = length; + + ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize); + pt = (ips_passthru_t *)ha->ioctl_data; + /* * Some notes about the passthru interface used * @@ -1664,26 +1634,14 @@ * packet we received from the sg driver. In this * case the CmdBSize field of the pt structure is * used for the size of the buffer. - * - * IF the scsi op_code == 0x81 then we assume that - * we will need our own buffer and we will copy the - * data to/from the user buffer passed in the scsi - * command. The data address resides at offset 4 - * in the scsi command. The length of the data resides - * at offset 8 in the scsi command. */ switch (pt->CoppCmd) { case IPS_NUMCTRLS: - memcpy(buffer + sizeof(ips_passthru_t), + memcpy(ha->ioctl_data + sizeof(ips_passthru_t), &ips_num_controllers, sizeof(int)); - SC->result = DID_OK << 16; - - return (IPS_SUCCESS_IMM); - - case IPS_CTRLINFO: - memcpy(buffer + sizeof(ips_passthru_t), - ha, sizeof(ips_ha_t)); + ips_scmd_buf_write(SC, ha->ioctl_data, + sizeof(ips_passthru_t) + sizeof(int)); SC->result = DID_OK << 16; return (IPS_SUCCESS_IMM); @@ -1700,9 +1658,11 @@ } if(ha->device_id == IPS_DEVICEID_COPPERHEAD && - pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW) - return ips_flash_copperhead(ha, pt, scb); - + pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW) { + ret = ips_flash_copperhead(ha, pt, scb); + ips_scmd_buf_write(SC, ha->ioctl_data, sizeof(ips_passthru_t)); + return ret; + } if (ips_usrcmd(ha, pt, scb)) return (IPS_SUCCESS); else @@ -1713,8 +1673,8 @@ } /* end switch */ - return (IPS_FAILURE); - } + return (IPS_FAILURE); +} /****************************************************************************/ /* Routine Name: ips_flash_copperhead */ @@ -1752,7 +1712,7 @@ pt->CoppCP.cmd.flashfw.count; for (count = PAGE_SIZE, ha->flash_order = 0; count < datasize; ha->flash_order++, count <<= 1); - ha->flash_data = (char *)__get_free_pages(GFP_ATOMIC, ha->flash_order); + ha->flash_data = (char *)__get_free_pages(IPS_ATOMIC_GFP, ha->flash_order); ha->flash_datasize = 0; }else return IPS_FAILURE; @@ -1829,13 +1789,55 @@ } /****************************************************************************/ +/* */ +/* Routine Name: ips_fill_scb_sg_single */ +/* */ +/* Routine Description: */ +/* Fill in a single scb sg_list element from an address */ +/* return a -1 if a breakup occured */ +/****************************************************************************/ +static inline int ips_fill_scb_sg_single(ips_ha_t *ha, dma_addr_t busaddr, + ips_scb_t *scb, int indx, unsigned int e_len) +{ + + int ret_val = 0; + + if ( (scb->data_len + e_len) > ha->max_xfer) { + e_len = ha->max_xfer - scb->data_len; + scb->breakup = indx; + ++scb->sg_break; + ret_val = -1; + } else { + scb->breakup = 0; + scb->sg_break = 0; + } + if (IPS_USE_ENH_SGLIST(ha)) { + scb->sg_list.enh_list[indx].address_lo = + cpu_to_le32(pci_dma_lo32(busaddr)); + scb->sg_list.enh_list[indx].address_hi = + cpu_to_le32(pci_dma_hi32(busaddr)); + scb->sg_list.enh_list[indx].length = + cpu_to_le32(e_len); + } else { + scb->sg_list.std_list[indx].address = + cpu_to_le32(pci_dma_lo32(busaddr)); + scb->sg_list.std_list[indx].length = + cpu_to_le32(e_len); + } + + ++scb->sg_len; + scb->data_len += e_len; + return ret_val; +} + +/****************************************************************************/ /* Routine Name: ips_flash_firmware */ /* Routine Description: */ /* flashes the firmware of a copperhead adapter */ /****************************************************************************/ static int ips_flash_firmware(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){ - IPS_SG_LIST *sg_list; + IPS_SG_LIST sg_list; uint32_t cmd_busaddr; if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE && @@ -1850,16 +1852,16 @@ return IPS_FAILURE; } /* Save the S/G list pointer so it doesn't get clobbered */ - sg_list = scb->sg_list; + sg_list.list = scb->sg_list.list; cmd_busaddr = scb->scb_busaddr; /* copy in the CP */ memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD)); /* FIX stuff that might be wrong */ - scb->sg_list = sg_list; + scb->sg_list.list = sg_list.list; scb->scb_busaddr = cmd_busaddr; - scb->bus = scb->scsi_cmd->channel; - scb->target_id = scb->scsi_cmd->target; - scb->lun = scb->scsi_cmd->lun; + scb->bus = scb->scsi_cmd->device->channel; + scb->target_id = scb->scsi_cmd->device->id; + scb->lun = scb->scsi_cmd->device->lun; scb->sg_len = 0; scb->data_len = 0; scb->flags = 0; @@ -1872,7 +1874,7 @@ IPS_DMA_DIR(scb)); scb->flags |= IPS_SCB_MAP_SINGLE; scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.flashfw.buffer_addr = scb->data_busaddr; + scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr); if (pt->TimeOut) scb->timeout = pt->TimeOut; scb->scsi_cmd->result = DID_OK <<16; @@ -1904,7 +1906,7 @@ /****************************************************************************/ static int ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) { - IPS_SG_LIST *sg_list; + IPS_SG_LIST sg_list; uint32_t cmd_busaddr; METHOD_TRACE("ips_usrcmd", 1); @@ -1913,18 +1915,18 @@ return (0); /* Save the S/G list pointer so it doesn't get clobbered */ - sg_list = scb->sg_list; + sg_list.list = scb->sg_list.list; cmd_busaddr = scb->scb_busaddr; /* copy in the CP */ memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD)); memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE)); /* FIX stuff that might be wrong */ - scb->sg_list = sg_list; + scb->sg_list.list = sg_list.list; scb->scb_busaddr = cmd_busaddr; - scb->bus = scb->scsi_cmd->channel; - scb->target_id = scb->scsi_cmd->target; - scb->lun = scb->scsi_cmd->lun; + scb->bus = scb->scsi_cmd->device->channel; + scb->target_id = scb->scsi_cmd->device->id; + scb->lun = scb->scsi_cmd->device->lun; scb->sg_len = 0; scb->data_len = 0; scb->flags = 0; @@ -1940,23 +1942,13 @@ return (0); if (pt->CmdBSize) { - if(!scb->scsi_cmd->use_sg){ - scb->data_len = pt->CmdBSize; - scb->data_busaddr = pci_map_single(ha->pcidev, - scb->scsi_cmd->request_buffer + - sizeof(ips_passthru_t), - pt->CmdBSize, - IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; - } else { - scb->data_len = pt->CmdBSize; - scb->data_busaddr = pci_map_single(ha->pcidev, - ha->ioctl_data + - sizeof(ips_passthru_t), - pt->CmdBSize, - IPS_DMA_DIR(scb)); - scb->flags |= IPS_SCB_MAP_SINGLE; - } + scb->data_len = pt->CmdBSize; + scb->data_busaddr = pci_map_single(ha->pcidev, + ha->ioctl_data + + sizeof(ips_passthru_t), + pt->CmdBSize, + IPS_DMA_DIR(scb)); + scb->flags |= IPS_SCB_MAP_SINGLE; } else { scb->data_busaddr = 0L; } @@ -2013,10 +2005,7 @@ return ; } - if(!scb->scsi_cmd->use_sg) - pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer; - else - pt = (ips_passthru_t *) ha->ioctl_data; + pt = (ips_passthru_t *) ha->ioctl_data; /* Copy data back to the user */ if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) /* Copy DCDB Back to Caller's Area */ @@ -2031,14 +2020,7 @@ scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW)) ips_free_flash_copperhead(ha); - if(scb->scsi_cmd->use_sg){ - int i, length = 0; - struct scatterlist *sg = scb->scsi_cmd->request_buffer; - for(i = 0; i < scb->scsi_cmd->use_sg; i++){ - memcpy(IPS_SG_ADDRESS(&sg[i]), &ha->ioctl_data[length], sg[i].length); - length += sg[i].length; - } - } + ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize); } /****************************************************************************/ @@ -2104,6 +2086,9 @@ copy_info(&info, "\tDriver Version : %s%s\n", IPS_VERSION_HIGH, IPS_VERSION_LOW); + copy_info(&info, "\tDriver Build : %d\n", + IPS_BUILD_IDENT); + copy_info(&info, "\tMax Physical Devices : %d\n", ha->enq->ucMaxPhysicalDevices); copy_info(&info, "\tMax Active Commands : %d\n", @@ -2245,6 +2230,17 @@ } break; + + case IPS_DEVICEID_MARCO: + switch (ha->subdevice_id) { + case IPS_SUBDEVICEID_6M: + ha->ad_type = IPS_ADTYPE_SERVERAID6M; + break; + case IPS_SUBDEVICEID_6I: + ha->ad_type = IPS_ADTYPE_SERVERAID6I; + break; + } + break; } } @@ -2355,7 +2351,7 @@ } else { /* Morpheus Family - Send Command to the card */ - buffer = kmalloc(0x1000, GFP_ATOMIC); + buffer = kmalloc(0x1000, IPS_ATOMIC_GFP); if (!buffer) return; @@ -2477,6 +2473,10 @@ return (0); } + /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */ + if ( (ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1) ) + ips_clear_adapter(ha, IPS_INTR_IORL); + /* set limits on SID, LUN, BUS */ ha->ntargets = IPS_MAX_TARGETS + 1; ha->nlun = 1; @@ -2666,7 +2666,7 @@ p = ha->scb_waitlist.head; while ((p) && (scb = ips_getscb(ha))) { - if ((p->channel > 0) && (ha->dcdb_active[p->channel-1] & (1 << p->target))) { + if ((p->device->channel > 0) && (ha->dcdb_active[p->device->channel-1] & (1 << p->device->id))) { ips_freescb(ha, scb); p = (Scsi_Cmnd *) p->host_scribble; continue; @@ -2683,9 +2683,9 @@ memset(SC->sense_buffer, 0, sizeof(SC->sense_buffer)); - scb->target_id = SC->target; - scb->lun = SC->lun; - scb->bus = SC->channel; + scb->target_id = SC->device->id; + scb->lun = SC->device->lun; + scb->bus = SC->device->channel; scb->scsi_cmd = SC; scb->breakup = 0; scb->data_len = 0; @@ -2705,68 +2705,20 @@ scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg, scsi_to_pci_dma_dir(SC->sc_data_direction)); scb->flags |= IPS_SCB_MAP_SG; - if (scb->sg_count == 1) { - if (sg_dma_len(sg) > ha->max_xfer) { - scb->breakup = 1; - scb->data_len = ha->max_xfer; - } else - scb->data_len = sg_dma_len(sg); - - scb->dcdb.transfer_length = scb->data_len; - scb->data_busaddr = sg_dma_address(sg); - scb->sg_len = 0; - } else { - /* Check for the first Element being bigger than MAX_XFER */ - if (sg_dma_len(&sg[0]) > ha->max_xfer) { - scb->sg_list[0].address = cpu_to_le32(sg_dma_address(&sg[0])); - scb->sg_list[0].length = ha->max_xfer; - scb->data_len = ha->max_xfer; - scb->breakup = 0; - scb->sg_break=1; - scb->sg_len = 1; - } else { - for (i = 0; i < scb->sg_count; i++) { - scb->sg_list[i].address = cpu_to_le32(sg_dma_address(&sg[i])); - scb->sg_list[i].length = cpu_to_le32(sg_dma_len(&sg[i])); - - if (scb->data_len + sg_dma_len(&sg[i]) > ha->max_xfer) { - /* - * Data Breakup required - */ - scb->breakup = i; - break; - } - - scb->data_len += sg_dma_len(&sg[i]); - } - - if (!scb->breakup) - scb->sg_len = scb->sg_count; - else - scb->sg_len = scb->breakup; - } - - scb->dcdb.transfer_length = scb->data_len; - scb->data_busaddr = scb->sg_busaddr; + for (i = 0; i < scb->sg_count; i++) { + if ( ips_fill_scb_sg_single(ha, sg_dma_address(&sg[i]), + scb, i, sg_dma_len(&sg[i])) < 0) + break; } + scb->dcdb.transfer_length = scb->data_len; } else { if (SC->request_bufflen) { - if (SC->request_bufflen > ha->max_xfer) { - /* - * Data breakup required - */ - scb->breakup = 1; - scb->data_len = ha->max_xfer; - } else { - scb->data_len = SC->request_bufflen; - } - - scb->dcdb.transfer_length = scb->data_len; scb->data_busaddr = pci_map_single(ha->pcidev, SC->request_buffer, - scb->data_len, + SC->request_bufflen, scsi_to_pci_dma_dir(SC->sc_data_direction)); scb->flags |= IPS_SCB_MAP_SINGLE; - scb->sg_len = 0; + ips_fill_scb_sg_single(ha, scb->data_busaddr, scb, 0, SC->request_bufflen); + scb->dcdb.transfer_length = scb->data_len; } else { scb->data_busaddr = 0L; scb->sg_len = 0; @@ -3319,118 +3271,41 @@ */ if ((scb->breakup) || (scb->sg_break)) { /* we had a data breakup */ - uint8_t bk_save; - - bk_save = scb->breakup; - scb->breakup = 0; - mod_timer(&scb->scsi_cmd->eh_timeout, jiffies + 120 * HZ); + scb->data_len = 0; if (scb->sg_count) { /* S/G request */ struct scatterlist *sg; - int i; + int ips_sg_index = 0; + int sg_dma_index; sg = scb->scsi_cmd->request_buffer; - if (scb->sg_count == 1) { - if (sg_dma_len(sg) - (bk_save * ha->max_xfer) > ha->max_xfer) { - /* Further breakup required */ - scb->data_len = ha->max_xfer; - scb->data_busaddr = sg_dma_address(sg) + (bk_save * ha->max_xfer); - scb->breakup = bk_save + 1; - } else { - scb->data_len = sg_dma_len(sg) - (bk_save * ha->max_xfer); - scb->data_busaddr = sg_dma_address(sg) + (bk_save * ha->max_xfer); - } + /* Spin forward to last dma chunk */ + sg_dma_index = scb->breakup; - scb->dcdb.transfer_length = scb->data_len; - scb->sg_len = 0; - } else { - /* We're here because there was MORE than one s/g unit. */ - /* bk_save points to which sg unit to look at */ - /* sg_break points to how far through this unit we are */ - /* NOTE: We will not move from one sg to another here, */ - /* just finish the one we are in. Not the most */ - /* efficient, but it keeps it from getting too hacky */ - - /* IF sg_break is non-zero, then just work on this current sg piece, */ - /* pointed to by bk_save */ - if (scb->sg_break) { - scb->sg_len = 1; - scb->sg_list[0].address = sg_dma_address(&sg[bk_save]) - + ha->max_xfer*scb->sg_break; - if (ha->max_xfer > sg_dma_len(&sg[bk_save]) - ha->max_xfer * scb->sg_break) - scb->sg_list[0].length = sg_dma_len(&sg[bk_save]) - ha->max_xfer * scb->sg_break; - else - scb->sg_list[0].length = ha->max_xfer; - scb->sg_break++; /* MUST GO HERE for math below to work */ - scb->data_len = scb->sg_list[0].length;; - - if (sg_dma_len(&sg[bk_save]) <= ha->max_xfer * scb->sg_break ) { - scb->sg_break = 0; /* No more work in this unit */ - if (( bk_save + 1 ) >= scb->sg_count) - scb->breakup = 0; - else - scb->breakup = bk_save + 1; - } - } else { - /* ( sg_break == 0 ), so this is our first look at a new sg piece */ - if (sg_dma_len(&sg[bk_save]) > ha->max_xfer) { - scb->sg_list[0].address = sg_dma_address(&sg[bk_save]); - scb->sg_list[0].length = ha->max_xfer; - scb->breakup = bk_save; - scb->sg_break = 1; - scb->data_len = ha->max_xfer; - scb->sg_len = 1; - } else { - /* OK, the next sg is a short one, so loop until full */ - scb->data_len = 0; - scb->sg_len = 0; - scb->sg_break = 0; - /* We're only doing full units here */ - for (i = bk_save; i < scb->sg_count; i++) { - scb->sg_list[i - bk_save].address = sg_dma_address(&sg[i]); - scb->sg_list[i - bk_save].length = cpu_to_le32(sg_dma_len(&sg[i])); - if (scb->data_len + sg_dma_len(&sg[i]) > ha->max_xfer) { - scb->breakup = i; /* sneaky, if not more work, than breakup is 0 */ - break; - } - scb->data_len += sg_dma_len(&sg[i]); - scb->sg_len++; /* only if we didn't get too big */ - } - } - } - - /* Also, we need to be sure we don't queue work ( breakup != 0 ) - if no more sg units for next time */ - scb->dcdb.transfer_length = scb->data_len; - scb->data_busaddr = scb->sg_busaddr; - } - - } else { - /* Non S/G Request */ - pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len, - IPS_DMA_DIR(scb)); - if ((scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer)) > ha->max_xfer) { - /* Further breakup required */ - scb->data_len = ha->max_xfer; - scb->data_busaddr = pci_map_single(ha->pcidev, - scb->scsi_cmd->request_buffer + - (bk_save * ha->max_xfer), - scb->data_len, IPS_DMA_DIR(scb)); - scb->breakup = bk_save + 1; - } else { - scb->data_len = scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer); - scb->data_busaddr = pci_map_single(ha->pcidev, - scb->scsi_cmd->request_buffer + - (bk_save * ha->max_xfer), - scb->data_len, IPS_DMA_DIR(scb)); - } + /* Take care of possible partial on last chunk*/ + ips_fill_scb_sg_single(ha, sg_dma_address(&sg[sg_dma_index]), + scb, ips_sg_index++, + sg_dma_len(&sg[sg_dma_index])); + + for (; sg_dma_index < scb->sg_count; sg_dma_index++) { + if ( ips_fill_scb_sg_single(ha, sg_dma_address(&sg[sg_dma_index]), + scb, ips_sg_index++, + sg_dma_len(&sg[sg_dma_index])) < 0) + break; - scb->dcdb.transfer_length = scb->data_len; - scb->sg_len = 0; - } + } + } else { + /* Non S/G Request */ + (void) ips_fill_scb_sg_single(ha, + scb->data_busaddr + (scb->sg_break * ha->max_xfer), + scb, 0, + scb->scsi_cmd->request_bufflen - (scb->sg_break * ha->max_xfer)); + } + + scb->dcdb.transfer_length = scb->data_len; scb->dcdb.cmd_attribute |= ips_command_direction[scb->scsi_cmd->cmnd[0]]; if (!scb->dcdb.cmd_attribute & 0x3) @@ -3499,9 +3374,9 @@ DEBUG_VAR(2, "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x", ips_name, ha->host_num, - scb->scsi_cmd->channel, - scb->scsi_cmd->target, - scb->scsi_cmd->lun, + scb->scsi_cmd->device->channel, + scb->scsi_cmd->channel->id, + scb->scsi_cmd->channel->lun, scb->basic_status, scb->extended_status, scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0, @@ -3636,6 +3511,68 @@ /****************************************************************************/ /* */ +/* Routine Name: ips_scmd_buf_write */ +/* */ +/* Routine Description: */ +/* Write data to Scsi_Cmnd request_buffer at proper offsets */ +/****************************************************************************/ +static void ips_scmd_buf_write(Scsi_Cmnd *scmd, void *data, unsigned + int count) +{ + if (scmd->use_sg) { + int i; + unsigned int min_cnt, xfer_cnt; + char *cdata = (char *)data; + struct scatterlist *sg = scmd->request_buffer; + for (i = 0, xfer_cnt = 0; + (i < scmd->use_sg) && (xfer_cnt < count); i++){ + if(!IPS_SG_ADDRESS(&sg[i])) + return; + min_cnt = min( count - xfer_cnt, sg[i].length); + memcpy(IPS_SG_ADDRESS(&sg[i]), &cdata[xfer_cnt], + min_cnt); + xfer_cnt += min_cnt; + } + + } else { + unsigned int min_cnt = min(count, scmd->request_bufflen); + memcpy(scmd->request_buffer, data, min_cnt); + } +} + +/****************************************************************************/ +/* */ +/* Routine Name: ips_scmd_buf_read */ +/* */ +/* Routine Description: */ +/* Copy data from a Scsi_Cmnd to a new, linear buffer */ +/****************************************************************************/ +static void ips_scmd_buf_read(Scsi_Cmnd *scmd, void *data, unsigned + int count) +{ + if (scmd->use_sg) { + int i; + unsigned int min_cnt, xfer_cnt; + char *cdata = (char *)data; + struct scatterlist *sg = scmd->request_buffer; + for (i = 0, xfer_cnt = 0; + (i < scmd->use_sg) && (xfer_cnt < count); i++){ + if(!IPS_SG_ADDRESS(&sg[i])) + return; + min_cnt = min( count - xfer_cnt, sg[i].length); + memcpy(&cdata[xfer_cnt],IPS_SG_ADDRESS(&sg[i]), + min_cnt); + xfer_cnt += min_cnt; + } + + } else { + unsigned int min_cnt = min(count, scmd->request_bufflen); + memcpy(data, scmd->request_buffer, min_cnt); + } +} + +/****************************************************************************/ +/* */ /* Routine Name: ips_send_cmd */ /* */ /* Routine Description: */ @@ -3710,7 +3647,7 @@ strncpy(inquiry.ProductId, "SERVERAID ", 16); strncpy(inquiry.ProductRevisionLevel, "1.00", 4); - memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen); + ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof(inquiry)); scb->scsi_cmd->result = DID_OK << 16; } @@ -3740,15 +3677,19 @@ if (!scb->sg_len) { scb->cmd.basic_io.op_code = (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE; + scb->cmd.basic_io.enhanced_sg = 0; + scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); } else { scb->cmd.basic_io.op_code = (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG; + scb->cmd.basic_io.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0; + scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->sg_busaddr); } + scb->cmd.basic_io.segment_4G = 0; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.basic_io.log_drv = scb->target_id; scb->cmd.basic_io.sg_count = scb->sg_len; - scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); if (scb->cmd.basic_io.lba) scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) + @@ -3763,7 +3704,6 @@ if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0) scb->cmd.basic_io.sector_count = cpu_to_le16(256); - scb->cmd.basic_io.reserved = 0; ret = IPS_SUCCESS; break; @@ -3772,15 +3712,19 @@ if (!scb->sg_len) { scb->cmd.basic_io.op_code = (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE; + scb->cmd.basic_io.enhanced_sg = 0; + scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); } else { scb->cmd.basic_io.op_code = (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG; + scb->cmd.basic_io.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0; + scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->sg_busaddr); } + scb->cmd.basic_io.segment_4G = 0; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.basic_io.log_drv = scb->target_id; scb->cmd.basic_io.sg_count = scb->sg_len; - scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr); if (scb->cmd.basic_io.lba) scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) + @@ -3793,7 +3737,6 @@ scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE); - scb->cmd.basic_io.reserved = 0; if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) { /* @@ -3815,6 +3758,8 @@ case MODE_SENSE: scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY; scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb); + scb->cmd.basic_io.segment_4G = 0; + scb->cmd.basic_io.enhanced_sg = 0; scb->data_len = sizeof(*ha->enq); scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, scb->data_len, IPS_DMA_DIR(scb)); @@ -3873,10 +3818,6 @@ /* setup DCDB */ if (scb->bus > 0) { - if (!scb->sg_len) - scb->cmd.dcdb.op_code = IPS_CMD_DCDB; - else - scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG; /* If we already know the Device is Not there, no need to attempt a Command */ /* This also protects an NT FailOver Controller from getting CDB's sent to it */ @@ -3892,15 +3833,19 @@ (unsigned long)scb); scb->cmd.dcdb.reserved = 0; scb->cmd.dcdb.reserved2 = 0; - scb->cmd.dcdb.reserved3 = 0; + scb->cmd.dcdb.reserved3 = 0; + scb->cmd.dcdb.segment_4G = 0; + scb->cmd.dcdb.enhanced_sg = 0; TimeOut = scb->scsi_cmd->timeout_per_command; if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */ - if (!scb->sg_len) + if (!scb->sg_len) { scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB; - else + } else { scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB_SG; + scb->cmd.dcdb.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0; + } tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb; /* Use Same Data Area as Old DCDB Struct */ tapeDCDB->device_address = ((scb->bus - 1) << 4) | scb->target_id; @@ -3919,13 +3864,23 @@ tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len; tapeDCDB->reserved_for_LUN = 0; tapeDCDB->transfer_length = scb->data_len; - tapeDCDB->buffer_pointer = cpu_to_le32(scb->data_busaddr); + if(scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG) + tapeDCDB->buffer_pointer = cpu_to_le32(scb->sg_busaddr); + else + tapeDCDB->buffer_pointer = cpu_to_le32(scb->data_busaddr); tapeDCDB->sg_count = scb->sg_len; tapeDCDB->sense_length = sizeof(tapeDCDB->sense_info); tapeDCDB->scsi_status = 0; tapeDCDB->reserved = 0; memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len); } else { + if (!scb->sg_len) { + scb->cmd.dcdb.op_code = IPS_CMD_DCDB; + } else { + scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG; + scb->cmd.dcdb.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0; + } + scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id; scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED; @@ -3941,7 +3896,10 @@ scb->dcdb.transfer_length = scb->data_len; if ( scb->dcdb.cmd_attribute & IPS_TRANSFER64K ) scb->dcdb.transfer_length = 0; - scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr); + if(scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG) + scb->dcdb.buffer_pointer = cpu_to_le32(scb->sg_busaddr); + else + scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr); scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len; scb->dcdb.sense_length = sizeof(scb->dcdb.sense_info); scb->dcdb.sg_count = scb->sg_len; @@ -4166,7 +4124,7 @@ strncpy(inquiry.ProductId, "SERVERAID ", 16); strncpy(inquiry.ProductRevisionLevel, "1.00", 4); - memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen); + ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof(inquiry)); return (1); } @@ -4182,17 +4140,17 @@ /****************************************************************************/ static int ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) { - IPS_SCSI_CAPACITY *cap; + IPS_SCSI_CAPACITY cap; METHOD_TRACE("ips_rdcap", 1); if (scb->scsi_cmd->bufflen < 8) return (0); - cap = (IPS_SCSI_CAPACITY *) scb->scsi_cmd->request_buffer; + cap.lba = cpu_to_be32(le32_to_cpu(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count) - 1); + cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE); - cap->lba = cpu_to_be32(le32_to_cpu(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count) - 1); - cap->len = cpu_to_be32((uint32_t) IPS_BLKSIZE); + ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof(cap)); return (1); } @@ -4270,7 +4228,7 @@ return (0); } /* end switch */ - memcpy(scb->scsi_cmd->request_buffer, &mdata, scb->scsi_cmd->request_bufflen); + ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof(mdata)); return (1); } @@ -4297,7 +4255,7 @@ reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE; reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE; - memcpy(scb->scsi_cmd->request_buffer, &reqsen, scb->scsi_cmd->request_bufflen); + ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof(reqsen)); return (1); } @@ -4376,8 +4334,8 @@ static int ips_deallocatescbs(ips_ha_t *ha, int cmds) { if (ha->scbs) { - pci_free_consistent(ha->pcidev,sizeof(IPS_SG_LIST) * IPS_MAX_SG * - cmds, ha->scbs->sg_list, ha->scbs->sg_busaddr); + pci_free_consistent(ha->pcidev, IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * + cmds, ha->scbs->sg_list.list, ha->scbs->sg_busaddr); pci_free_consistent(ha->pcidev, sizeof(ips_scb_t) * cmds, ha->scbs, ha->scbs->scb_busaddr); ha->scbs = NULL; @@ -4397,7 +4355,7 @@ static int ips_allocatescbs(ips_ha_t *ha) { ips_scb_t *scb_p; - IPS_SG_LIST* ips_sg; + IPS_SG_LIST ips_sg; int i; dma_addr_t command_dma, sg_dma; @@ -4408,9 +4366,9 @@ &command_dma); if (ha->scbs == NULL) return 0; - ips_sg = pci_alloc_consistent(ha->pcidev, sizeof(IPS_SG_LIST) * IPS_MAX_SG * - ha->max_cmds, &sg_dma); - if(ips_sg == NULL){ + ips_sg.list = pci_alloc_consistent(ha->pcidev, IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * + ha->max_cmds, &sg_dma); + if(ips_sg.list == NULL){ pci_free_consistent(ha->pcidev,ha->max_cmds * sizeof(ips_scb_t),ha->scbs, command_dma); return 0; } @@ -4421,8 +4379,13 @@ scb_p = &ha->scbs[i]; scb_p->scb_busaddr = command_dma + sizeof(ips_scb_t) * i; /* set up S/G list */ - scb_p->sg_list = ips_sg + i * IPS_MAX_SG; - scb_p->sg_busaddr = sg_dma + sizeof(IPS_SG_LIST) * IPS_MAX_SG * i; + if (IPS_USE_ENH_SGLIST(ha)) { + scb_p->sg_list.enh_list = ips_sg.enh_list + i * IPS_MAX_SG; + scb_p->sg_busaddr = sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i; + } else { + scb_p->sg_list.std_list = ips_sg.std_list + i * IPS_MAX_SG; + scb_p->sg_busaddr = sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i; + } /* add to the free list */ if (i < ha->max_cmds - 1) { @@ -4446,14 +4409,14 @@ /****************************************************************************/ static void ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) { - IPS_SG_LIST *sg_list; + IPS_SG_LIST sg_list; uint32_t cmd_busaddr, sg_busaddr; METHOD_TRACE("ips_init_scb", 1); if (scb == NULL) return ; - sg_list = scb->sg_list; + sg_list.list = scb->sg_list.list; cmd_busaddr = scb->scb_busaddr; sg_busaddr = scb->sg_busaddr; /* zero fill */ @@ -4469,7 +4432,7 @@ /* set bus address of scb */ scb->scb_busaddr = cmd_busaddr; scb->sg_busaddr = sg_busaddr; - scb->sg_list = sg_list; + scb->sg_list.list = sg_list.list; /* Neptune Fix */ scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE); @@ -4523,8 +4486,7 @@ METHOD_TRACE("ips_freescb", 1); if(scb->flags & IPS_SCB_MAP_SG) - pci_unmap_sg(ha->pcidev, scb->scsi_cmd->request_buffer, - scb->scsi_cmd->use_sg, + pci_unmap_sg(ha->pcidev,scb->scsi_cmd->request_buffer, scb->scsi_cmd->use_sg, IPS_DMA_DIR(scb)); else if(scb->flags & IPS_SCB_MAP_SINGLE) pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len, @@ -4953,6 +4915,13 @@ writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR); /* if we get here then everything went OK */ + + /* Since we did a RESET, an EraseStripeLock may be needed */ + if (Post == 0xEF10) { + if ( (Config == 0x000F) || (Config == 0x0009) ) + ha->requires_esl = 1; + } + return (1); } @@ -5633,7 +5602,6 @@ scb->cmd.basic_io.lba = 0; scb->cmd.basic_io.sector_count = 0; scb->cmd.basic_io.log_drv = 0; - scb->cmd.basic_io.reserved = 0; scb->data_len = sizeof(*ha->enq); scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, scb->data_len, IPS_DMA_DIR(scb)); @@ -5678,7 +5646,6 @@ scb->cmd.basic_io.lba = 0; scb->cmd.basic_io.sector_count = 0; scb->cmd.basic_io.log_drv = 0; - scb->cmd.basic_io.reserved = 0; scb->data_len = sizeof(*ha->subsys); scb->data_busaddr = pci_map_single(ha->pcidev, ha->subsys, scb->data_len, IPS_DMA_DIR(scb)); @@ -6504,6 +6471,8 @@ uint8_t BiosVersion[ IPS_COMPAT_ID_LENGTH + 1]; int MatchError; int rc; + char BiosString[10]; + char FirmwareString[10]; METHOD_TRACE("ips_version_check", 1); @@ -6536,28 +6505,30 @@ MatchError = 0; if (strncmp(FirmwareVersion, Compatable[ ha->nvram->adapter_type ], IPS_COMPAT_ID_LENGTH) != 0) - { - if (ips_cd_boot == 0) - printk(KERN_WARNING "Warning: Adapter %d Firmware Compatible Version is %s, but should be %s\n", - ha->host_num, FirmwareVersion, Compatable[ ha->nvram->adapter_type ]); MatchError = 1; - } if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0) - { - if (ips_cd_boot == 0) - printk(KERN_WARNING "Warning: Adapter %d BIOS Compatible Version is %s, but should be %s\n", - ha->host_num, BiosVersion, IPS_COMPAT_BIOS); MatchError = 1; - } ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */ if (MatchError) { ha->nvram->version_mismatch = 1; - if (ips_cd_boot == 0) - printk(KERN_WARNING "Warning ! ! ! ServeRAID Version Mismatch\n"); + if (ips_cd_boot == 0) + { + strncpy(&BiosString[0], ha->nvram->bios_high, 4); + strncpy(&BiosString[4], ha->nvram->bios_low, 4); + BiosString[8] = 0; + + strncpy(&FirmwareString[0], ha->enq->CodeBlkVersion, 8); + FirmwareString[8] = 0; + + printk(KERN_WARNING "Warning ! ! ! ServeRAID Version Mismatch\n"); + printk(KERN_WARNING "Bios = %s, Firmware = %s, Device Driver = %s%s\n", + BiosString, FirmwareString, IPS_VERSION_HIGH, IPS_VERSION_LOW ); + printk(KERN_WARNING "These levels should match to avoid possible compatibility problems.\n" ); + } } else { @@ -6605,20 +6576,185 @@ return( rc ); } - - -static Scsi_Host_Template driver_template = IPS; -#include "scsi_module.c" - -static int ips_abort_init(ips_ha_t *ha, struct Scsi_Host *sh, int index){ +/****************************************************************************/ +/* */ +/* Routine Name: ips_abort_init */ +/* */ +/* Routine Description: */ +/* cleanup routine for a failed adapter initialization */ +/****************************************************************************/ +static int ips_abort_init(ips_ha_t *ha, int index){ ha->active = 0; ips_free(ha); - scsi_unregister(sh); ips_ha[index] = 0; ips_sh[index] = 0; return -1; } +/****************************************************************************/ +/* */ +/* Routine Name: ips_shift_controllers */ +/* */ +/* Routine Description: */ +/* helper function for ordering adapters */ +/****************************************************************************/ +static void +ips_shift_controllers(int lowindex, int highindex){ + ips_ha_t *ha_sav = ips_ha[highindex]; + struct Scsi_Host *sh_sav = ips_sh[highindex]; + int i; + + for ( i = highindex; i > lowindex; i--){ + ips_ha[i] = ips_ha[i - 1]; + ips_sh[i] = ips_sh[i - 1]; + ips_ha[i]->host_num = i; + } + ha_sav->host_num = lowindex; + ips_ha[lowindex] = ha_sav; + ips_sh[lowindex] = sh_sav; +} + +/****************************************************************************/ +/* */ +/* Routine Name: ips_order_controllers */ +/* */ +/* Routine Description: */ +/* place controllers is the "proper" boot order */ +/****************************************************************************/ +static void +ips_order_controllers(void){ + int i, j, tmp, position = 0; + IPS_NVRAM_P5 *nvram; + if(!ips_ha[0]) + return; + nvram = ips_ha[0]->nvram; + + if(nvram->adapter_order[0]){ + for(i = 1; i <= nvram->adapter_order[0]; i++){ + for(j = position; j < ips_num_controllers; j++){ + switch(ips_ha[j]->ad_type){ + case IPS_ADTYPE_SERVERAID6M: + if(nvram->adapter_order[i] == 'M'){ + ips_shift_controllers(position, j); + position++; + } + break; + case IPS_ADTYPE_SERVERAID4L: + case IPS_ADTYPE_SERVERAID4M: + case IPS_ADTYPE_SERVERAID4MX: + case IPS_ADTYPE_SERVERAID4LX: + if(nvram->adapter_order[i] == 'N'){ + ips_shift_controllers(position, j); + position++; + } + break; + case IPS_ADTYPE_SERVERAID6I: + case IPS_ADTYPE_SERVERAID5I2: + case IPS_ADTYPE_SERVERAID5I1: + if(nvram->adapter_order[i] == 'S'){ + ips_shift_controllers(position, j); + position++; + } + break; + case IPS_ADTYPE_SERVERAID: + case IPS_ADTYPE_SERVERAID2: + case IPS_ADTYPE_NAVAJO: + case IPS_ADTYPE_KIOWA: + case IPS_ADTYPE_SERVERAID3L: + case IPS_ADTYPE_SERVERAID3: + case IPS_ADTYPE_SERVERAID4H: + if(nvram->adapter_order[i] == 'A'){ + ips_shift_controllers(position, j); + position++; + } + break; + default: + } + } + } + /* if adapter_order[0], then ordering is complete */ + return; + } + /* old bios, use older ordering */ + tmp = 0; + for(i = position; i < ips_num_controllers; i++){ + if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I2 || + ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I1){ + ips_shift_controllers(position, i); + position++; + tmp = 1; + } + } + /* if there were no 5I cards, then don't do any extra ordering */ + if (!tmp) + return; + for(i = position; i < ips_num_controllers; i++){ + if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4L || + ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4M || + ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4LX || + ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4MX){ + ips_shift_controllers(position, i); + position++; + } + } + + return; +} + + +/****************************************************************************/ +/* */ +/* Routine Name: ips_register_scsi */ +/* */ +/* Routine Description: */ +/* perform any registration and setup with the scsi layer */ +/****************************************************************************/ +static int +ips_register_scsi( int index){ + struct Scsi_Host *sh; + ips_ha_t *ha, *oldha; + sh = scsi_register(&ips_driver_template, sizeof(ips_ha_t)); + if(!sh) { + printk(KERN_WARNING "Unable to register controller with SCSI subsystem\n" ); + return -1; + } + oldha = ips_ha[index]; + ha = IPS_HA(sh); + memcpy(ha, oldha, sizeof(ips_ha_t)); + free_irq(oldha->irq, oldha); + /* Install the interrupt handler with the new ha */ + if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { + printk(KERN_WARNING "Unable to install interrupt handler\n" ); + scsi_unregister(sh); + return -1; + } + kfree(oldha); + ips_sh[index] = sh; + ips_ha[index] = ha; + scsi_set_pci_device(sh, ha->pcidev); + + /* Store away needed values for later use */ + sh->io_port = ha->io_addr; + sh->n_io_port = ha->io_addr ? 255 : 0; + sh->unique_id = (ha->io_addr) ? ha->io_addr : ha->mem_addr; + sh->irq = ha->irq; + sh->sg_tablesize = sh->hostt->sg_tablesize; + sh->can_queue = sh->hostt->can_queue; + sh->cmd_per_lun = sh->hostt->cmd_per_lun; + sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma; + sh->use_clustering = sh->hostt->use_clustering; + +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7) + sh->max_sectors = 128; +#endif + + sh->max_id = ha->ntargets; + sh->max_lun = ha->nlun; + sh->max_channel = ha->nbus - 1; + sh->can_queue = ha->max_cmds-1; + + return 0; +} /*---------------------------------------------------------------------------*/ /* Routine Name: ips_remove_device */ @@ -6644,6 +6780,43 @@ } } +/****************************************************************************/ +/* */ +/* Routine Name: ips_module_init */ +/* */ +/* Routine Description: */ +/* function called on module load */ +/****************************************************************************/ +static int __init +ips_module_init(void){ + if( pci_module_init(&ips_pci_driver) < 0 ) + return -ENODEV; + ips_driver_template.module = THIS_MODULE; + ips_order_controllers(); + if( scsi_register_host(&ips_driver_template) ){ + pci_unregister_driver(&ips_pci_driver); + return -ENODEV; + } + + return 0; +} + +/****************************************************************************/ +/* */ +/* Routine Name: ips_module_exit */ +/* */ +/* Routine Description: */ +/* function called on module unload */ +/****************************************************************************/ +static void __exit +ips_module_exit(void){ + scsi_unregister_host(&ips_driver_template); + pci_unregister_driver(&ips_pci_driver); + unregister_reboot_notifier(&ips_notifier); +} + +module_init(ips_module_init); +module_exit(ips_module_exit); /*---------------------------------------------------------------------------*/ /* Routine Name: ips_insert_device */ @@ -6686,7 +6859,6 @@ /*---------------------------------------------------------------------------*/ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr ) { - struct Scsi_Host *sh; ips_ha_t *ha; uint32_t io_addr; uint32_t mem_addr; @@ -6777,65 +6949,88 @@ subdevice_id = pci_dev->subsystem_device; /* found a controller */ - sh = scsi_register(&driver_template, sizeof(ips_ha_t)); -#if LINUX_VERSION_CODE > LinuxVersionCode(2,5,0) - pci_set_dma_mask(pci_dev, (u64)0xffffffff); - scsi_set_pci_device(sh, pci_dev); -#endif - if (sh == NULL) { - printk(KERN_WARNING "Unable to register controller with SCSI subsystem\n" ); + ha = kmalloc(sizeof(ips_ha_t), GFP_KERNEL); + if (ha == NULL) { + printk(KERN_WARNING "Unable to allocate temporary ha struct\n" ); return -1; } - ha = IPS_HA(sh); memset(ha, 0, sizeof(ips_ha_t)); - ips_sh[index] = sh; + ips_sh[index] = NULL; ips_ha[index] = ha; ha->active = 1; - ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL); + /* Store info in HA structure */ + ha->irq = irq; + ha->io_addr = io_addr; + ha->io_len = io_len; + ha->mem_addr = mem_addr; + ha->mem_len = mem_len; + ha->mem_ptr = mem_ptr; + ha->ioremap_ptr = ioremap_ptr; + ha->host_num = ( uint32_t) index; + ha->revision_id = revision_id; + ha->slot_num = PCI_SLOT(pci_dev->devfn); + ha->device_id = pci_dev->device; + ha->subdevice_id = subdevice_id; + ha->pcidev = pci_dev; + + /* + * Set the pci_dev's dma_mask. Not all adapters support 64bit + * addressing so don't enable it if the adapter can't support + * it! Also, don't use 64bit addressing if dma addresses + * are guaranteed to be < 4G. + */ + if ( IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) && + !pci_set_dma_mask(ha->pcidev, (u64)0xffffffffffffffff)) { + (ha)->flags |= IPS_HA_ENH_SG; + } else { + pci_set_dma_mask(ha->pcidev, (u64)0xffffffff); + } + + ha->enq = kmalloc(sizeof(IPS_ENQ), IPS_INIT_GFP); if (!ha->enq) { printk(KERN_WARNING "Unable to allocate host inquiry structure\n" ); - return ips_abort_init(ha, sh, index); + return ips_abort_init(ha, index); } ha->adapt = pci_alloc_consistent(pci_dev, sizeof(IPS_ADAPTER) + sizeof(IPS_IO_CMD), &dma_address); if (!ha->adapt) { printk(KERN_WARNING "Unable to allocate host adapt & dummy structures\n"); - return ips_abort_init(ha, sh, index); + return ips_abort_init(ha, index); } ha->adapt->hw_status_start = dma_address; ha->dummy = (void *)(ha->adapt + 1); - ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL); + ha->conf = kmalloc(sizeof(IPS_CONF), IPS_INIT_GFP); if (!ha->conf) { printk(KERN_WARNING "Unable to allocate host conf structure\n" ); - return ips_abort_init(ha, sh, index); + return ips_abort_init(ha, index); } - ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL); + ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), IPS_INIT_GFP); if (!ha->nvram) { printk(KERN_WARNING "Unable to allocate host NVRAM structure\n" ); - return ips_abort_init(ha, sh, index); + return ips_abort_init(ha, index); } - ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL); + ha->subsys = kmalloc(sizeof(IPS_SUBSYS), IPS_INIT_GFP); if (!ha->subsys) { printk(KERN_WARNING "Unable to allocate host subsystem structure\n" ); - return ips_abort_init(ha, sh, index); + return ips_abort_init(ha, index); } for (count = PAGE_SIZE, ha->ioctl_order = 0; count < ips_ioctlsize; ha->ioctl_order++, count <<= 1); - ha->ioctl_data = (char *) __get_free_pages(GFP_KERNEL, ha->ioctl_order); + ha->ioctl_data = (char *) __get_free_pages(IPS_INIT_GFP, ha->ioctl_order); ha->ioctl_datasize = count; if (!ha->ioctl_data) { @@ -6845,49 +7040,19 @@ ha->ioctl_datasize = 0; } - /* Store away needed values for later use */ - sh->io_port = io_addr; - sh->n_io_port = io_addr ? 255 : 0; - sh->unique_id = (io_addr) ? io_addr : mem_addr; - sh->irq = irq; - //sh->select_queue_depths = ips_select_queue_depth; - sh->sg_tablesize = sh->hostt->sg_tablesize; - sh->can_queue = sh->hostt->can_queue; - sh->cmd_per_lun = sh->hostt->cmd_per_lun; - sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma; - sh->use_clustering = sh->hostt->use_clustering; - -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7) - sh->max_sectors = 128; -#endif - - /* Store info in HA structure */ - ha->irq = irq; - ha->io_addr = io_addr; - ha->io_len = io_len; - ha->mem_addr = mem_addr; - ha->mem_len = mem_len; - ha->mem_ptr = mem_ptr; - ha->ioremap_ptr = ioremap_ptr; - ha->host_num = ( uint32_t) index; - ha->revision_id = revision_id; - ha->slot_num = PCI_SLOT(pci_dev->devfn); - ha->device_id = pci_dev->device; - ha->subdevice_id = subdevice_id; - ha->pcidev = pci_dev; - /* * Setup Functions */ ips_setup_funclist(ha); - if ( IPS_IS_MORPHEUS( ha ) ) { + if ( ( IPS_IS_MORPHEUS( ha ) ) || ( IPS_IS_MARCO( ha ) ) ) { /* If Morpheus appears dead, reset it */ IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 ); if ( IsDead == 0xDEADBEEF ) { ips_reset_morpheus( ha ); } } + /* * Initialize the card if it isn't already */ @@ -6898,31 +7063,14 @@ * Initialization failed */ printk(KERN_WARNING "Unable to initialize controller\n" ); - return ips_abort_init(ha, sh, index); + return ips_abort_init(ha, index); } } - /* Install the interrupt handler */ - if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { - printk(KERN_WARNING "Unable to install interrupt handler\n" ); - return ips_abort_init(ha, sh, index); - } - - /* - * Allocate a temporary SCB for initialization - */ - ha->max_cmds = 1; - if (!ips_allocatescbs(ha)) { - printk(KERN_WARNING "Unable to allocate a CCB\n" ); - free_irq(ha->irq, ha); - return ips_abort_init(ha, sh, index); - } - *indexPtr = index; return SUCCESS; } - /*---------------------------------------------------------------------------*/ /* Routine Name: ips_init_phase2 */ /* */ @@ -6934,24 +7082,36 @@ /*---------------------------------------------------------------------------*/ static int ips_init_phase2( int index ) { - struct Scsi_Host *sh; ips_ha_t *ha; ha = ips_ha[index]; - sh = ips_sh[index]; METHOD_TRACE("ips_init_phase2", 1); if (!ha->active) { - scsi_unregister(sh); ips_ha[index] = NULL; - ips_sh[index] = NULL; - return -1;; + return -1; + } + + /* Install the interrupt handler */ + if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) { + printk(KERN_WARNING "Unable to install interrupt handler\n" ); + return ips_abort_init(ha, index); + } + + /* + * Allocate a temporary SCB for initialization + */ + ha->max_cmds = 1; + if (!ips_allocatescbs(ha)) { + printk(KERN_WARNING "Unable to allocate a CCB\n" ); + free_irq(ha->irq, ha); + return ips_abort_init(ha, index); } if (!ips_hainit(ha)) { printk(KERN_WARNING "Unable to initialize controller\n" ); free_irq(ha->irq, ha); - return ips_abort_init(ha, sh, index); + return ips_abort_init(ha, index); } /* Free the temporary SCB */ ips_deallocatescbs(ha, 1); @@ -6960,20 +7120,16 @@ if (!ips_allocatescbs(ha)) { printk(KERN_WARNING "Unable to allocate CCBs\n" ); free_irq(ha->irq, ha); - return ips_abort_init(ha, sh, index); + return ips_abort_init(ha, index); } - /* finish setting values */ - sh->max_id = ha->ntargets; - sh->max_lun = ha->nlun; - sh->max_channel = ha->nbus - 1; - sh->can_queue = ha->max_cmds-1; - return SUCCESS; } +#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,9) MODULE_LICENSE("GPL"); +#endif /* * Overrides for Emacs so that we almost follow Linus's tabbing style. diff -Nru a/drivers/scsi/ips.h b/drivers/scsi/ips.h --- a/drivers/scsi/ips.h Sun Feb 9 21:13:29 2003 +++ b/drivers/scsi/ips.h Sun Feb 9 21:13:29 2003 @@ -59,11 +59,7 @@ extern int ips_eh_abort(Scsi_Cmnd *); extern int ips_eh_reset(Scsi_Cmnd *); extern int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *)); - extern int ips_biosparam(struct scsi_device *, struct block_device *, - sector_t, int *); - extern int ips_slave_configure(Scsi_Device *); extern const char * ips_info(struct Scsi_Host *); - extern void do_ips(int, void *, struct pt_regs *); /* * Some handy macros @@ -72,6 +68,13 @@ #define LinuxVersionCode(x,y,z) (((x)<<16)+((y)<<8)+(z)) #endif + #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,20) || defined CONFIG_HIGHIO + #define IPS_HIGHIO + #define IPS_HIGHMEM_IO .highmem_io = 1, + #else + #define IPS_HIGHMEM_IO + #endif + #define IPS_HA(x) ((ips_ha_t *) x->hostdata) #define IPS_COMMAND_ID(ha, scb) (int) (scb - ha->scbs) #define IPS_IS_TROMBONE(ha) (((ha->device_id == IPS_DEVICEID_COPPERHEAD) && \ @@ -81,18 +84,55 @@ (ha->revision_id >= IPS_REVID_CLARINETP1) && \ (ha->revision_id <= IPS_REVID_CLARINETP3)) ? 1 : 0) #define IPS_IS_MORPHEUS(ha) (ha->device_id == IPS_DEVICEID_MORPHEUS) + #define IPS_IS_MARCO(ha) (ha->device_id == IPS_DEVICEID_MARCO) #define IPS_USE_I2O_DELIVER(ha) ((IPS_IS_MORPHEUS(ha) || \ (IPS_IS_TROMBONE(ha) && \ (ips_force_i2o))) ? 1 : 0) - #define IPS_USE_I2O_STATUS(ha) (IPS_IS_MORPHEUS(ha)) #define IPS_USE_MEMIO(ha) ((IPS_IS_MORPHEUS(ha) || \ ((IPS_IS_TROMBONE(ha) || IPS_IS_CLARINET(ha)) && \ (ips_force_memio))) ? 1 : 0) + #define IPS_HAS_ENH_SGLIST(ha) (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) + #define IPS_USE_ENH_SGLIST(ha) ((ha)->flags & IPS_HA_ENH_SG) + #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) + #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) + #endif + #ifndef MDELAY #define MDELAY mdelay #endif - + + #ifndef min + #define min(x,y) ((x) < (y) ? x : y) + #endif + + #define pci_dma_lo32(a) (a & 0xffffffff) + + #if (BITS_PER_LONG > 32) || (defined CONFIG_HIGHMEM64G && defined IPS_HIGHIO) + #define IPS_ENABLE_DMA64 (1) + #define pci_dma_hi32(a) (a >> 32) + #else + #define IPS_ENABLE_DMA64 (0) + #define pci_dma_hi32(a) (0) + #endif + + #if defined(__ia64__) + #define IPS_ATOMIC_GFP (GFP_DMA | GFP_ATOMIC) + #define IPS_INIT_GFP GFP_DMA + #else + #define IPS_ATOMIC_GFP GFP_ATOMIC + #define IPS_INIT_GFP GFP_KERNEL + #endif + /* * Adapter address map equates */ @@ -152,7 +192,7 @@ #define IPS_CMD_DCDB 0x04 #define IPS_CMD_DCDB_SG 0x84 #define IPS_CMD_EXTENDED_DCDB 0x95 - #define IPS_CMD_EXTENDED_DCDB_SG 0x96 + #define IPS_CMD_EXTENDED_DCDB_SG 0x96 #define IPS_CMD_CONFIG_SYNC 0x58 #define IPS_CMD_ERROR_TABLE 0x17 #define IPS_CMD_DOWNLOAD 0x20 @@ -166,6 +206,7 @@ #define IPS_CSL 0xFF #define IPS_POCL 0x30 #define IPS_NORM_STATE 0x00 + #define IPS_MAX_ADAPTER_TYPES 3 #define IPS_MAX_ADAPTERS 16 #define IPS_MAX_IOCTL 1 #define IPS_MAX_IOCTL_QUEUE 8 @@ -188,15 +229,19 @@ #define IPS_INTR_IORL 1 #define IPS_FFDC 99 #define IPS_ADAPTER_ID 0xF - #define IPS_VENDORID 0x1014 + #define IPS_VENDORID_IBM 0x1014 + #define IPS_VENDORID_ADAPTEC 0x9005 #define IPS_DEVICEID_COPPERHEAD 0x002E #define IPS_DEVICEID_MORPHEUS 0x01BD + #define IPS_DEVICEID_MARCO 0x0250 #define IPS_SUBDEVICEID_4M 0x01BE #define IPS_SUBDEVICEID_4L 0x01BF #define IPS_SUBDEVICEID_4MX 0x0208 #define IPS_SUBDEVICEID_4LX 0x020E #define IPS_SUBDEVICEID_5I2 0x0259 #define IPS_SUBDEVICEID_5I1 0x0258 + #define IPS_SUBDEVICEID_6M 0x0279 + #define IPS_SUBDEVICEID_6I 0x028C #define IPS_IOCTL_SIZE 8192 #define IPS_STATUS_SIZE 4 #define IPS_STATUS_Q_SIZE (IPS_MAX_CMDS+1) * IPS_STATUS_SIZE @@ -279,6 +324,8 @@ #define IPS_ADTYPE_SERVERAID4LX 0x0B #define IPS_ADTYPE_SERVERAID5I2 0x0C #define IPS_ADTYPE_SERVERAID5I1 0x0D + #define IPS_ADTYPE_SERVERAID6M 0x0E + #define IPS_ADTYPE_SERVERAID6I 0x0F /* * Adapter Command/Status Packet Definitions @@ -350,6 +397,12 @@ #define IPS_SCSI_MP3_AllocateSurface 0x08 /* + * HA Flags + */ + + #define IPS_HA_ENH_SG 0x1 + + /* * SCB Flags */ #define IPS_SCB_MAP_SG 0x00008 @@ -387,34 +440,31 @@ * Scsi_Host Template */ #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0) -#define IPS{ \ - .module = NULL, \ - .proc_info = NULL, \ - .name = NULL, \ + static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *); + static int ips_biosparam(Disk *disk, kdev_t dev, int geom[]); +#define IPS { \ .detect = ips_detect, \ .release = ips_release, \ .info = ips_info, \ - .command = NULL, \ .queuecommand = ips_queue, \ - .eh_strategy_handler = NULL, \ .eh_abort_handler = ips_eh_abort, \ - .eh_device_reset_handler = NULL, \ - .eh_bus_reset_handler = NULL, \ .eh_host_reset_handler = ips_eh_reset, \ - .abort = NULL, \ - .reset = NULL, \ - .slave_attach = NULL, \ .bios_param = ips_biosparam,\ + .select_queue_depths = ips_select_queue_depth, \ .can_queue = 0, \ .this_id = -1, \ .sg_tablesize = IPS_MAX_SG, \ - .cmd_per_lun = 3, \ + .cmd_per_lun = 16, \ .present = 0, \ .unchecked_isa_dma = 0, \ .use_clustering = ENABLE_CLUSTERING,\ - .use_new_eh_code = 1 \ + .use_new_eh_code = 1, \ + IPS_HIGHMEM_IO \ } #else + static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev, + sector_t capacity, int geom[]); + int ips_slave_configure(Scsi_Device *SDptr); #define IPS { \ .detect = ips_detect, \ .release = ips_release, \ @@ -436,7 +486,7 @@ #endif /* - * IBM PCI Raid Command Formats + * Raid Command Formats */ typedef struct { uint8_t op_code; @@ -446,7 +496,8 @@ uint32_t lba; uint32_t sg_addr; uint16_t sector_count; - uint16_t reserved; + uint8_t segment_4G; + uint8_t enhanced_sg; uint32_t ccsar; uint32_t cccr; } IPS_IO_CMD, *PIPS_IO_CMD; @@ -497,7 +548,9 @@ uint16_t reserved; uint32_t reserved2; uint32_t dcdb_address; - uint32_t reserved3; + uint16_t reserved3; + uint8_t segment_4G; + uint8_t enhanced_sg; uint32_t ccsar; uint32_t cccr; } IPS_DCDB_CMD, *PIPS_DCDB_CMD; @@ -714,7 +767,7 @@ uint16_t usConfigUpdateCount; uint8_t ucBlkFlag; uint8_t reserved; - uint16_t usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS]; + uint16_t usAddrDeadDisk[IPS_MAX_CHANNELS * (IPS_MAX_TARGETS + 1)]; } IPS_ENQ, *PIPS_ENQ; typedef struct { @@ -790,7 +843,8 @@ uint8_t ReservedForOS2[8]; uint8_t bios_high[4]; /* Adapter's Flashed BIOS Version */ uint8_t bios_low[4]; - uint8_t Filler[76]; + uint8_t adapter_order[16]; /* BIOS Telling us the Sort Order */ + uint8_t Filler[60]; } IPS_NVRAM_P5, *PIPS_NVRAM_P5; /*--------------------------------------------------------------------------*/ @@ -940,7 +994,20 @@ typedef struct ips_sglist { uint32_t address; uint32_t length; -} IPS_SG_LIST, *PIPS_SG_LIST; +} IPS_STD_SG_LIST; + +typedef struct ips_enh_sglist { + uint32_t address_lo; + uint32_t address_hi; + uint32_t length; + uint32_t reserved; +} IPS_ENH_SG_LIST; + +typedef union { + void *list; + IPS_STD_SG_LIST *std_list; + IPS_ENH_SG_LIST *enh_list; +} IPS_SG_LIST; typedef struct _IPS_INFOSTR { char *buffer; @@ -1040,6 +1107,7 @@ char *ioctl_data; /* IOCTL data area */ uint32_t ioctl_datasize; /* IOCTL data size */ uint32_t cmd_in_progress; /* Current command in progress*/ + int flags; /* */ uint8_t waitflag; /* are we waiting for cmd */ uint8_t active; int ioctl_reset; /* IOCTL Requested Reset Flag */ @@ -1050,7 +1118,6 @@ uint8_t slot_num; /* PCI Slot Number */ uint16_t subdevice_id; /* Subsystem device ID */ uint8_t ioctl_order; /* Number of pages in ioctl */ - uint8_t reserved2; /* Empty */ uint8_t bios_version[8]; /* BIOS Revision */ uint32_t mem_addr; /* Memory mapped address */ uint32_t io_len; /* Size of IO Address */ @@ -1060,8 +1127,9 @@ ips_hw_func_t func; /* hw function pointers */ struct pci_dev *pcidev; /* PCI device handle */ char *flash_data; /* Save Area for flash data */ - u8 flash_order; /* Save Area for flash size order */ - u32 flash_datasize; /* Save Area for flash data size */ + u8 flash_order; /* Save Area for flash size order */ + u32 flash_datasize; /* Save Area for flash data size */ + uint8_t requires_esl; /* Requires an EraseStripeLock */ } ips_ha_t; typedef void (*ips_scb_callback) (ips_ha_t *, struct ips_scb *); @@ -1087,7 +1155,7 @@ uint32_t sg_len; uint32_t flags; uint32_t op_code; - IPS_SG_LIST *sg_list; + IPS_SG_LIST sg_list; Scsi_Cmnd *scsi_cmd; struct ips_scb *q_next; ips_scb_callback callback; @@ -1148,58 +1216,64 @@ #define IPS_VER_MAJOR 5 #define IPS_VER_MAJOR_STRING "5" -#define IPS_VER_MINOR 10 -#define IPS_VER_MINOR_STRING "10" -#define IPS_VER_BUILD_STRING "13" -#define IPS_VER_STRING "5.10.13-BETA" -#define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved." -#define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002." +#define IPS_VER_MINOR 99 +#define IPS_VER_MINOR_STRING "99" +#define IPS_VER_BUILD 00 +#define IPS_VER_BUILD_STRING "00" +#define IPS_VER_STRING "5.99.00" +#define IPS_BUILD_IDENT 1132 /* Version numbers for various adapters */ -#define IPS_VER_SERVERAID1 "2.25.01" -#define IPS_VER_SERVERAID2 "2.88.13" -#define IPS_VER_NAVAJO "2.88.13" -#define IPS_VER_SERVERAID3 "5.10.01" -#define IPS_VER_SERVERAID4H "5.10.01" -#define IPS_VER_SERVERAID4MLx "5.10.01" -#define IPS_VER_SARASOTA "5.10.05" +#define IPS_VER_SERVERAID1 "2.25.01" +#define IPS_VER_SERVERAID2 "2.88.13" +#define IPS_VER_NAVAJO "2.88.13" +#define IPS_VER_SERVERAID3 "5.11.05" +#define IPS_VER_SERVERAID4H "5.11.05" +#define IPS_VER_SERVERAID4MLx "5.11.05" +#define IPS_VER_SARASOTA "5.11.05" +#define IPS_VER_MARCO "0.00.00" +#define IPS_VER_SEBRING "0.00.00" /* Compatability IDs for various adapters */ -#define IPS_COMPAT_UNKNOWN "" -#define IPS_COMPAT_CURRENT "SA510" -#define IPS_COMPAT_SERVERAID1 "2.25.01" -#define IPS_COMPAT_SERVERAID2 "2.88.13" -#define IPS_COMPAT_NAVAJO "2.88.13" -#define IPS_COMPAT_KIOWA "2.88.13" -#define IPS_COMPAT_SERVERAID3H "5.10.01" -#define IPS_COMPAT_SERVERAID3L "5.10.01" -#define IPS_COMPAT_SERVERAID4H "5.10.01" +#define IPS_COMPAT_UNKNOWN "" +#define IPS_COMPAT_CURRENT "SB610" +#define IPS_COMPAT_SERVERAID1 "2.25.01" +#define IPS_COMPAT_SERVERAID2 "2.88.13" +#define IPS_COMPAT_NAVAJO "2.88.13" +#define IPS_COMPAT_KIOWA "2.88.13" +#define IPS_COMPAT_SERVERAID3H "SA510" +#define IPS_COMPAT_SERVERAID3L "SA510" +#define IPS_COMPAT_SERVERAID4H "SA510" #define IPS_COMPAT_SERVERAID4M "SA510" #define IPS_COMPAT_SERVERAID4L "SA510" #define IPS_COMPAT_SERVERAID4Mx "SA510" #define IPS_COMPAT_SERVERAID4Lx "SA510" #define IPS_COMPAT_SARASOTA "SA510" -#define IPS_COMPAT_BIOS "SA510" +#define IPS_COMPAT_MARCO "SA000" +#define IPS_COMPAT_SEBRING "SA000" +#define IPS_COMPAT_BIOS "SA510" -#define IPS_COMPAT_MAX_ADAPTER_TYPE 14 -#define IPS_COMPAT_ID_LENGTH 8 +#define IPS_COMPAT_MAX_ADAPTER_TYPE 16 +#define IPS_COMPAT_ID_LENGTH 8 #define IPS_DEFINE_COMPAT_TABLE(tablename) \ char tablename[IPS_COMPAT_MAX_ADAPTER_TYPE] [IPS_COMPAT_ID_LENGTH] = { \ - IPS_COMPAT_UNKNOWN, \ - IPS_COMPAT_SERVERAID1, \ - IPS_COMPAT_SERVERAID2, \ - IPS_COMPAT_NAVAJO, \ - IPS_COMPAT_KIOWA, \ - IPS_COMPAT_SERVERAID3H, \ - IPS_COMPAT_SERVERAID3L, \ - IPS_COMPAT_SERVERAID4H, \ - IPS_COMPAT_SERVERAID4M, \ - IPS_COMPAT_SERVERAID4L, \ + IPS_COMPAT_UNKNOWN, \ + IPS_COMPAT_SERVERAID1, \ + IPS_COMPAT_SERVERAID2, \ + IPS_COMPAT_NAVAJO, \ + IPS_COMPAT_KIOWA, \ + IPS_COMPAT_SERVERAID3H, \ + IPS_COMPAT_SERVERAID3L, \ + IPS_COMPAT_SERVERAID4H, \ + IPS_COMPAT_SERVERAID4M, \ + IPS_COMPAT_SERVERAID4L, \ IPS_COMPAT_SERVERAID4Mx, \ IPS_COMPAT_SERVERAID4Lx, \ - IPS_COMPAT_SARASOTA, \ - IPS_COMPAT_SARASOTA \ + IPS_COMPAT_SARASOTA, /* one-channel variety of SARASOTA */ \ + IPS_COMPAT_SARASOTA, /* two-channel variety of SARASOTA */ \ + IPS_COMPAT_MARCO, \ + IPS_COMPAT_SEBRING \ } diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c --- a/drivers/scsi/megaraid.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/megaraid.c Sun Feb 9 21:13:28 2003 @@ -443,7 +443,7 @@ * Mon Aug 6 14:59:29 BST 2001 - "Michael Johnson" * * Make the HP print formatting and check for buggy firmware runtime not - * ifdef dependant. + * ifdef dependent. * * * Version 1.17d @@ -863,8 +863,8 @@ { if (SCpnt->result) { TRACE (("*** %.08lx %.02x <%d.%d.%d> = %x\n", - SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, - SCpnt->target, SCpnt->lun, SCpnt->result)); + SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->device->channel, + SCpnt->device->id, SCpnt->device->lun, SCpnt->result)); } SCpnt->scsi_done (SCpnt); } @@ -1077,10 +1077,10 @@ panic(KERN_ERR "megaraid:Problem...!\n"); } - islogical = ( (SCpnt->channel >= megaCfg->productInfo.SCSIChanPresent) && - (SCpnt->channel <= megaCfg->host->max_channel) ); + islogical = ( (SCpnt->device->channel >= megaCfg->productInfo.SCSIChanPresent) && + (SCpnt->device->channel <= megaCfg->host->max_channel) ); #if 0 - islogical = (SCpnt->channel == megaCfg->host->max_channel); + islogical = (SCpnt->device->channel == megaCfg->host->max_channel); #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) @@ -1119,7 +1119,7 @@ status = 0xF0; } #endif - if( IS_RAID_CH(SCpnt->channel) && ((c & 0x1F ) == TYPE_DISK) ) { + if( IS_RAID_CH(SCpnt->device->channel) && ((c & 0x1F ) == TYPE_DISK) ) { status = 0xF0; } } @@ -1206,7 +1206,7 @@ mega_ext_passthru *epthru; long seg; char islogical; - int lun = SCpnt->lun; + int lun = SCpnt->device->lun; int max_lun; if ((SCpnt->cmnd[0] == MEGADEVIOC)) @@ -1224,11 +1224,11 @@ } #endif - islogical = ( (SCpnt->channel >= megaCfg->productInfo.SCSIChanPresent) && - (SCpnt->channel <= megaCfg->host->max_channel) ); + islogical = ( (SCpnt->device->channel >= megaCfg->productInfo.SCSIChanPresent) && + (SCpnt->device->channel <= megaCfg->host->max_channel) ); #if 0 - islogical = (IS_RAID_CH(SCpnt->channel) && /* virtual ch is raid - AM */ - (SCpnt->channel == megaCfg->host->max_channel)); + islogical = (IS_RAID_CH(SCpnt->device->channel) && /* virtual ch is raid - AM */ + (SCpnt->device->channel == megaCfg->host->max_channel)); #endif if ( ! megaCfg->support_ext_cdb ) { @@ -1239,7 +1239,7 @@ } } - if (!islogical && SCpnt->target == skip_id) { + if (!islogical && SCpnt->device->id == skip_id) { SCpnt->result = (DID_BAD_TARGET << 16); callDone (SCpnt); return NULL; @@ -1248,7 +1248,7 @@ if (islogical) { /* have just LUN 0 for each target on virtual channels */ - if( SCpnt->lun != 0 ) { + if( SCpnt->device->lun != 0 ) { SCpnt->result = (DID_BAD_TARGET << 16); callDone (SCpnt); return NULL; @@ -1561,11 +1561,11 @@ int lun; int virt_chan; - tgt = sc->target; + tgt = sc->device->id; if ( tgt > 7 ) tgt--; /* we do not get inquires for tgt 7 */ - virt_chan = sc->channel - this_hba->productInfo.SCSIChanPresent; + virt_chan = sc->device->channel - this_hba->productInfo.SCSIChanPresent; lun = (virt_chan * 15) + tgt; /* @@ -1610,11 +1610,11 @@ pthru->ars = 1; pthru->reqsenselen = 14; pthru->islogical = 0; - pthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->channel; + pthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->device->channel; pthru->target = (megacfg->flag & BOARD_40LD) ? - (sc->channel << 4) | sc->target : sc->target; + (sc->device->channel << 4) | sc->device->id : sc->device->id; pthru->cdblen = sc->cmd_len; - pthru->logdrv = sc->lun; + pthru->logdrv = sc->device->lun; memcpy (pthru->cdb, sc->cmnd, sc->cmd_len); @@ -1666,11 +1666,11 @@ epthru->ars = 1; epthru->reqsenselen = 14; epthru->islogical = 0; - epthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->channel; + epthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->device->channel; epthru->target = (megacfg->flag & BOARD_40LD) ? - (sc->channel << 4) | sc->target : sc->target; + (sc->device->channel << 4) | sc->device->id : sc->device->id; epthru->cdblen = sc->cmd_len; - epthru->logdrv = sc->lun; + epthru->logdrv = sc->device->lun; memcpy(epthru->cdb, sc->cmnd, sc->cmd_len); @@ -3535,21 +3535,21 @@ mega_scb *pScb; char *user_area = NULL; - megaCfg = (mega_host_config *) SCpnt->host->hostdata; + megaCfg = (mega_host_config *) SCpnt->device->host->hostdata; DRIVER_LOCK (megaCfg); - if (!(megaCfg->flag & (1L << SCpnt->channel))) { - if (SCpnt->channel < megaCfg->productInfo.SCSIChanPresent) + if (!(megaCfg->flag & (1L << SCpnt->device->channel))) { + if (SCpnt->device->channel < megaCfg->productInfo.SCSIChanPresent) printk ( KERN_NOTICE "scsi%d: scanning channel %d for devices.\n", - megaCfg->host->host_no, SCpnt->channel); + megaCfg->host->host_no, SCpnt->device->channel); else printk ( KERN_NOTICE "scsi%d: scanning virtual channel %d for logical drives.\n", megaCfg->host->host_no, - SCpnt->channel-megaCfg->productInfo.SCSIChanPresent+1); + SCpnt->device->channel-megaCfg->productInfo.SCSIChanPresent+1); - megaCfg->flag |= (1L << SCpnt->channel); + megaCfg->flag |= (1L << SCpnt->device->channel); } SCpnt->scsi_done = pktComp; @@ -3698,7 +3698,7 @@ rc = SCSI_ABORT_NOT_RUNNING; - megaCfg = (mega_host_config *) SCpnt->host->hostdata; + megaCfg = (mega_host_config *) SCpnt->device->host->hostdata; megaCfg->flag |= IN_ABORT; @@ -3796,18 +3796,18 @@ mega_scb *pScb; rc = SCSI_RESET_NOT_RUNNING; - megaCfg = (mega_host_config *) SCpnt->host->hostdata; + megaCfg = (mega_host_config *) SCpnt->device->host->hostdata; megaCfg->flag |= IN_RESET; printk ("megaraid_RESET: %.08lx cmd=%.02x , flag = %x\n", - SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, - SCpnt->target, SCpnt->lun, rstflags); + SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->device->channel, + SCpnt->device->id, SCpnt->device->lun, rstflags); TRACE (("RESET: %.08lx %.02x <%d.%d.%d>\n", - SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, - SCpnt->target, SCpnt->lun)); + SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->device->channel, + SCpnt->device->id, SCpnt->device->lun)); /* * Walk list of SCBs for any that are still outstanding @@ -4515,7 +4515,7 @@ if(scsicmd == NULL) return -ENOMEM; memset(scsicmd, 0, sizeof(Scsi_Cmnd)); - scsicmd->host = shpnt; + scsicmd->device->host = shpnt; if( outlen || inlen ) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) @@ -4652,7 +4652,7 @@ if(scsicmd == NULL) return -ENOMEM; memset(scsicmd, 0, sizeof(Scsi_Cmnd)); - scsicmd->host = shpnt; + scsicmd->device->host = shpnt; if (outlen || inlen) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) diff -Nru a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c --- a/drivers/scsi/ncr53c8xx.c Sun Feb 9 21:13:30 2003 +++ b/drivers/scsi/ncr53c8xx.c Sun Feb 9 21:13:30 2003 @@ -3196,8 +3196,8 @@ static void PRINT_ADDR(Scsi_Cmnd *cmd) { - struct host_data *host_data = (struct host_data *) cmd->host->hostdata; - PRINT_LUN(host_data->ncb, cmd->target, cmd->lun); + struct host_data *host_data = (struct host_data *) cmd->device->host->hostdata; + PRINT_LUN(host_data->ncb, cmd->device->id, cmd->device->lun); } /*========================================================== @@ -4345,8 +4345,8 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd) { /* Scsi_Device *device = cmd->device; */ - tcb_p tp = &np->target[cmd->target]; - lcb_p lp = tp->lp[cmd->lun]; + tcb_p tp = &np->target[cmd->device->id]; + lcb_p lp = tp->lp[cmd->device->lun]; ccb_p cp; int segments; @@ -4361,9 +4361,9 @@ ** **--------------------------------------------- */ - if ((cmd->target == np->myaddr ) || - (cmd->target >= MAX_TARGET) || - (cmd->lun >= MAX_LUN )) { + if ((cmd->device->id == np->myaddr ) || + (cmd->device->id >= MAX_TARGET) || + (cmd->device->lun >= MAX_LUN )) { return(DID_BAD_TARGET); } @@ -4403,7 +4403,7 @@ np->settle_time = tlimit; } - if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->target, cmd->lun))) { + if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->device->id, cmd->device->lun))) { insert_into_waiting_list(np, cmd); return(DID_OK); } @@ -4418,7 +4418,7 @@ #if 0 /* This stuff was only useful for linux-1.2.13 */ if (lp && !lp->numtags && cmd->device && cmd->device->tagged_queue) { lp->numtags = tp->usrtags; - ncr_setup_tags (np, cmd->target, cmd->lun); + ncr_setup_tags (np, cmd->device->id, cmd->device->lun); } #endif @@ -4429,7 +4429,7 @@ **---------------------------------------------------- */ - idmsg = M_IDENTIFY | cmd->lun; + idmsg = M_IDENTIFY | cmd->device->lun; if (cp ->tag != NO_TAG || (cp != np->ccb && np->disc && !(tp->usrflag & UF_NODISC))) @@ -4662,7 +4662,7 @@ /* ** select */ - cp->phys.select.sel_id = cmd->target; + cp->phys.select.sel_id = cmd->device->id; cp->phys.select.sel_scntl3 = tp->wval; cp->phys.select.sel_sxfer = tp->sval; /* @@ -5199,8 +5199,8 @@ cmd = cp->cmd; cp->cmd = NULL; - tp = &np->target[cmd->target]; - lp = tp->lp[cmd->lun]; + tp = &np->target[cmd->device->id]; + lp = tp->lp[cmd->device->lun]; /* ** We donnot queue more than 1 ccb per target @@ -5296,7 +5296,7 @@ ** Allocate the lcb if not yet. */ if (!lp) - ncr_alloc_lcb (np, cmd->target, cmd->lun); + ncr_alloc_lcb (np, cmd->device->id, cmd->device->lun); /* ** On standard INQUIRY response (EVPD and CmDt @@ -5306,7 +5306,7 @@ if (cmd->cmnd[0] == 0x12 && !(cmd->cmnd[1] & 0x3) && cmd->cmnd[4] >= 7 && !cmd->use_sg) { sync_scsi_data(np, cmd); /* SYNC the data */ - ncr_setup_lcb (np, cmd->target, cmd->lun, + ncr_setup_lcb (np, cmd->device->id, cmd->device->lun, (char *) cmd->request_buffer); } @@ -5322,7 +5322,7 @@ if (lp->num_good >= 1000) { lp->num_good = 0; ++lp->numtags; - ncr_setup_tags (np, cmd->target, cmd->lun); + ncr_setup_tags (np, cmd->device->id, cmd->device->lun); } } } else if ((cp->host_status == HS_COMPLETE) @@ -5902,7 +5902,7 @@ */ for (cp = np->ccb; cp; cp = cp->link_ccb) { if (!cp->cmd) continue; - if (cp->cmd->target != target) continue; + if (cp->cmd->device->id != target) continue; #if 0 cp->sync_status = tp->sval; cp->wide_status = tp->wval; @@ -5932,7 +5932,7 @@ cmd = cp->cmd; if (!cmd) return; - assert (target == (cmd->target & 0xf)); + assert (target == (cmd->device->id & 0xf)); tp = &np->target[target]; @@ -6017,7 +6017,7 @@ cmd = cp->cmd; if (!cmd) return; - assert (target == (cmd->target & 0xf)); + assert (target == (cmd->device->id & 0xf)); tp = &np->target[target]; tp->widedone = wide+1; @@ -7057,8 +7057,8 @@ static void ncr_sir_to_redo(ncb_p np, int num, ccb_p cp) { Scsi_Cmnd *cmd = cp->cmd; - tcb_p tp = &np->target[cmd->target]; - lcb_p lp = tp->lp[cmd->lun]; + tcb_p tp = &np->target[cmd->device->id]; + lcb_p lp = tp->lp[cmd->device->lun]; XPT_QUEHEAD *qp; ccb_p cp2; int disc_cnt = 0; @@ -7104,7 +7104,7 @@ if (disc_cnt < lp->numtags) { lp->numtags = disc_cnt > 2 ? disc_cnt : 2; lp->num_good = 0; - ncr_setup_tags (np, cmd->target, cmd->lun); + ncr_setup_tags (np, cmd->device->id, cmd->device->lun); } /* ** Requeue the command to the start queue. @@ -7136,7 +7136,7 @@ ** ** identify message */ - cp->scsi_smsg2[0] = M_IDENTIFY | cmd->lun; + cp->scsi_smsg2[0] = M_IDENTIFY | cmd->device->lun; cp->phys.smsg.addr = cpu_to_scr(CCB_PHYS (cp, scsi_smsg2)); cp->phys.smsg.size = cpu_to_scr(1); @@ -7150,7 +7150,7 @@ ** patch requested size into sense command */ cp->sensecmd[0] = 0x03; - cp->sensecmd[1] = cmd->lun << 5; + cp->sensecmd[1] = cmd->device->lun << 5; cp->sensecmd[4] = sizeof(cp->sense_buf); /* @@ -8731,7 +8731,7 @@ int ncr53c8xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) { - ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb; + ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb; unsigned long flags; int sts; @@ -8798,9 +8798,9 @@ if (DEBUG_FLAGS & DEBUG_TINY) printk ("]\n"); if (done_list) { - NCR_LOCK_SCSI_DONE(done_list->host, flags); + NCR_LOCK_SCSI_DONE(done_list->device->host, flags); ncr_flush_done_cmds(done_list); - NCR_UNLOCK_SCSI_DONE(done_list->host, flags); + NCR_UNLOCK_SCSI_DONE(done_list->device->host, flags); } } @@ -8821,9 +8821,9 @@ NCR_UNLOCK_NCB(np, flags); if (done_list) { - NCR_LOCK_SCSI_DONE(done_list->host, flags); + NCR_LOCK_SCSI_DONE(done_list->device->host, flags); ncr_flush_done_cmds(done_list); - NCR_UNLOCK_SCSI_DONE(done_list->host, flags); + NCR_UNLOCK_SCSI_DONE(done_list->device->host, flags); } } @@ -8837,7 +8837,7 @@ int ncr53c8xx_reset(Scsi_Cmnd *cmd) #endif { - ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb; + ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb; int sts; unsigned long flags; Scsi_Cmnd *done_list; @@ -8899,7 +8899,7 @@ int ncr53c8xx_abort(Scsi_Cmnd *cmd) { - ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb; + ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb; int sts; unsigned long flags; Scsi_Cmnd *done_list; diff -Nru a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c --- a/drivers/scsi/nsp32.c Sun Feb 9 21:13:31 2003 +++ b/drivers/scsi/nsp32.c Sun Feb 9 21:13:31 2003 @@ -458,7 +458,7 @@ /* XXX: Auto DiscPriv detection is progressing... */ 0x40 | /* DiscPriv */ #endif - SCpnt->lun; /* LUNTRN */ + SCpnt->device->lun; /* LUNTRN */ data->msgoutlen = pos; } @@ -532,9 +532,9 @@ */ static int nsp32hw_start_selection(Scsi_Cmnd *SCpnt, nsp32_hw_data *data) { - unsigned int host_id = SCpnt->host->this_id; - unsigned int base = SCpnt->host->io_port; - unsigned char target = SCpnt->target; + unsigned int host_id = SCpnt->device->host->this_id; + unsigned int base = SCpnt->device->host->io_port; + unsigned char target = SCpnt->device->id; unsigned char *param = data->autoparam; unsigned char phase, arbit; int i, time; @@ -744,7 +744,7 @@ * set SCSIOUT LATCH(initiator)/TARGET(target) (ORed) ID */ nsp32_write1(base, SCSI_OUT_LATCH_TARGET_ID, - ((1 << NSP32_HOST_SCSIID) | (1 << SCpnt->target))); + ((1 << NSP32_HOST_SCSIID) | (1 << SCpnt->device->id))); /* * set SCSI MSGOUT REG @@ -1021,7 +1021,7 @@ static int nsp32_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { - nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; struct nsp32_target *target; struct nsp32_lunt *curlunt; int ret; @@ -1029,7 +1029,7 @@ nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "enter. target: 0x%x LUN: 0x%x cmnd: 0x%x cmndlen: 0x%x " "use_sg: 0x%x reqbuf: 0x%lx reqlen: 0x%x", - SCpnt->target, SCpnt->lun, SCpnt->cmnd[0], SCpnt->cmd_len, + SCpnt->device->id, SCpnt->device->lun, SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_buffer, SCpnt->request_bufflen); if (data->CurrentSC != NULL ) { @@ -1042,14 +1042,14 @@ } /* check target ID is not same as this initiator ID */ - if (SCpnt->target == NSP32_HOST_SCSIID) { + if (SCpnt->device->id == NSP32_HOST_SCSIID) { SCpnt->result = DID_BAD_TARGET << 16; done(SCpnt); return 1; } /* check target LUN is allowable value */ - if (SCpnt->lun >= MAX_LUN) { + if (SCpnt->device->lun >= MAX_LUN) { SCpnt->result = DID_BAD_TARGET << 16; done(SCpnt); return 1; @@ -1071,13 +1071,13 @@ /* initialize data */ data->msgoutlen = 0; data->msginlen = 0; - curlunt = data->lunt[SCpnt->target][SCpnt->lun]; + curlunt = data->lunt[SCpnt->device->id][SCpnt->device->lun]; curlunt->SCpnt = SCpnt; curlunt->save_datp = 0; curlunt->msgin03 = FALSE; data->curlunt = curlunt; - data->pid = SCpnt->target; - data->plun = SCpnt->lun; + data->pid = SCpnt->device->id; + data->plun = SCpnt->device->lun; ret = nsp32hw_setup_sg_table(SCpnt, data); if (ret == FALSE) { @@ -1093,7 +1093,7 @@ * (target don't have SDTR_DONE and SDTR_INITIATOR), sync * message SDTR is needed to do synchronous transfer. */ - target = &data->target[SCpnt->target]; + target = &data->target[SCpnt->device->id]; data->curtarget = target; if (!(target->sync_flag & (SDTR_DONE | SDTR_INITIATOR | SDTR_TARGET))) { @@ -1139,7 +1139,7 @@ nsp32_dbg(NSP32_DEBUG_TARGETFLAG, "target: %d sync_flag: 0x%x syncreg: 0x%x ackwidth: 0x%x", - SCpnt->target, target->sync_flag, target->syncreg, + SCpnt->device->id, target->sync_flag, target->syncreg, target->ackwidth); /* Selection */ @@ -1920,7 +1920,7 @@ static int nsp32_eh_abort(Scsi_Cmnd *SCpnt) { - nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; unsigned int base = data->BaseAddress; nsp32_msg(KERN_WARNING, "abort"); @@ -1942,7 +1942,7 @@ static int nsp32_eh_bus_reset(Scsi_Cmnd *SCpnt) { - nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata; + nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; unsigned int base = data->BaseAddress; nsp32_msg(KERN_INFO, "Bus Reset"); @@ -1997,7 +1997,7 @@ static int nsp32_eh_host_reset(Scsi_Cmnd *SCpnt) { - struct Scsi_Host *host = SCpnt->host; + struct Scsi_Host *host = SCpnt->device->host; nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata; unsigned int base = data->BaseAddress; diff -Nru a/drivers/scsi/osst.c b/drivers/scsi/osst.c --- a/drivers/scsi/osst.c Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/osst.c Sun Feb 9 21:13:32 2003 @@ -4211,7 +4211,7 @@ unsigned short flags; int i, b_size, new_session = FALSE, retval = 0; unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; + Scsi_Request * SRpnt = NULL; OS_Scsi_Tape * STp; ST_mode * STm; ST_partstat * STps; diff -Nru a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c --- a/drivers/scsi/pci2000.c Sun Feb 9 21:13:33 2003 +++ b/drivers/scsi/pci2000.c Sun Feb 9 21:13:33 2003 @@ -390,7 +390,7 @@ OpDone (SCpnt, DID_OK << 16); irq_return: - spin_unlock_irqrestore(&shost->host_lock, flags); + spin_unlock_irqrestore(shost->host_lock, flags); out:; } /**************************************************************** @@ -407,11 +407,11 @@ int Pci2000_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB - PADAPTER2000 padapter = HOSTDATA(SCpnt->host); // Pointer to adapter control structure + PADAPTER2000 padapter = HOSTDATA(SCpnt->device->host); // Pointer to adapter control structure int rc = -1; // command return code - UCHAR bus = SCpnt->channel; - UCHAR pun = SCpnt->target; - UCHAR lun = SCpnt->lun; + UCHAR bus = SCpnt->device->channel; + UCHAR pun = SCpnt->device->id; + UCHAR lun = SCpnt->device->lun; UCHAR cmd; PDEV2000 pdev = &padapter->dev[bus][pun]; @@ -506,13 +506,16 @@ if ( SCpnt->use_sg ) { - SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, ((struct scatterlist *)SCpnt->request_buffer)->address, - SCpnt->request_bufflen, scsi_to_pci_dma_dir (SCpnt->sc_data_direction)); + SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, + ((struct scatterlist *)SCpnt->request_buffer)->address, + SCpnt->request_bufflen, + scsi_to_pci_dma_dir (SCpnt->sc_data_direction)); } else { - SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, - SCpnt->request_bufflen, scsi_to_pci_dma_dir (SCpnt->sc_data_direction)); + SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, + SCpnt->request_bufflen, + scsi_to_pci_dma_dir (SCpnt->sc_data_direction)); } outl (SCpnt->SCp.have_data_in, padapter->mb2); outl (SCpnt->request_bufflen, padapter->mb3); diff -Nru a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h --- a/drivers/scsi/pci2000.h Sun Feb 9 21:13:36 2003 +++ b/drivers/scsi/pci2000.h Sun Feb 9 21:13:36 2003 @@ -202,15 +202,15 @@ #endif /* screen is 80 columns wide, damnit! */ -#define PCI2000 { \ +#define PCI2000 { \ .proc_name = "pci2000", \ .name = "PCI-2000 SCSI Intelligent Disk Controller", \ - .detect = Pci2000_Detect, \ + .detect = Pci2000_Detect, \ .release = Pci2000_Release, \ .command = Pci2000_Command, \ .queuecommand = Pci2000_QueueCommand, \ - .abort = Pci2000_Abort, \ - .reset = Pci2000_Reset, \ + .abort = Pci2000_Abort, \ + .reset = Pci2000_Reset, \ .bios_param = Pci2000_BiosParam, \ .can_queue = 16, \ .this_id = -1, \ diff -Nru a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c --- a/drivers/scsi/pci2220i.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/pci2220i.c Sun Feb 9 21:13:28 2003 @@ -1156,7 +1156,7 @@ static void TimerExpiry (unsigned long data) { PADAPTER2220I padapter = (PADAPTER2220I)data; - struct Scsi_Host *host = padapter->SCpnt->host; + struct Scsi_Host *host = padapter->SCpnt->device->host; POUR_DEVICE pdev = padapter->pdev; UCHAR status = IDE_STATUS_BUSY; UCHAR temp, temp1; @@ -1334,7 +1334,7 @@ static void ReconTimerExpiry (unsigned long data) { PADAPTER2220I padapter = (PADAPTER2220I)data; - struct Scsi_Host *host = padapter->SCpnt->host; + struct Scsi_Host *host = padapter->SCpnt->device->host; POUR_DEVICE pdev; ULONG testsize = 0; PIDENTIFY_DATA pid; @@ -2041,8 +2041,8 @@ int Pci2220i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB - PADAPTER2220I padapter = HOSTDATA(SCpnt->host); // Pointer to adapter control structure - POUR_DEVICE pdev = &padapter->device[SCpnt->target];// Pointer to device information + PADAPTER2220I padapter = HOSTDATA(SCpnt->device->host); // Pointer to adapter control structure + POUR_DEVICE pdev = &padapter->device[SCpnt->device->id];// Pointer to device information UCHAR rc; // command return code int z; PDEVICE_RAID1 pdr; @@ -2073,9 +2073,9 @@ { UCHAR zlo, zhi; - DEB (printk ("\nPCI2242I: ID %d, LUN %d opcode %X ", SCpnt->target, SCpnt->lun, *cdb)); + DEB (printk ("\nPCI2242I: ID %d, LUN %d opcode %X ", SCpnt->device->id, SCpnt->device->lun, *cdb)); padapter->pdev = pdev; - if ( !pdev->byte6 || SCpnt->lun ) + if ( !pdev->byte6 || SCpnt->device->lun ) { OpDone (padapter, DID_BAD_TARGET << 16); return 0; @@ -2138,7 +2138,7 @@ padapter->reconTimer.data = 0; } - if ( (SCpnt->target >= padapter->numberOfDrives) || SCpnt->lun ) + if ( (SCpnt->device->id >= padapter->numberOfDrives) || SCpnt->device->lun ) { OpDone (padapter, DID_BAD_TARGET << 16); return 0; @@ -2791,8 +2791,8 @@ ****************************************************************/ int Pci2220i_Abort (Scsi_Cmnd *SCpnt) { - PADAPTER2220I padapter = HOSTDATA(SCpnt->host); // Pointer to adapter control structure - POUR_DEVICE pdev = &padapter->device[SCpnt->target];// Pointer to device information + PADAPTER2220I padapter = HOSTDATA(SCpnt->device->host); // Pointer to adapter control structure + POUR_DEVICE pdev = &padapter->device[SCpnt->device->id];// Pointer to device information if ( !padapter->SCpnt ) return SCSI_ABORT_NOT_RUNNING; @@ -2823,8 +2823,8 @@ ****************************************************************/ int Pci2220i_Reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags) { - PADAPTER2220I padapter = HOSTDATA(SCpnt->host); // Pointer to adapter control structure - POUR_DEVICE pdev = &padapter->device[SCpnt->target];// Pointer to device information + PADAPTER2220I padapter = HOSTDATA(SCpnt->device->host); // Pointer to adapter control structure + POUR_DEVICE pdev = &padapter->device[SCpnt->device->id];// Pointer to device information if ( padapter->atapi ) { diff -Nru a/drivers/scsi/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig --- a/drivers/scsi/pcmcia/Kconfig Sun Feb 9 21:13:33 2003 +++ b/drivers/scsi/pcmcia/Kconfig Sun Feb 9 21:13:33 2003 @@ -23,7 +23,7 @@ Say Y here if you intend to attach this type of PCMCIA SCSI host adapter to your computer. - This driver is also available as a module called aha152x_cs.o ( = + This driver is also available as a module called aha152x_cs ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -35,7 +35,7 @@ Say Y here if you intend to attach this type of PCMCIA SCSI host adapter to your computer. - This driver is also available as a module called fdomain_cs.o ( = + This driver is also available as a module called fdomain_cs ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -48,7 +48,7 @@ your computer, say Y here and read . - This driver is also available as a module called nsp_cs.o ( = + This driver is also available as a module called nsp_cs ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -60,7 +60,7 @@ Say Y here if you intend to attach this type of PCMCIA SCSI host adapter to your computer. - This driver is also available as a module called qlogic_cs.o ( = + This driver is also available as a module called qlogic_cs ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . diff -Nru a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c --- a/drivers/scsi/pcmcia/aha152x_stub.c Sun Feb 9 21:13:35 2003 +++ b/drivers/scsi/pcmcia/aha152x_stub.c Sun Feb 9 21:13:35 2003 @@ -142,6 +142,7 @@ if (!info) return NULL; memset(info, 0, sizeof(*info)); link = &info->link; link->priv = info; + init_timer(&link->release); link->release.function = &aha152x_release_cs; link->release.data = (u_long)link; @@ -350,7 +351,7 @@ DEBUG(0, "aha152x_release_cs(0x%p)\n", link); -#warning This doesn't protect you. You need some real fix for your races. +#warning This does not protect you. You need some real fix for your races. #if 0 if (GET_USE_COUNT(driver_template.module) != 0) { DEBUG(1, "aha152x_cs: release postponed, " diff -Nru a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c --- a/drivers/scsi/pcmcia/fdomain_stub.c Sun Feb 9 21:13:33 2003 +++ b/drivers/scsi/pcmcia/fdomain_stub.c Sun Feb 9 21:13:33 2003 @@ -122,6 +122,7 @@ if (!info) return NULL; memset(info, 0, sizeof(*info)); link = &info->link; link->priv = info; + init_timer(&link->release); link->release.function = &fdomain_release; link->release.data = (u_long)link; @@ -313,7 +314,7 @@ DEBUG(0, "fdomain_release(0x%p)\n", link); -#warning This doesn't protect you. You need some real fix for your races. +#warning This does not protect you. You need some real fix for your races. #if 0 if (GET_USE_COUNT(&__this_module) != 0) { DEBUG(1, "fdomain_cs: release postponed, " diff -Nru a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c --- a/drivers/scsi/pcmcia/qlogic_stub.c Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/pcmcia/qlogic_stub.c Sun Feb 9 21:13:32 2003 @@ -126,6 +126,7 @@ memset(info, 0, sizeof(*info)); link = &info->link; link->priv = info; + init_timer(&link->release); link->release.function = &qlogic_release; link->release.data = (u_long) link; @@ -329,7 +330,7 @@ DEBUG(0, "qlogic_release(0x%p)\n", link); -#warning This doesn't protect you. You need some real fix for your races. +#warning This does not protect you. You need some real fix for your races. #if 0 if (GET_USE_COUNT(&__this_module) != 0) { DEBUG(0, "qlogic_cs: release postponed, device still open\n"); diff -Nru a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c --- a/drivers/scsi/pluto.c Sun Feb 9 21:13:30 2003 +++ b/drivers/scsi/pluto.c Sun Feb 9 21:13:30 2003 @@ -156,12 +156,12 @@ pluto->fc = fc; - SCpnt->host = host; SCpnt->cmnd[0] = INQUIRY; SCpnt->cmnd[4] = 255; /* FC layer requires this, so that SCpnt->device->tagged_supported is initially 0 */ SCpnt->device = &dev; + dev.host = host; SCpnt->cmd_len = COMMAND_SIZE(INQUIRY); @@ -325,16 +325,18 @@ */ static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd) { - PLND(("encode addr %d %d %d\n", SCpnt->channel, SCpnt->target, SCpnt->cmnd[1] & 0xe0)) + PLND(("encode addr %d %d %d\n", SCpnt->device->channel, SCpnt->device->id, SCpnt->cmnd[1] & 0xe0)) /* We don't support LUNs - neither does SSA :) */ - if (SCpnt->cmnd[1] & 0xe0) return -EINVAL; - if (!SCpnt->channel) { - if (SCpnt->target) return -EINVAL; + if (SCpnt->cmnd[1] & 0xe0) + return -EINVAL; + if (!SCpnt->device->channel) { + if (SCpnt->device->id) + return -EINVAL; memset (addr, 0, 4 * sizeof(u16)); } else { addr[0] = 1; - addr[1] = SCpnt->channel - 1; - addr[2] = SCpnt->target; + addr[1] = SCpnt->device->channel - 1; + addr[2] = SCpnt->device->id; addr[3] = 0; } /* We're Point-to-Point, so target it to the default DID */ diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c --- a/drivers/scsi/qla1280.c Sun Feb 9 21:13:37 2003 +++ b/drivers/scsi/qla1280.c Sun Feb 9 21:13:37 2003 @@ -107,8 +107,8 @@ - Provide compat macros for pci_enable_device(), pci_find_subsys() and scsi_set_pci_device() - Call scsi_set_pci_device() for all devices - - Reduce size of kernel version dependant device probe code - - Move duplicate probe/init code to seperate function + - Reduce size of kernel version dependent device probe code + - Move duplicate probe/init code to separate function - Handle error if qla1280_mem_alloc() fails - Kill OFFSET() macro and use Linux's PCI definitions instead - Kill private structure defining PCI config space (struct config_reg) @@ -588,9 +588,9 @@ #define ENTER_INTR(x) dprintk(3, "qla1280 : Entering %s()\n", x); #define LEAVE_INTR(x) dprintk(3, "qla1280 : Leaving %s()\n", x); -#define SCSI_BUS_32(scp) scp->channel -#define SCSI_TCN_32(scp) scp->target -#define SCSI_LUN_32(scp) scp->lun +#define SCSI_BUS_32(scp) scp->device->channel +#define SCSI_TCN_32(scp) scp->device->id +#define SCSI_LUN_32(scp) scp->device->lun /****************************************************************************/ /* LINUX - Loadable Module Functions. */ @@ -866,19 +866,17 @@ "qla1280", ha)) { printk("qla1280 : Failed to reserve interrupt %d already " "in use\n", host->irq); - goto error_mem_alloced; + goto error_unmap; } #if !MEMORY_MAPPED_IO /* Register the I/O space with Linux */ - if (check_region(host->io_port, 0xff)) { + if (!request_region(host->io_port, 0xff, "qla1280")) { printk("qla1280 : Failed to reserve i/o region 0x%04lx-0x%04lx" " already in use\n", host->io_port, host->io_port + 0xff); - free_irq(host->irq, ha); - goto error_mem_alloced; + goto error_irq; } - request_region(host->io_port, 0xff, "qla1280"); #endif reg = ha->iobase; @@ -886,7 +884,7 @@ /* load the F/W, read paramaters, and init the H/W */ if (qla1280_initialize_adapter(ha)) { printk(KERN_INFO "qla1x160:Failed to initialize adapter\n"); - goto error_mem_alloced; + goto error_region; } /* set our host ID (need to do something about our two IDs) */ @@ -894,6 +892,21 @@ return host; + error_region: +#if !MEMORY_MAPPED_IO + release_region(host->io_port, 0xff); +#endif + + error_irq: + free_irq(host->irq, ha); + + error_unmap: +#if MEMORY_MAPPED_IO + if (ha->mmpbase) + iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK)); +#endif + + error_mem_alloced: qla1280_mem_free(ha); @@ -1157,7 +1170,7 @@ /*ENTER("qla1280_queuecommand"); */ - host = cmd->host; + host = cmd->device->host; ha = (struct scsi_qla_host *)host->hostdata; /* send command to adapter */ @@ -1232,8 +1245,8 @@ u16 data; ENTER("qla1280_abort"); - ha = (struct scsi_qla_host *)cmd->host->hostdata; - host = cmd->host; + ha = (struct scsi_qla_host *)cmd->device->host->hostdata; + host = cmd->device->host; /* Get the SCSI request ptr */ sp = (srb_t *)CMD_SP(cmd); @@ -1365,7 +1378,7 @@ u16 data; ENTER("qla1280_abort"); - host = cmd->host; + host = cmd->device->host; ha = (struct scsi_qla_host *)host->hostdata; /* Get the SCSI request ptr */ @@ -1523,7 +1536,7 @@ "pointer, failing.\n"); return SCSI_RESET_SNOOZE; } - ha = (struct scsi_qla_host *)cmd->host->hostdata; + ha = (struct scsi_qla_host *)cmd->device->host->hostdata; sp = (srb_t *)CMD_SP(cmd); #if STOP_ON_RESET @@ -1820,7 +1833,7 @@ /* device->queue_depth = 20; */ printk(KERN_INFO "scsi(%li:%d:%d:%d): Enabled tagged queuing, " "queue depth %d.\n", p->host_no, device->channel, - device->id, device->lun, device->new_queue_depth); + device->id, device->lun, device->queue_depth); } else { scsi_adjust_queue_depth(device, 0 /* TCQ off */, 3); } diff -Nru a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c --- a/drivers/scsi/qlogicfas.c Sun Feb 9 21:13:37 2003 +++ b/drivers/scsi/qlogicfas.c Sun Feb 9 21:13:37 2003 @@ -348,7 +348,7 @@ /**/ outb(qlcfg5, qbase + 5); /* select timer */ outb(qlcfg9 & 7, qbase + 9); /* prescaler */ /* outb(0x99, qbase + 5); */ - outb(cmd->target, qbase + 4); + outb(cmd->device->id, qbase + 4); for (i = 0; i < cmd->cmd_len; i++) outb(cmd->cmnd[i], qbase + 2); @@ -573,7 +573,7 @@ * Non-irq version */ - if (cmd->target == qinitid) + if (cmd->device->id == qinitid) return (DID_BAD_TARGET << 16); ql_icmd(cmd); if ((k = ql_wai())) @@ -590,7 +590,7 @@ int qlogicfas_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) { - if (cmd->target == qinitid) { + if (cmd->device->id == qinitid) { cmd->result = DID_BAD_TARGET << 16; done(cmd); return 0; diff -Nru a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c --- a/drivers/scsi/qlogicfc.c Sun Feb 9 21:13:34 2003 +++ b/drivers/scsi/qlogicfc.c Sun Feb 9 21:13:34 2003 @@ -397,7 +397,7 @@ #define MBOX_PORT_LOGOUT 0x0071 /* - * Firmware if needed (note this is a hack, it belongs in a seperate + * Firmware if needed (note this is a hack, it belongs in a separate * module. */ @@ -1148,7 +1148,7 @@ ENTER("isp2x00_queuecommand"); - host = Cmnd->host; + host = Cmnd->device->host; hostdata = (struct isp2x00_hostdata *) host->hostdata; Cmnd->scsi_done = done; @@ -1233,10 +1233,10 @@ cmd->hdr.entry_type = ENTRY_COMMAND; cmd->hdr.entry_cnt = 1; - cmd->target_lun = Cmnd->lun; - cmd->expanded_lun = cpu_to_le16(Cmnd->lun); + cmd->target_lun = Cmnd->device->lun; + cmd->expanded_lun = cpu_to_le16(Cmnd->device->lun); #if ISP2x00_PORTDB - cmd->target_id = hostdata->port_db[Cmnd->target].loop_id; + cmd->target_id = hostdata->port_db[Cmnd->device->id].loop_id; #else cmd->target_id = Cmnd->target; #endif @@ -1312,9 +1312,9 @@ cmd->control_flags = cpu_to_le16(CFLAG_READ); if (Cmnd->device->tagged_supported) { - if ((jiffies - hostdata->tag_ages[Cmnd->target]) > (2 * SCSI_TIMEOUT)) { + if ((jiffies - hostdata->tag_ages[Cmnd->device->id]) > (2 * SCSI_TIMEOUT)) { cmd->control_flags |= cpu_to_le16(CFLAG_ORDERED_TAG); - hostdata->tag_ages[Cmnd->target] = jiffies; + hostdata->tag_ages[Cmnd->device->id] = jiffies; } else switch (Cmnd->tag) { case HEAD_OF_QUEUE_TAG: @@ -1383,8 +1383,8 @@ } for (i = 0; i < QLOGICFC_REQ_QUEUE_LEN; i++){ - if (hostdata->handle_ptrs[i] && (hostdata->port_db[hostdata->handle_ptrs[i]->target].loop_id > QLOGICFC_MAX_LOOP_ID || hostdata->adapter_state & AS_REDO_LOOP_PORTDB)){ - if (hostdata->port_db[hostdata->handle_ptrs[i]->target].loop_id != hostdata->port_db[0].loop_id){ + if (hostdata->handle_ptrs[i] && (hostdata->port_db[hostdata->handle_ptrs[i]->device->id].loop_id > QLOGICFC_MAX_LOOP_ID || hostdata->adapter_state & AS_REDO_LOOP_PORTDB)){ + if (hostdata->port_db[hostdata->handle_ptrs[i]->device->id].loop_id != hostdata->port_db[0].loop_id){ Scsi_Cmnd *Cmnd = hostdata->handle_ptrs[i]; if (Cmnd->use_sg) @@ -1581,7 +1581,7 @@ * the device may well be back in a couple of * seconds. */ - if ((hostdata->adapter_state == AS_LOOP_DOWN || sts->completion_status == cpu_to_le16(CS_PORT_UNAVAILABLE) || sts->completion_status == cpu_to_le16(CS_PORT_LOGGED_OUT) || sts->completion_status == cpu_to_le16(CS_PORT_CONFIG_CHANGED)) && hostdata->port_db[Cmnd->target].wwn){ + if ((hostdata->adapter_state == AS_LOOP_DOWN || sts->completion_status == cpu_to_le16(CS_PORT_UNAVAILABLE) || sts->completion_status == cpu_to_le16(CS_PORT_LOGGED_OUT) || sts->completion_status == cpu_to_le16(CS_PORT_CONFIG_CHANGED)) && hostdata->port_db[Cmnd->device->id].wwn){ outw(out_ptr, host->io_port + MBOX5); continue; } @@ -1709,7 +1709,7 @@ ENTER("isp2x00_abort"); - host = Cmnd->host; + host = Cmnd->device->host; hostdata = (struct isp2x00_hostdata *) host->hostdata; for (i = 0; i < QLOGICFC_REQ_QUEUE_LEN; i++) @@ -1724,7 +1724,7 @@ param[0] = MBOX_ABORT_IOCB; #if ISP2x00_PORTDB - param[1] = (((u_short) hostdata->port_db[Cmnd->target].loop_id) << 8) | Cmnd->lun; + param[1] = (((u_short) hostdata->port_db[Cmnd->device->id].loop_id) << 8) | Cmnd->device->lun; #else param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun; #endif @@ -1766,7 +1766,7 @@ ENTER("isp2x00_reset"); - host = Cmnd->host; + host = Cmnd->device->host; hostdata = (struct isp2x00_hostdata *) host->hostdata; param[0] = MBOX_BUS_RESET; param[1] = 3; diff -Nru a/drivers/scsi/qlogicisp.c b/drivers/scsi/qlogicisp.c --- a/drivers/scsi/qlogicisp.c Sun Feb 9 21:13:37 2003 +++ b/drivers/scsi/qlogicisp.c Sun Feb 9 21:13:37 2003 @@ -802,7 +802,7 @@ ENTER("isp1020_queuecommand"); - host = Cmnd->host; + host = Cmnd->device->host; hostdata = (struct isp1020_hostdata *) host->hostdata; Cmnd->scsi_done = done; @@ -853,8 +853,8 @@ cmd->hdr.entry_type = ENTRY_COMMAND; cmd->hdr.entry_cnt = 1; - cmd->target_lun = Cmnd->lun; - cmd->target_id = Cmnd->target; + cmd->target_lun = Cmnd->device->lun; + cmd->target_id = Cmnd->device->id; cmd->cdb_length = cpu_to_le16(Cmnd->cmd_len); cmd->control_flags = cpu_to_le16(CFLAG_READ | CFLAG_WRITE); cmd->time_out = cpu_to_le16(30); @@ -1175,7 +1175,7 @@ ENTER("isp1020_abort"); - host = Cmnd->host; + host = Cmnd->device->host; hostdata = (struct isp1020_hostdata *) host->hostdata; for (i = 0; i < QLOGICISP_REQ_QUEUE_LEN + 1; i++) @@ -1186,7 +1186,7 @@ isp1020_disable_irqs(host); param[0] = MBOX_ABORT; - param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun; + param[1] = (((u_short) Cmnd->device->id) << 8) | Cmnd->device->lun; param[2] = cmd_cookie >> 16; param[3] = cmd_cookie & 0xffff; @@ -1214,7 +1214,7 @@ ENTER("isp1020_reset"); - host = Cmnd->host; + host = Cmnd->device->host; hostdata = (struct isp1020_hostdata *) host->hostdata; param[0] = MBOX_BUS_RESET; diff -Nru a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c --- a/drivers/scsi/qlogicpti.c Sun Feb 9 21:13:34 2003 +++ b/drivers/scsi/qlogicpti.c Sun Feb 9 21:13:34 2003 @@ -1004,16 +1004,16 @@ memset(cmd, 0, sizeof(struct Command_Entry)); cmd->hdr.entry_cnt = 1; cmd->hdr.entry_type = ENTRY_COMMAND; - cmd->target_id = Cmnd->target; - cmd->target_lun = Cmnd->lun; + cmd->target_id = Cmnd->device->id; + cmd->target_lun = Cmnd->device->lun; cmd->cdb_length = Cmnd->cmd_len; cmd->control_flags = 0; if (Cmnd->device->tagged_supported) { - if (qpti->cmd_count[Cmnd->target] == 0) - qpti->tag_ages[Cmnd->target] = jiffies; - if ((jiffies - qpti->tag_ages[Cmnd->target]) > (5*HZ)) { + if (qpti->cmd_count[Cmnd->device->id] == 0) + qpti->tag_ages[Cmnd->device->id] = jiffies; + if ((jiffies - qpti->tag_ages[Cmnd->device->id]) > (5*HZ)) { cmd->control_flags = CFLAG_ORDERED_TAG; - qpti->tag_ages[Cmnd->target] = jiffies; + qpti->tag_ages[Cmnd->device->id] = jiffies; } else cmd->control_flags = CFLAG_SIMPLE_TAG; } @@ -1097,7 +1097,7 @@ cmd->handle = in_ptr; qpti->cmd_slots[in_ptr] = Cmnd; - qpti->cmd_count[Cmnd->target]++; + qpti->cmd_count[Cmnd->device->id]++; sbus_writew(in_ptr, qpti->qregs + MBOX4); qpti->req_in_ptr = in_ptr; @@ -1118,8 +1118,8 @@ */ static void ourdone(Scsi_Cmnd *Cmnd) { - struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->host->hostdata; - int tgt = Cmnd->target; + struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata; + int tgt = Cmnd->device->id; void (*done) (Scsi_Cmnd *); /* This grot added by DaveM, blame him for ugliness. @@ -1170,7 +1170,7 @@ static int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)) { - struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->host->hostdata; + struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata; unsigned long flags; /* @@ -1229,7 +1229,7 @@ * and can rock on.. */ if (qpti == NULL) - Cmnd->host->hostt->queuecommand = qlogicpti_queuecommand; + Cmnd->device->host->hostt->queuecommand = qlogicpti_queuecommand; spin_unlock_irqrestore(&qpti->lock, flags); @@ -1246,7 +1246,7 @@ */ static int qlogicpti_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)) { - struct Scsi_Host *host = Cmnd->host; + struct Scsi_Host *host = Cmnd->device->host; struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; struct Command_Entry *cmd; unsigned long flags; @@ -1431,7 +1431,7 @@ Cmnd->request_bufflen, scsi_to_sbus_dma_dir(Cmnd->sc_data_direction)); } - qpti->cmd_count[Cmnd->target]--; + qpti->cmd_count[Cmnd->device->id]--; sbus_writew(out_ptr, qpti->qregs + MBOX5); Cmnd->host_scribble = (unsigned char *) done_queue; done_queue = Cmnd; @@ -1468,7 +1468,7 @@ static int qlogicpti_abort(Scsi_Cmnd *Cmnd) { u_short param[6]; - struct Scsi_Host *host = Cmnd->host; + struct Scsi_Host *host = Cmnd->device->host; struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; int return_status = SUCCESS; unsigned long flags; @@ -1476,7 +1476,7 @@ int i; printk(KERN_WARNING "qlogicpti : Aborting cmd for tgt[%d] lun[%d]\n", - (int)Cmnd->target, (int)Cmnd->lun); + (int)Cmnd->device->id, (int)Cmnd->device->lun); spin_lock_irqsave(&qpti->lock, flags); @@ -1491,7 +1491,7 @@ cmd_cookie = i; param[0] = MBOX_ABORT; - param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun; + param[1] = (((u_short) Cmnd->device->id) << 8) | Cmnd->device->lun; param[2] = cmd_cookie >> 16; param[3] = cmd_cookie & 0xffff; if (qlogicpti_mbox_command(qpti, param, 0) || @@ -1510,7 +1510,7 @@ static int qlogicpti_reset(Scsi_Cmnd *Cmnd) { u_short param[6]; - struct Scsi_Host *host = Cmnd->host; + struct Scsi_Host *host = Cmnd->device->host; struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; int return_status = SUCCESS; unsigned long flags; diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c --- a/drivers/scsi/scsi.c Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/scsi.c Sun Feb 9 21:13:32 2003 @@ -145,7 +145,6 @@ * Function prototypes. */ extern void scsi_times_out(Scsi_Cmnd * SCpnt); -void scsi_build_commandblocks(Scsi_Device * SDpnt); #ifdef MODULE MODULE_PARM(scsi_logging_level, "i"); @@ -196,14 +195,6 @@ } /* - * This lock protects the freelist for all devices on the system. - * We could make this finer grained by having a single lock per - * device if it is ever found that there is excessive contention - * on this lock. - */ -static spinlock_t device_request_lock = SPIN_LOCK_UNLOCKED; - -/* * Function: scsi_allocate_request * * Purpose: Allocate a request descriptor. @@ -265,7 +256,7 @@ { if( req->sr_command != NULL ) { - scsi_release_command(req->sr_command); + scsi_put_command(req->sr_command); req->sr_command = NULL; } @@ -273,235 +264,6 @@ } /* - * FIXME(eric) - this is not at all optimal. Given that - * single lun devices are rare and usually slow - * (i.e. CD changers), this is good enough for now, but - * we may want to come back and optimize this later. - * - * Scan through all of the devices attached to this - * host, and see if any are active or not. If so, - * we need to defer this command. - * - * We really need a busy counter per device. This would - * allow us to more easily figure out whether we should - * do anything here or not. - */ -static int check_all_luns(struct Scsi_Host *shost, struct scsi_device *myself) -{ - struct scsi_device *sdev; - - list_for_each_entry(sdev, &myself->same_target_siblings, - same_target_siblings) { - if (atomic_read(&sdev->device_active)) - return 1; - } - - return 0; -} - -/* - * Function: scsi_allocate_device - * - * Purpose: Allocate a command descriptor. - * - * Arguments: device - device for which we want a command descriptor - * wait - 1 if we should wait in the event that none - * are available. - * interruptible - 1 if we should unblock and return NULL - * in the event that we must wait, and a signal - * arrives. - * - * Lock status: No locks assumed to be held. This function is SMP-safe. - * - * Returns: Pointer to command descriptor. - * - * Notes: Prior to the new queue code, this function was not SMP-safe. - * - * If the wait flag is true, and we are waiting for a free - * command block, this function will interrupt and return - * NULL in the event that a signal arrives that needs to - * be handled. - * - * This function is deprecated, and drivers should be - * rewritten to use Scsi_Request instead of Scsi_Cmnd. - */ -struct scsi_cmnd *scsi_allocate_device(struct scsi_device *sdev, int wait) -{ - DECLARE_WAITQUEUE(wq, current); - struct Scsi_Host *shost = sdev->host; - struct scsi_cmnd *scmnd; - unsigned long flags; - - spin_lock_irqsave(&device_request_lock, flags); - while (1) { - if (sdev->device_blocked) - goto busy; - if (sdev->single_lun && check_all_luns(shost, sdev)) - goto busy; - - /* - * Now we can check for a free command block for this device. - */ - for (scmnd = sdev->device_queue; scmnd; scmnd = scmnd->next) - if (!scmnd->request) - goto found; - -busy: - if (!wait) - goto fail; - - /* - * We need to wait for a free commandblock. We need to - * insert ourselves into the list before we release the - * lock. This way if a block were released the same - * microsecond that we released the lock, the call - * to schedule() wouldn't block (well, it might switch, - * but the current task will still be schedulable. - */ - add_wait_queue(&sdev->scpnt_wait, &wq); - set_current_state(TASK_UNINTERRUPTIBLE); - - spin_unlock_irqrestore(&device_request_lock, flags); - schedule(); - spin_lock_irqsave(&device_request_lock, flags); - - remove_wait_queue(&sdev->scpnt_wait, &wq); - set_current_state(TASK_RUNNING); - } - -found: - scmnd->request = NULL; - atomic_inc(&scmnd->host->host_active); - atomic_inc(&scmnd->device->device_active); - - scmnd->buffer = NULL; - scmnd->bufflen = 0; - scmnd->request_buffer = NULL; - scmnd->request_bufflen = 0; - - scmnd->use_sg = 0; /* Reset the scatter-gather flag */ - scmnd->old_use_sg = 0; - scmnd->transfersize = 0; /* No default transfer size */ - scmnd->cmd_len = 0; - - scmnd->sc_data_direction = SCSI_DATA_UNKNOWN; - scmnd->sc_request = NULL; - scmnd->sc_magic = SCSI_CMND_MAGIC; - - scmnd->result = 0; - scmnd->underflow = 0; /* Do not flag underflow conditions */ - scmnd->old_underflow = 0; - scmnd->resid = 0; - scmnd->state = SCSI_STATE_INITIALIZING; - scmnd->owner = SCSI_OWNER_HIGHLEVEL; - - spin_unlock_irqrestore(&device_request_lock, flags); - - SCSI_LOG_MLQUEUE(5, printk("Activating command for device %d (%d)\n", - scmnd->target, - atomic_read(&scmnd->host->host_active))); - - return scmnd; - -fail: - spin_unlock_irqrestore(&device_request_lock, flags); - return NULL; -} - -inline void __scsi_release_command(Scsi_Cmnd * SCpnt) -{ - unsigned long flags; - Scsi_Device * SDpnt; - int alloc_cmd = 0; - - spin_lock_irqsave(&device_request_lock, flags); - - SDpnt = SCpnt->device; - - SCpnt->request = NULL; - SCpnt->state = SCSI_STATE_UNUSED; - SCpnt->owner = SCSI_OWNER_NOBODY; - atomic_dec(&SCpnt->host->host_active); - atomic_dec(&SDpnt->device_active); - - SCSI_LOG_MLQUEUE(5, printk("Deactivating command for device %d (active=%d, failed=%d)\n", - SCpnt->target, - atomic_read(&SCpnt->host->host_active), - SCpnt->host->host_failed)); - - if(SDpnt->current_queue_depth > SDpnt->new_queue_depth) { - Scsi_Cmnd *prev, *next; - /* - * Release the command block and decrement the queue - * depth. - */ - for(prev = NULL, next = SDpnt->device_queue; - next != SCpnt; - prev = next, next = next->next) ; - if(prev == NULL) - SDpnt->device_queue = next->next; - else - prev->next = next->next; - kfree((char *)SCpnt); - SDpnt->current_queue_depth--; - } else if(SDpnt->current_queue_depth < SDpnt->new_queue_depth) { - alloc_cmd = 1; - SDpnt->current_queue_depth++; - } - spin_unlock_irqrestore(&device_request_lock, flags); - - /* - * Wake up anyone waiting for this device. Do this after we - * have released the lock, as they will need it as soon as - * they wake up. - */ - wake_up(&SDpnt->scpnt_wait); - - /* - * We are happy to release command blocks in the scope of the - * device_request_lock since that's nice and quick, but allocation - * can take more time so do it outside that scope instead. - */ - if(alloc_cmd) { - Scsi_Cmnd *newSCpnt; - - newSCpnt = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC | - (SDpnt->host->unchecked_isa_dma ? - GFP_DMA : 0)); - if(newSCpnt) { - memset(newSCpnt, 0, sizeof(Scsi_Cmnd)); - init_timer(&newSCpnt->eh_timeout); - newSCpnt->host = SDpnt->host; - newSCpnt->device = SDpnt; - newSCpnt->target = SDpnt->id; - newSCpnt->lun = SDpnt->lun; - newSCpnt->channel = SDpnt->channel; - newSCpnt->request = NULL; - newSCpnt->use_sg = 0; - newSCpnt->old_use_sg = 0; - newSCpnt->old_cmd_len = 0; - newSCpnt->underflow = 0; - newSCpnt->old_underflow = 0; - newSCpnt->transfersize = 0; - newSCpnt->resid = 0; - newSCpnt->serial_number = 0; - newSCpnt->serial_number_at_timeout = 0; - newSCpnt->host_scribble = NULL; - newSCpnt->state = SCSI_STATE_UNUSED; - newSCpnt->owner = SCSI_OWNER_NOBODY; - spin_lock_irqsave(&device_request_lock, flags); - newSCpnt->next = SDpnt->device_queue; - SDpnt->device_queue = newSCpnt; - spin_unlock_irqrestore(&device_request_lock, flags); - } else { - spin_lock_irqsave(&device_request_lock, flags); - SDpnt->current_queue_depth--; - spin_unlock_irqrestore(&device_request_lock, flags); - } - } -} - -/* * Function: scsi_mlqueue_insert() * * Purpose: Insert a command in the midlevel queue. @@ -520,9 +282,9 @@ * Notes: This could be called either from an interrupt context or a * normal process context. */ -int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason) +static int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason) { - struct Scsi_Host *host = cmd->host; + struct Scsi_Host *host = cmd->device->host; struct scsi_device *device = cmd->device; SCSI_LOG_MLQUEUE(1, @@ -582,43 +344,190 @@ return 0; } +struct scsi_host_cmd_pool { + kmem_cache_t *slab; + unsigned int users; + char *name; + unsigned int slab_flags; + unsigned int gfp_mask; +}; + +static struct scsi_host_cmd_pool scsi_cmd_pool = { + .name = "scsi_cmd_cache", + .slab_flags = SLAB_HWCACHE_ALIGN, +}; + +static struct scsi_host_cmd_pool scsi_cmd_dma_pool = { + .name = "scsi_cmd_cache(DMA)", + .slab_flags = SLAB_HWCACHE_ALIGN|SLAB_CACHE_DMA, + .gfp_mask = __GFP_DMA, +}; + +static DECLARE_MUTEX(host_cmd_pool_mutex); + +static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, + int gfp_mask) +{ + struct scsi_cmnd *cmd; + + cmd = kmem_cache_alloc(shost->cmd_pool->slab, + gfp_mask | shost->cmd_pool->gfp_mask); + + if (unlikely(!cmd)) { + unsigned long flags; + + spin_lock_irqsave(&shost->free_list_lock, flags); + if (likely(!list_empty(&shost->free_list))) { + cmd = list_entry(shost->free_list.next, + struct scsi_cmnd, list); + list_del_init(&cmd->list); + } + spin_unlock_irqrestore(&shost->free_list_lock, flags); + } + + return cmd; +} + /* - * Function: scsi_release_command + * Function: scsi_get_command() * - * Purpose: Release a command block. + * Purpose: Allocate and setup a scsi command block * - * Arguments: SCpnt - command block we are releasing. + * Arguments: dev - parent scsi device + * gfp_mask- allocator flags * - * Notes: The command block can no longer be used by the caller once - * this funciton is called. This is in effect the inverse - * of scsi_allocate_device. Note that we also must perform - * a couple of additional tasks. We must first wake up any - * processes that might have blocked waiting for a command - * block, and secondly we must hit the queue handler function - * to make sure that the device is busy. Note - there is an - * option to not do this - there were instances where we could - * recurse too deeply and blow the stack if this happened - * when we were indirectly called from the request function - * itself. - * - * The idea is that a lot of the mid-level internals gunk - * gets hidden in this function. Upper level drivers don't - * have any chickens to wave in the air to get things to - * work reliably. + * Returns: The allocated scsi command structure. + */ +struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int gfp_mask) +{ + struct scsi_cmnd *cmd = __scsi_get_command(dev->host, gfp_mask); + + if (likely(cmd != NULL)) { + unsigned long flags; + + memset(cmd, 0, sizeof(*cmd)); + cmd->device = dev; + cmd->state = SCSI_STATE_UNUSED; + cmd->owner = SCSI_OWNER_NOBODY; + init_timer(&cmd->eh_timeout); + INIT_LIST_HEAD(&cmd->list); + spin_lock_irqsave(&dev->list_lock, flags); + list_add_tail(&cmd->list, &dev->cmd_list); + spin_unlock_irqrestore(&dev->list_lock, flags); + } + + return cmd; +} + +/* + * Function: scsi_put_command() + * + * Purpose: Free a scsi command block * - * This function is deprecated, and drivers should be - * rewritten to use Scsi_Request instead of Scsi_Cmnd. + * Arguments: cmd - command block to free + * + * Returns: Nothing. + * + * Notes: The command must not belong to any lists. */ -void scsi_release_command(Scsi_Cmnd * SCpnt) +void scsi_put_command(struct scsi_cmnd *cmd) { - __scsi_release_command(SCpnt); - /* - * Finally, hit the queue request function to make sure that - * the device is actually busy if there are requests present. - * This won't block - if the device cannot take any more, life - * will go on. - */ - scsi_queue_next_request(SCpnt->device->request_queue, NULL); + struct Scsi_Host *shost = cmd->device->host; + unsigned long flags; + + /* serious error if the command hasn't come from a device list */ + spin_lock_irqsave(&cmd->device->list_lock, flags); + BUG_ON(list_empty(&cmd->list)); + list_del_init(&cmd->list); + spin_unlock(&cmd->device->list_lock); + /* changing locks here, don't need to restore the irq state */ + spin_lock(&shost->free_list_lock); + if (unlikely(list_empty(&shost->free_list))) { + list_add(&cmd->list, &shost->free_list); + cmd = NULL; + } + spin_unlock_irqrestore(&shost->free_list_lock, flags); + + if (likely(cmd != NULL)) + kmem_cache_free(shost->cmd_pool->slab, cmd); +} + +/* + * Function: scsi_setup_command_freelist() + * + * Purpose: Setup the command freelist for a scsi host. + * + * Arguments: shost - host to allocate the freelist for. + * + * Returns: Nothing. + */ +int scsi_setup_command_freelist(struct Scsi_Host *shost) +{ + struct scsi_host_cmd_pool *pool; + struct scsi_cmnd *cmd; + + spin_lock_init(&shost->free_list_lock); + INIT_LIST_HEAD(&shost->free_list); + + /* + * Select a command slab for this host and create it if not + * yet existant. + */ + down(&host_cmd_pool_mutex); + pool = (shost->unchecked_isa_dma ? &scsi_cmd_dma_pool : &scsi_cmd_pool); + if (!pool->users) { + pool->slab = kmem_cache_create(pool->name, + sizeof(struct scsi_cmnd), 0, + pool->slab_flags, NULL, NULL); + if (!pool->slab) + goto fail; + } + + pool->users++; + shost->cmd_pool = pool; + up(&host_cmd_pool_mutex); + + /* + * Get one backup command for this host. + */ + cmd = kmem_cache_alloc(shost->cmd_pool->slab, + GFP_KERNEL | shost->cmd_pool->gfp_mask); + if (!cmd) + goto fail2; + list_add(&cmd->list, &shost->free_list); + return 0; + + fail2: + if (!--pool->users) + kmem_cache_destroy(pool->slab); + return -ENOMEM; + fail: + up(&host_cmd_pool_mutex); + return -ENOMEM; + +} + +/* + * Function: scsi_destroy_command_freelist() + * + * Purpose: Release the command freelist for a scsi host. + * + * Arguments: shost - host that's freelist is going to be destroyed + */ +void scsi_destroy_command_freelist(struct Scsi_Host *shost) +{ + while (!list_empty(&shost->free_list)) { + struct scsi_cmnd *cmd; + + cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list); + list_del_init(&cmd->list); + kmem_cache_free(shost->cmd_pool->slab, cmd); + } + + down(&host_cmd_pool_mutex); + if (!--shost->cmd_pool->users) + kmem_cache_destroy(shost->cmd_pool->slab); + up(&host_cmd_pool_mutex); } /* @@ -649,7 +558,7 @@ #endif #endif - host = SCpnt->host; + host = SCpnt->device->host; ASSERT_LOCK(host->host_lock, 0); @@ -663,7 +572,7 @@ */ if (SCpnt->device->scsi_level <= SCSI_2) SCpnt->cmnd[1] = (SCpnt->cmnd[1] & 0x1f) | - (SCpnt->lun << 5 & 0xe0); + (SCpnt->device->lun << 5 & 0xe0); /* * We will wait MIN_RESET_DELAY clock ticks after the last reset so @@ -695,7 +604,7 @@ */ SCSI_LOG_MLQUEUE(3, printk("scsi_dispatch_cmnd (host = %d, channel = %d, target = %d, " "command = %p, buffer = %p, \nbufflen = %d, done = %p)\n", - SCpnt->host->host_no, SCpnt->channel, SCpnt->target, SCpnt->cmnd, + SCpnt->device->host->host_no, SCpnt->device->channel, SCpnt->device->id, SCpnt->cmnd, SCpnt->buffer, SCpnt->bufflen, SCpnt->done)); SCpnt->state = SCSI_STATE_QUEUED; @@ -707,7 +616,7 @@ * Before we queue this command, check if the command * length exceeds what the host adapter can handle. */ - if (CDB_SIZE(SCpnt) <= SCpnt->host->max_cmd_len) { + if (CDB_SIZE(SCpnt) <= SCpnt->device->host->max_cmd_len) { spin_lock_irqsave(host->host_lock, flags); rtn = host->hostt->queuecommand(SCpnt, scsi_done); spin_unlock_irqrestore(host->host_lock, flags); @@ -750,13 +659,6 @@ return rtn; } -/* - * scsi_do_cmd sends all the commands out to the low-level driver. It - * handles the specifics required for each low level driver - ie queued - * or non queued. It also prevents conflicts when different high level - * drivers go for the same host at the same time. - */ - void scsi_wait_req (Scsi_Request * SRpnt, const void *cmnd , void *buffer, unsigned bufflen, int timeout, int retries) @@ -772,7 +674,7 @@ SRpnt->sr_request->waiting = NULL; if( SRpnt->sr_command != NULL ) { - scsi_release_command(SRpnt->sr_command); + scsi_put_command(SRpnt->sr_command); SRpnt->sr_command = NULL; } @@ -816,12 +718,11 @@ SCSI_LOG_MLQUEUE(4, { int i; - int target = SDpnt->id; int size = COMMAND_SIZE(((const unsigned char *)cmnd)[0]); printk("scsi_do_req (host = %d, channel = %d target = %d, " "buffer =%p, bufflen = %d, done = %p, timeout = %d, " "retries = %d)\n" - "command : ", host->host_no, SDpnt->channel, target, buffer, + "command : ", host->host_no, SDpnt->channel, SDpnt->id, buffer, bufflen, done, timeout, retries); for (i = 0; i < size; ++i) printk("%02x ", ((unsigned char *) cmnd)[i]); @@ -839,7 +740,7 @@ */ if( SRpnt->sr_command != NULL ) { - scsi_release_command(SRpnt->sr_command); + scsi_put_command(SRpnt->sr_command); SRpnt->sr_command = NULL; } @@ -906,7 +807,7 @@ */ void scsi_init_cmd_from_req(Scsi_Cmnd * SCpnt, Scsi_Request * SRpnt) { - struct Scsi_Host *host = SCpnt->host; + struct Scsi_Host *host = SCpnt->device->host; ASSERT_LOCK(host->host_lock, 0); @@ -965,121 +866,6 @@ SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_init_cmd_from_req()\n")); } -/* - * Function: scsi_do_cmd - * - * Purpose: Queue a SCSI command - * - * Arguments: SCpnt - command descriptor. - * cmnd - actual SCSI command to be performed. - * buffer - data buffer. - * bufflen - size of data buffer. - * done - completion function to be run. - * timeout - how long to let it run before timeout. - * retries - number of retries we allow. - * - * Lock status: With the new queueing code, this is SMP-safe, and no locks - * need be held upon entry. The old queueing code the lock was - * assumed to be held upon entry. - * - * Returns: Nothing. - * - * Notes: Prior to the new queue code, this function was not SMP-safe. - * Also, this function is now only used for queueing requests - * for things like ioctls and character device requests - this - * is because we essentially just inject a request into the - * queue for the device. Normal block device handling manipulates - * the queue directly. - */ -void scsi_do_cmd(Scsi_Cmnd * SCpnt, const void *cmnd, - void *buffer, unsigned bufflen, void (*done) (Scsi_Cmnd *), - int timeout, int retries) -{ - struct Scsi_Host *host = SCpnt->host; - - ASSERT_LOCK(host->host_lock, 0); - - SCpnt->pid = scsi_pid++; - SCpnt->owner = SCSI_OWNER_MIDLEVEL; - - SCSI_LOG_MLQUEUE(4, - { - int i; - int target = SCpnt->target; - int size = COMMAND_SIZE(((const unsigned char *)cmnd)[0]); - printk("scsi_do_cmd (host = %d, channel = %d target = %d, " - "buffer =%p, bufflen = %d, done = %p, timeout = %d, " - "retries = %d)\n" - "command : ", host->host_no, SCpnt->channel, target, buffer, - bufflen, done, timeout, retries); - for (i = 0; i < size; ++i) - printk("%02x ", ((unsigned char *) cmnd)[i]); - printk("\n"); - }); - - if (!host) { - panic("Invalid or not present host.\n"); - } - /* - * We must prevent reentrancy to the lowlevel host driver. This prevents - * it - we enter a loop until the host we want to talk to is not busy. - * Race conditions are prevented, as interrupts are disabled in between the - * time we check for the host being not busy, and the time we mark it busy - * ourselves. - */ - - - /* - * Our own function scsi_done (which marks the host as not busy, disables - * the timeout counter, etc) will be called by us or by the - * scsi_hosts[host].queuecommand() function needs to also call - * the completion function for the high level driver. - */ - - memcpy((void *) SCpnt->data_cmnd, (const void *) cmnd, - sizeof(SCpnt->data_cmnd)); - SCpnt->reset_chain = NULL; - SCpnt->serial_number = 0; - SCpnt->serial_number_at_timeout = 0; - SCpnt->bufflen = bufflen; - SCpnt->buffer = buffer; - SCpnt->flags = 0; - SCpnt->retries = 0; - SCpnt->allowed = retries; - SCpnt->done = done; - SCpnt->timeout_per_command = timeout; - - memcpy((void *) SCpnt->cmnd, (const void *) cmnd, - sizeof(SCpnt->cmnd)); - /* Zero the sense buffer. Some host adapters automatically request - * sense on error. 0 is not a valid sense code. - */ - memset((void *) SCpnt->sense_buffer, 0, sizeof SCpnt->sense_buffer); - SCpnt->request_buffer = buffer; - SCpnt->request_bufflen = bufflen; - SCpnt->old_use_sg = SCpnt->use_sg; - if (SCpnt->cmd_len == 0) - SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]); - SCpnt->old_cmd_len = SCpnt->cmd_len; - SCpnt->sc_old_data_direction = SCpnt->sc_data_direction; - SCpnt->old_underflow = SCpnt->underflow; - - /* Start the timer ticking. */ - - SCpnt->internal_timeout = NORMAL_TIMEOUT; - SCpnt->abort_reason = 0; - SCpnt->result = 0; - - /* - * At this point, we merely set up the command, stick it in the normal - * request queue, and return. Eventually that request will come to the - * top of the list, and will be dispatched. - */ - scsi_insert_special_cmd(SCpnt, 0); - - SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_do_cmd()\n")); -} - /** * scsi_done - Mark this command as done * @SCpnt: The SCSI Command which we think we've completed. @@ -1180,8 +966,8 @@ /* * Add to BH queue. */ - SCSI_LOG_MLCOMPLETE(3, printk("Command finished %d %d 0x%x\n", SCpnt->host->host_busy, - SCpnt->host->host_failed, + SCSI_LOG_MLCOMPLETE(3, printk("Command finished %d %d 0x%x\n", SCpnt->device->host->host_busy, + SCpnt->device->host->host_failed, SCpnt->result)); scsi_finish_command(SCpnt); @@ -1194,8 +980,8 @@ * track of the number of tries, so we don't * end up looping, of course. */ - SCSI_LOG_MLCOMPLETE(3, printk("Command needs retry %d %d 0x%x\n", SCpnt->host->host_busy, - SCpnt->host->host_failed, SCpnt->result)); + SCSI_LOG_MLCOMPLETE(3, printk("Command needs retry %d %d 0x%x\n", SCpnt->device->host->host_busy, + SCpnt->device->host->host_failed, SCpnt->result)); scsi_retry_command(SCpnt); break; @@ -1219,11 +1005,11 @@ * Here we have a fatal error of some sort. * Turn it over to the error handler. */ - SCSI_LOG_MLCOMPLETE(3, printk("Command failed %p %x active=%d busy=%d failed=%d\n", - SCpnt, SCpnt->result, - atomic_read(&SCpnt->host->host_active), - SCpnt->host->host_busy, - SCpnt->host->host_failed)); + SCSI_LOG_MLCOMPLETE(3, + printk("Command failed %p %x busy=%d failed=%d\n", + SCpnt, SCpnt->result, + SCpnt->device->host->host_busy, + SCpnt->device->host->host_failed)); /* * Dump the sense information too. @@ -1231,12 +1017,12 @@ if ((status_byte(SCpnt->result) & CHECK_CONDITION) != 0) { SCSI_LOG_MLCOMPLETE(3, print_sense("bh", SCpnt)); } - if (SCpnt->host->eh_wait != NULL) { + if (SCpnt->device->host->eh_wait != NULL) { scsi_eh_eflags_set(SCpnt, SCSI_EH_CMD_FAILED | SCSI_EH_CMD_ERR); SCpnt->owner = SCSI_OWNER_ERROR_HANDLER; SCpnt->state = SCSI_STATE_FAILED; - scsi_host_failed_inc_and_test(SCpnt->host); + scsi_host_failed_inc_and_test(SCpnt->device->host); } else { /* * We only get here if the error @@ -1288,7 +1074,7 @@ Scsi_Device *device; Scsi_Request * SRpnt; - host = SCpnt->host; + host = SCpnt->device->host; device = SCpnt->device; ASSERT_LOCK(host->host_lock, 0); @@ -1345,98 +1131,6 @@ } /* - * Function: scsi_release_commandblocks() - * - * Purpose: Release command blocks associated with a device. - * - * Arguments: SDpnt - device - * - * Returns: Nothing - * - * Lock status: No locking assumed or required. - * - * Notes: - */ -void scsi_release_commandblocks(Scsi_Device * SDpnt) -{ - Scsi_Cmnd *SCpnt, *SCnext; - unsigned long flags; - - spin_lock_irqsave(&device_request_lock, flags); - for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCnext) { - SDpnt->device_queue = SCnext = SCpnt->next; - kfree((char *) SCpnt); - } - SDpnt->current_queue_depth = 0; - SDpnt->new_queue_depth = 0; - spin_unlock_irqrestore(&device_request_lock, flags); -} - -/* - * Function: scsi_build_commandblocks() - * - * Purpose: Allocate command blocks associated with a device. - * - * Arguments: SDpnt - device - * - * Returns: Nothing - * - * Lock status: No locking assumed or required. - * - * Notes: We really only allocate one command here. We will allocate - * more commands as needed once the device goes into real use. - */ -void scsi_build_commandblocks(Scsi_Device * SDpnt) -{ - unsigned long flags; - Scsi_Cmnd *SCpnt; - - if (SDpnt->current_queue_depth != 0) - return; - - SCpnt = (Scsi_Cmnd *) kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC | - (SDpnt->host->unchecked_isa_dma ? GFP_DMA : 0)); - if (NULL == SCpnt) { - /* - * Since we don't currently have *any* command blocks on this - * device, go ahead and try an atomic allocation... - */ - SCpnt = (Scsi_Cmnd *) kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC | - (SDpnt->host->unchecked_isa_dma ? GFP_DMA : 0)); - if (NULL == SCpnt) - return; /* Oops, we aren't going anywhere for now */ - } - - memset(SCpnt, 0, sizeof(Scsi_Cmnd)); - init_timer(&SCpnt->eh_timeout); - SCpnt->host = SDpnt->host; - SCpnt->device = SDpnt; - SCpnt->target = SDpnt->id; - SCpnt->lun = SDpnt->lun; - SCpnt->channel = SDpnt->channel; - SCpnt->request = NULL; - SCpnt->use_sg = 0; - SCpnt->old_use_sg = 0; - SCpnt->old_cmd_len = 0; - SCpnt->underflow = 0; - SCpnt->old_underflow = 0; - SCpnt->transfersize = 0; - SCpnt->resid = 0; - SCpnt->serial_number = 0; - SCpnt->serial_number_at_timeout = 0; - SCpnt->host_scribble = NULL; - SCpnt->state = SCSI_STATE_UNUSED; - SCpnt->owner = SCSI_OWNER_NOBODY; - spin_lock_irqsave(&device_request_lock, flags); - if(SDpnt->new_queue_depth == 0) - SDpnt->new_queue_depth = 1; - SDpnt->current_queue_depth++; - SCpnt->next = SDpnt->device_queue; - SDpnt->device_queue = SCpnt; - spin_unlock_irqrestore(&device_request_lock, flags); -} - -/* * Function: scsi_adjust_queue_depth() * * Purpose: Allow low level drivers to tell us to change the queue depth @@ -1457,28 +1151,10 @@ * the right thing depending on whether or not the device is * currently active and whether or not it even has the * command blocks built yet. - * - * If cmdblocks != 0 then we are a live device. We just set the - * new_queue_depth variable and when the scsi completion handler - * notices that current_queue_depth != new_queue_depth it will - * work to rectify the situation. If new_queue_depth is less than - * current_queue_depth, then it will free the completed command - * instead of putting it back on the free list and dec - * current_queue_depth. Otherwise it will try to allocate a new - * command block for the device and put it on the free list along - * with the command that is being - * completed. Obviously, if the device isn't doing anything then - * neither is this code, so it will bring the devices queue depth - * back into line when the device is actually being used. This - * keeps us from needing to fire off a kernel thread or some such - * nonsense (this routine can be called from interrupt code, so - * handling allocations here would be tricky and risky, making - * a kernel thread a much safer way to go if we wanted to handle - * the work immediately instead of letting it get done a little - * at a time in the completion handler). */ void scsi_adjust_queue_depth(Scsi_Device *SDpnt, int tagged, int tags) { + static spinlock_t device_request_lock = SPIN_LOCK_UNLOCKED; unsigned long flags; /* @@ -1495,7 +1171,7 @@ return; spin_lock_irqsave(&device_request_lock, flags); - SDpnt->new_queue_depth = tags; + SDpnt->queue_depth = tags; switch(tagged) { case MSG_ORDERED_TAG: SDpnt->ordered_tags = 1; @@ -1512,7 +1188,7 @@ SDpnt->channel, SDpnt->id, SDpnt->lun); case 0: SDpnt->ordered_tags = SDpnt->simple_tags = 0; - SDpnt->new_queue_depth = tags; + SDpnt->queue_depth = tags; break; } spin_unlock_irqrestore(&device_request_lock, flags); @@ -1863,28 +1539,6 @@ */ int scsi_slave_attach(struct scsi_device *sdev) { - /* all this code is now handled elsewhere - if (sdev->attached++ == 0) { - scsi_build_commandblocks(sdev); - if (sdev->current_queue_depth == 0) { - printk(KERN_ERR "scsi: Allocation failure during" - " attach, some SCSI devices might not be" - " configured\n"); - return -ENOMEM; - } - if (sdev->host->hostt->slave_configure != NULL) { - if (sdev->host->hostt->slave_configure(sdev) != 0) { - printk(KERN_INFO "scsi: failed low level driver" - " attach, some SCSI device might not be" - " configured\n"); - scsi_release_commandblocks(sdev); - return -ENOMEM; - } - } else if (sdev->host->cmd_per_lun != 0) - scsi_adjust_queue_depth(sdev, 0, - sdev->host->cmd_per_lun); - } - */ sdev->attached++; return 0; } @@ -1901,11 +1555,6 @@ */ void scsi_slave_detach(struct scsi_device *sdev) { - /* - if (--sdev->attached == 0) { - scsi_release_commandblocks(sdev); - } - */ sdev->attached--; } /* @@ -1955,17 +1604,16 @@ { Scsi_Device *SDpnt; struct Scsi_Host *shpnt; - /* * Next, detach the devices from the driver. */ - for (shpnt = scsi_host_get_next(NULL); shpnt; shpnt = scsi_host_get_next(shpnt)) { list_for_each_entry(SDpnt, &shpnt->my_devices, siblings) (*tpnt->detach) (SDpnt); } + /* * Extract the template from the linked list. */ @@ -1974,11 +1622,6 @@ up_write(&scsi_devicelist_mutex); scsi_upper_driver_unregister(tpnt); - - /* - * Final cleanup for the driver is done in the driver sources in the - * cleanup function. - */ return 0; } @@ -2021,10 +1664,9 @@ #endif +/* FIXME(hch): add proper error handling */ static int __init init_scsi(void) { - printk(KERN_INFO "SCSI subsystem driver " REVISION "\n"); - scsi_init_queue(); scsi_init_procfs(); devfs_mk_dir(NULL, "scsi", NULL); diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h --- a/drivers/scsi/scsi.h Sun Feb 9 21:13:30 2003 +++ b/drivers/scsi/scsi.h Sun Feb 9 21:13:30 2003 @@ -446,8 +446,10 @@ * Prototypes for functions in scsi.c */ extern int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt); -extern void scsi_release_commandblocks(Scsi_Device * SDpnt); -extern void scsi_build_commandblocks(Scsi_Device * SDpnt); +extern int scsi_setup_command_freelist(struct Scsi_Host *shost); +extern void scsi_destroy_command_freelist(struct Scsi_Host *shost); +extern struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int flags); +extern void scsi_put_command(struct scsi_cmnd *cmd); extern void scsi_adjust_queue_depth(Scsi_Device *, int, int); extern int scsi_track_queue_full(Scsi_Device *, int); extern int scsi_slave_attach(struct scsi_device *); @@ -457,14 +459,6 @@ extern void scsi_done(Scsi_Cmnd * SCpnt); extern void scsi_finish_command(Scsi_Cmnd *); extern int scsi_retry_command(Scsi_Cmnd *); -extern Scsi_Cmnd *scsi_allocate_device(Scsi_Device *, int); -extern void __scsi_release_command(Scsi_Cmnd *); -extern void scsi_release_command(Scsi_Cmnd *); -extern void scsi_do_cmd(Scsi_Cmnd *, const void *cmnd, - void *buffer, unsigned bufflen, - void (*done) (struct scsi_cmnd *), - int timeout, int retries); -extern int scsi_mlqueue_insert(struct scsi_cmnd *, int); extern int scsi_attach_device(struct scsi_device *); extern void scsi_detach_device(struct scsi_device *); extern int scsi_get_device_flags(unsigned char *vendor, unsigned char *model); @@ -576,14 +570,11 @@ device is busy */ struct Scsi_Host *host; request_queue_t *request_queue; - atomic_t device_active; /* commands checked out for device */ volatile unsigned short device_busy; /* commands actually active on low-level */ - struct list_head free_cmnds; /* list of available Scsi_Cmnd structs */ - struct list_head busy_cmnds; /* list of Scsi_Cmnd structs in use */ - Scsi_Cmnd *device_queue; /* queue of SCSI Command structures */ + spinlock_t list_lock; + struct list_head cmd_list; /* queue of in use SCSI Command structures */ Scsi_Cmnd *current_cmnd; /* currently active command */ - unsigned short current_queue_depth;/* How deep of a queue we have */ - unsigned short new_queue_depth; /* How deep of a queue we want */ + unsigned short queue_depth; /* How deep of a queue we want */ unsigned short last_queue_full_depth; /* These two are used by */ unsigned short last_queue_full_count; /* scsi_track_queue_full() */ unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same @@ -728,14 +719,13 @@ struct scsi_cmnd { int sc_magic; - struct Scsi_Host *host; + struct scsi_device *device; unsigned short state; unsigned short owner; - Scsi_Device *device; Scsi_Request *sc_request; - struct scsi_cmnd *next; struct scsi_cmnd *reset_chain; - struct list_head list_entry; /* Used to place us on the cmd lists */ + + struct list_head list; /* scsi_cmnd participates in queue lists */ int eh_state; /* Used for state tracking in error handlr */ int eh_eflags; /* Used by error handlr */ @@ -770,10 +760,6 @@ unsigned volatile char internal_timeout; struct scsi_cmnd *bh_next; /* To enumerate the commands waiting to be processed. */ - - unsigned int target; - unsigned int lun; - unsigned int channel; unsigned char cmd_len; unsigned char old_cmd_len; unsigned char sc_data_direction; @@ -990,4 +976,4 @@ extern int scsi_sysfs_register(void); extern void scsi_sysfs_unregister(void); -#endif +#endif /* _SCSI_H */ diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c --- a/drivers/scsi/scsi_debug.c Sun Feb 9 21:13:33 2003 +++ b/drivers/scsi/scsi_debug.c Sun Feb 9 21:13:33 2003 @@ -217,7 +217,7 @@ int block, upper_blk, num; unsigned char *buff; int errsts = 0; - int target = SCpnt->target; + int target = SCpnt->device->id; int bufflen = SCpnt->request_bufflen; unsigned long capac; struct sdebug_dev_info * devip = NULL; @@ -247,7 +247,7 @@ return schedule_resp(SCpnt, NULL, done, 0, 0); } - if (SCpnt->lun >= scsi_debug_max_luns) + if (SCpnt->device->lun >= scsi_debug_max_luns) return schedule_resp(SCpnt, NULL, done, DID_NO_CONNECT << 16, 0); devip = devInfoReg(SCpnt); @@ -868,19 +868,19 @@ return devip; for (k = 0; k < scsi_debug_num_devs; ++k) { devip = &devInfop[k]; - if ((devip->channel == scmd->channel) && - (devip->target == scmd->target) && - (devip->lun == scmd->lun) && - (devip->host == scmd->host)) + if ((devip->channel == scmd->device->channel) && + (devip->target == scmd->device->id) && + (devip->lun == scmd->device->lun) && + (devip->host == scmd->device->host)) return devip; } for (k = 0; k < scsi_debug_num_devs; ++k) { devip = &devInfop[k]; if (!devip->used) { - devip->channel = scmd->channel; - devip->target = scmd->target; - devip->lun = scmd->lun; - devip->host = scmd->host; + devip->channel = scmd->device->channel; + devip->target = scmd->device->id; + devip->lun = scmd->device->lun; + devip->host = scmd->device->host; devip->reset = 1; devip->used = 1; memset(devip->sense_buff, 0, SDEBUG_SENSE_LEN); @@ -962,7 +962,7 @@ if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) printk(KERN_INFO "scsi_debug: bus_reset\n"); ++num_bus_resets; - if (SCpnt && ((sdp = SCpnt->device)) && ((hp = SCpnt->host))) { + if (SCpnt && ((sdp = SCpnt->device)) && ((hp = SCpnt->device->host))) { for (k = 0; k < scsi_debug_num_devs; ++k) { if (hp == devInfop[k].host) devInfop[k].reset = 1; diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c --- a/drivers/scsi/scsi_error.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/scsi_error.c Sun Feb 9 21:13:28 2003 @@ -131,23 +131,22 @@ **/ void scsi_times_out(Scsi_Cmnd *scmd) { + struct Scsi_Host *shost = scmd->device->host; + /* Set the serial_number_at_timeout to the current serial_number */ scmd->serial_number_at_timeout = scmd->serial_number; scsi_eh_eflags_set(scmd, SCSI_EH_CMD_TIMEOUT | SCSI_EH_CMD_ERR); - if( scmd->host->eh_wait == NULL ) { + if (unlikely(shost->eh_wait == NULL)) { panic("Error handler thread not present at %p %p %s %d", - scmd, scmd->host, __FILE__, __LINE__); + scmd, shost, __FILE__, __LINE__); } - scsi_host_failed_inc_and_test(scmd->host); + scsi_host_failed_inc_and_test(shost); - SCSI_LOG_TIMEOUT(3, printk("Command timed out active=%d busy=%d " - " failed=%d\n", - atomic_read(&scmd->host->host_active), - scmd->host->host_busy, - scmd->host->host_failed)); + SCSI_LOG_TIMEOUT(3, printk("Command timed out busy=%d failed=%d\n", + shost->host_busy, shost->host_failed)); } /** @@ -234,7 +233,10 @@ found = 0; list_for_each_entry(sdev, &shost->my_devices, siblings) { - for (scmd = sdev->device_queue; scmd; scmd = scmd->next) { + unsigned long flags; + + spin_lock_irqsave(&sdev->list_lock, flags); + list_for_each_entry(scmd, &sdev->cmd_list, list) { if (scsi_eh_eflags_chk(scmd, SCSI_EH_CMD_ERR)) { scmd->bh_next = *sc_list; *sc_list = scmd; @@ -263,10 +265,11 @@ " cmds still active" " (%p %x %d)\n", scmd, scmd->state, - scmd->target)); + scmd->device->id)); } } } + spin_unlock_irqrestore(&sdev->list_lock, flags); } SCSI_LOG_ERROR_RECOVERY(1, scsi_eh_prt_fail_stats(*sc_list, shost)); @@ -426,8 +429,8 @@ SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd:%p\n", __FUNCTION__, scmd)); - if (scmd->host->eh_action != NULL) - up(scmd->host->eh_action); + if (scmd->device->host->eh_action != NULL) + up(scmd->device->host->eh_action); else printk("%s: eh_action NULL\n", __FUNCTION__); } @@ -458,8 +461,8 @@ SCSI_LOG_ERROR_RECOVERY(3, printk("%s scmd: %p result: %x\n", __FUNCTION__, scmd, scmd->result)); - if (scmd->host->eh_action != NULL) - up(scmd->host->eh_action); + if (scmd->device->host->eh_action != NULL) + up(scmd->device->host->eh_action); } /** @@ -477,7 +480,7 @@ static int scsi_send_eh_cmnd(Scsi_Cmnd *scmd, int timeout) { unsigned long flags; - struct Scsi_Host *host = scmd->host; + struct Scsi_Host *host = scmd->device->host; int rtn = SUCCESS; ASSERT_LOCK(host->host_lock, 0); @@ -490,7 +493,7 @@ if (scmd->device->scsi_level <= SCSI_2) scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | - (scmd->lun << 5 & 0xe0); + (scmd->device->lun << 5 & 0xe0); if (host->can_queue) { DECLARE_MUTEX_LOCKED(sem); @@ -500,16 +503,16 @@ /* * set up the semaphore so we wait for the command to complete. */ - scmd->host->eh_action = &sem; + scmd->device->host->eh_action = &sem; scmd->request->rq_status = RQ_SCSI_BUSY; - spin_lock_irqsave(scmd->host->host_lock, flags); + spin_lock_irqsave(scmd->device->host->host_lock, flags); host->hostt->queuecommand(scmd, scsi_eh_done); - spin_unlock_irqrestore(scmd->host->host_lock, flags); + spin_unlock_irqrestore(scmd->device->host->host_lock, flags); down(&sem); - scmd->host->eh_action = NULL; + scmd->device->host->eh_action = NULL; /* * see if timeout. if so, tell the host to forget about it. @@ -529,10 +532,10 @@ * abort a timed out command or not. not sure how * we should treat them differently anyways. */ - spin_lock_irqsave(scmd->host->host_lock, flags); - if (scmd->host->hostt->eh_abort_handler) - scmd->host->hostt->eh_abort_handler(scmd); - spin_unlock_irqrestore(scmd->host->host_lock, flags); + spin_lock_irqsave(scmd->device->host->host_lock, flags); + if (scmd->device->host->hostt->eh_abort_handler) + scmd->device->host->hostt->eh_abort_handler(scmd); + spin_unlock_irqrestore(scmd->device->host->host_lock, flags); scmd->request->rq_status = RQ_SCSI_DONE; scmd->owner = SCSI_OWNER_ERROR_HANDLER; @@ -600,7 +603,7 @@ memcpy((void *) scmd->cmnd, (void *) generic_sense, sizeof(generic_sense)); - scsi_result = (!scmd->host->hostt->unchecked_isa_dma) + scsi_result = (!scmd->device->host->hostt->unchecked_isa_dma) ? &scsi_result0[0] : kmalloc(512, GFP_ATOMIC | GFP_DMA); if (scsi_result == NULL) { @@ -732,7 +735,7 @@ SCSI_LOG_ERROR_RECOVERY(2, printk("%s: requesting sense" " for tgt: %d\n", - __FUNCTION__, scmd->target)); + __FUNCTION__, scmd->device->id)); rtn = scsi_request_sense(scmd); if (rtn != SUCCESS) continue; @@ -790,7 +793,7 @@ int rtn = FAILED; unsigned long flags; - if (scmd->host->hostt->eh_abort_handler == NULL) { + if (scmd->device->host->hostt->eh_abort_handler == NULL) { return rtn; } /* @@ -802,9 +805,9 @@ scmd->owner = SCSI_OWNER_LOWLEVEL; - spin_lock_irqsave(scmd->host->host_lock, flags); - rtn = scmd->host->hostt->eh_abort_handler(scmd); - spin_unlock_irqrestore(scmd->host->host_lock, flags); + spin_lock_irqsave(scmd->device->host->host_lock, flags); + rtn = scmd->device->host->hostt->eh_abort_handler(scmd); + spin_unlock_irqrestore(scmd->device->host->host_lock, flags); return rtn; } @@ -912,14 +915,14 @@ unsigned long flags; int rtn = FAILED; - if (scmd->host->hostt->eh_device_reset_handler == NULL) { + if (scmd->device->host->hostt->eh_device_reset_handler == NULL) { return rtn; } scmd->owner = SCSI_OWNER_LOWLEVEL; - spin_lock_irqsave(scmd->host->host_lock, flags); - rtn = scmd->host->hostt->eh_device_reset_handler(scmd); - spin_unlock_irqrestore(scmd->host->host_lock, flags); + spin_lock_irqsave(scmd->device->host->host_lock, flags); + rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd); + spin_unlock_irqrestore(scmd->device->host->host_lock, flags); if (rtn == SUCCESS) { scmd->device->was_reset = 1; @@ -990,20 +993,20 @@ scmd->owner = SCSI_OWNER_LOWLEVEL; scmd->serial_number_at_timeout = scmd->serial_number; - if (scmd->host->hostt->eh_bus_reset_handler == NULL) + if (scmd->device->host->hostt->eh_bus_reset_handler == NULL) return FAILED; - spin_lock_irqsave(scmd->host->host_lock, flags); - rtn = scmd->host->hostt->eh_bus_reset_handler(scmd); - spin_unlock_irqrestore(scmd->host->host_lock, flags); + spin_lock_irqsave(scmd->device->host->host_lock, flags); + rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd); + spin_unlock_irqrestore(scmd->device->host->host_lock, flags); if (rtn == SUCCESS) { scsi_sleep(BUS_RESET_SETTLE_TIME); /* * Mark all affected devices to expect a unit attention. */ - list_for_each_entry(sdev, &scmd->host->my_devices, siblings) - if (scmd->channel == sdev->channel) { + list_for_each_entry(sdev, &scmd->device->host->my_devices, siblings) + if (scmd->device->channel == sdev->channel) { sdev->was_reset = 1; sdev->expecting_cc_ua = 1; } @@ -1026,20 +1029,20 @@ scmd->owner = SCSI_OWNER_LOWLEVEL; scmd->serial_number_at_timeout = scmd->serial_number; - if (scmd->host->hostt->eh_host_reset_handler == NULL) + if (scmd->device->host->hostt->eh_host_reset_handler == NULL) return FAILED; - spin_lock_irqsave(scmd->host->host_lock, flags); - rtn = scmd->host->hostt->eh_host_reset_handler(scmd); - spin_unlock_irqrestore(scmd->host->host_lock, flags); + spin_lock_irqsave(scmd->device->host->host_lock, flags); + rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd); + spin_unlock_irqrestore(scmd->device->host->host_lock, flags); if (rtn == SUCCESS) { scsi_sleep(HOST_RESET_SETTLE_TIME); /* * Mark all affected devices to expect a unit attention. */ - list_for_each_entry(sdev, &scmd->host->my_devices, siblings) - if (scmd->channel == sdev->channel) { + list_for_each_entry(sdev, &scmd->device->host->my_devices, siblings) + if (scmd->device->channel == sdev->channel) { sdev->was_reset = 1; sdev->expecting_cc_ua = 1; } @@ -1078,7 +1081,7 @@ for (scmd = sc_todo; scmd; scmd = scmd->bh_next) { if (!scsi_eh_eflags_chk(scmd, SCSI_EH_CMD_ERR)) continue; - if (channel == scmd->channel) { + if (channel == scmd->device->channel) { chan_scmd = scmd; break; /* @@ -1102,7 +1105,7 @@ if (rtn == SUCCESS) { for (scmd = sc_todo; scmd; scmd = scmd->bh_next) { if (!scsi_eh_eflags_chk(scmd, SCSI_EH_CMD_ERR) - || channel != scmd->channel) + || channel != scmd->device->channel) continue; if (!scsi_eh_tur(scmd)) { rtn = scsi_eh_retry_cmd(scmd); @@ -1335,7 +1338,7 @@ case RESERVATION_CONFLICT: printk("scsi%d (%d,%d,%d) : reservation conflict\n", - scmd->host->host_no, scmd->channel, + scmd->device->host->host_no, scmd->device->channel, scmd->device->id, scmd->device->lun); return SUCCESS; /* causes immediate i/o error */ default: @@ -1371,7 +1374,7 @@ scmd->sc_request = NULL; sreq->sr_command = NULL; - scsi_release_command(scmd); + scsi_put_command(scmd); scsi_release_request(sreq); } @@ -1576,10 +1579,10 @@ int rtn; DECLARE_MUTEX_LOCKED(sem); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigfillset(¤t->blocked); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); lock_kernel(); @@ -1594,6 +1597,7 @@ */ sprintf(current->comm, "scsi_eh_%d", shost->host_no); + current->flags |= PF_IOTHREAD; shost->eh_wait = &sem; shost->ehandler = current; @@ -1739,29 +1743,13 @@ int scsi_reset_provider(Scsi_Device *dev, int flag) { - struct scsi_cmnd SC, *SCpnt = &SC; + struct scsi_cmnd *SCpnt = scsi_get_command(dev, GFP_KERNEL); struct request req; int rtn; SCpnt->request = &req; memset(&SCpnt->eh_timeout, 0, sizeof(SCpnt->eh_timeout)); - SCpnt->host = dev->host; - SCpnt->device = dev; - SCpnt->target = dev->id; - SCpnt->lun = dev->lun; - SCpnt->channel = dev->channel; SCpnt->request->rq_status = RQ_SCSI_BUSY; - SCpnt->request->waiting = NULL; - SCpnt->use_sg = 0; - SCpnt->old_use_sg = 0; - SCpnt->old_cmd_len = 0; - SCpnt->underflow = 0; - SCpnt->transfersize = 0; - SCpnt->resid = 0; - SCpnt->serial_number = 0; - SCpnt->serial_number_at_timeout = 0; - SCpnt->host_scribble = NULL; - SCpnt->next = NULL; SCpnt->state = SCSI_STATE_INITIALIZING; SCpnt->owner = SCSI_OWNER_MIDLEVEL; @@ -1794,5 +1782,6 @@ rtn = scsi_new_reset(SCpnt, flag); scsi_delete_timer(SCpnt); + scsi_put_command(SCpnt); return rtn; } diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c --- a/drivers/scsi/scsi_lib.c Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/scsi_lib.c Sun Feb 9 21:13:32 2003 @@ -33,15 +33,16 @@ struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR] = { SP(8), SP(16), SP(32), SP(64), SP(MAX_PHYS_SEGMENTS) }; -#undef SP +#undef SP + /* * Function: scsi_insert_special_cmd() * * Purpose: Insert pre-formed command into request queue. * - * Arguments: SCpnt - command that is ready to be queued. - * at_head - boolean. True if we should insert at head + * Arguments: cmd - command that is ready to be queued. + * at_head - boolean. True if we should insert at head * of queue, false if we should insert at tail. * * Lock status: Assumed that lock is not held upon entry. @@ -55,10 +56,10 @@ * for now), and then call the queue request function to actually * process it. */ -int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head) +int scsi_insert_special_cmd(struct scsi_cmnd *cmd, int at_head) { - blk_insert_request(SCpnt->device->request_queue, SCpnt->request, - at_head, SCpnt); + blk_insert_request(cmd->device->request_queue, cmd->request, + at_head, cmd); return 0; } @@ -67,8 +68,8 @@ * * Purpose: Insert pre-formed request into request queue. * - * Arguments: SRpnt - request that is ready to be queued. - * at_head - boolean. True if we should insert at head + * Arguments: sreq - request that is ready to be queued. + * at_head - boolean. True if we should insert at head * of queue, false if we should insert at tail. * * Lock status: Assumed that lock is not held upon entry. @@ -82,24 +83,24 @@ * for now), and then call the queue request function to actually * process it. */ -int scsi_insert_special_req(Scsi_Request * SRpnt, int at_head) +int scsi_insert_special_req(struct scsi_request *sreq, int at_head) { - /* This is used to insert SRpnt specials. Because users of - * this function are apt to reuse requests with no modification, - * we have to sanitise the request flags here - */ - SRpnt->sr_request->flags &= ~REQ_DONTPREP; - blk_insert_request(SRpnt->sr_device->request_queue, SRpnt->sr_request, - at_head, SRpnt); + /* + * Because users of this function are apt to reuse requests with no + * modification, we have to sanitise the request flags here + */ + sreq->sr_request->flags &= ~REQ_DONTPREP; + blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request, + at_head, sreq); return 0; } /* * Function: scsi_init_cmd_errh() * - * Purpose: Initialize SCpnt fields related to error handling. + * Purpose: Initialize cmd fields related to error handling. * - * Arguments: SCpnt - command that is ready to be queued. + * Arguments: cmd - command that is ready to be queued. * * Returns: Nothing * @@ -107,21 +108,20 @@ * fields related to error handling. Typically this will * be called once for each command, as required. */ -static int scsi_init_cmd_errh(Scsi_Cmnd * SCpnt) +static int scsi_init_cmd_errh(struct scsi_cmnd *cmd) { - SCpnt->owner = SCSI_OWNER_MIDLEVEL; - SCpnt->reset_chain = NULL; - SCpnt->serial_number = 0; - SCpnt->serial_number_at_timeout = 0; - SCpnt->flags = 0; - SCpnt->retries = 0; - - SCpnt->abort_reason = 0; + cmd->owner = SCSI_OWNER_MIDLEVEL; + cmd->reset_chain = NULL; + cmd->serial_number = 0; + cmd->serial_number_at_timeout = 0; + cmd->flags = 0; + cmd->retries = 0; + cmd->abort_reason = 0; - memset((void *) SCpnt->sense_buffer, 0, sizeof SCpnt->sense_buffer); + memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer); - if (SCpnt->cmd_len == 0) - SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]); + if (cmd->cmd_len == 0) + cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); /* * We need saved copies of a number of fields - this is because @@ -130,19 +130,16 @@ * we will need to restore these values prior to running the actual * command. */ - SCpnt->old_use_sg = SCpnt->use_sg; - SCpnt->old_cmd_len = SCpnt->cmd_len; - SCpnt->sc_old_data_direction = SCpnt->sc_data_direction; - SCpnt->old_underflow = SCpnt->underflow; - memcpy((void *) SCpnt->data_cmnd, - (const void *) SCpnt->cmnd, sizeof(SCpnt->cmnd)); - SCpnt->buffer = SCpnt->request_buffer; - SCpnt->bufflen = SCpnt->request_bufflen; - - SCpnt->reset_chain = NULL; - - SCpnt->internal_timeout = NORMAL_TIMEOUT; - SCpnt->abort_reason = 0; + cmd->old_use_sg = cmd->use_sg; + cmd->old_cmd_len = cmd->cmd_len; + cmd->sc_old_data_direction = cmd->sc_data_direction; + cmd->old_underflow = cmd->underflow; + memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd)); + cmd->buffer = cmd->request_buffer; + cmd->bufflen = cmd->request_bufflen; + cmd->reset_chain = NULL; + cmd->internal_timeout = NORMAL_TIMEOUT; + cmd->abort_reason = 0; return 1; } @@ -152,23 +149,22 @@ * * Purpose: Restore the command state for a retry * - * Arguments: SCpnt - command to be restored + * Arguments: cmd - command to be restored * * Returns: Nothing * * Notes: Immediately prior to retrying a command, we need * to restore certain fields that we saved above. */ -void scsi_setup_cmd_retry(Scsi_Cmnd *SCpnt) +void scsi_setup_cmd_retry(struct scsi_cmnd *cmd) { - memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd, - sizeof(SCpnt->data_cmnd)); - SCpnt->request_buffer = SCpnt->buffer; - SCpnt->request_bufflen = SCpnt->bufflen; - SCpnt->use_sg = SCpnt->old_use_sg; - SCpnt->cmd_len = SCpnt->old_cmd_len; - SCpnt->sc_data_direction = SCpnt->sc_old_data_direction; - SCpnt->underflow = SCpnt->old_underflow; + memcpy(cmd->cmnd, cmd->data_cmnd, sizeof(cmd->data_cmnd)); + cmd->request_buffer = cmd->buffer; + cmd->request_bufflen = cmd->bufflen; + cmd->use_sg = cmd->old_use_sg; + cmd->cmd_len = cmd->old_cmd_len; + cmd->sc_data_direction = cmd->sc_old_data_direction; + cmd->underflow = cmd->old_underflow; } /* @@ -176,7 +172,7 @@ * * Purpose: Handle post-processing of completed commands. * - * Arguments: SCpnt - command that may need to be requeued. + * Arguments: cmd - command that may need to be requeued. * * Returns: Nothing * @@ -186,7 +182,7 @@ * that a medium error occurred, and the sectors after * the bad block need to be re-read. * - * If SCpnt is NULL, it means that the previous command + * If cmd is NULL, it means that the previous command * was completely finished, and we should simply start * a new command, if possible. * @@ -207,17 +203,17 @@ * permutations grows as 2**N, and if too many more special cases * get added, we start to get screwed. */ -void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) +void scsi_queue_next_request(request_queue_t *q, struct scsi_cmnd *cmd) { - int all_clear; + struct scsi_device *sdev, *sdev2; + struct Scsi_Host *shost; unsigned long flags; - Scsi_Device *SDpnt, *SDpnt2; - struct Scsi_Host *SHpnt; + int all_clear; ASSERT_LOCK(q->queue_lock, 0); spin_lock_irqsave(q->queue_lock, flags); - if (SCpnt != NULL) { + if (cmd != NULL) { /* * For some reason, we are not done with this request. @@ -225,16 +221,18 @@ * in which case we need to request the blocks that come after * the bad sector. */ - SCpnt->request->special = (void *) SCpnt; - if(blk_rq_tagged(SCpnt->request)) - blk_queue_end_tag(q, SCpnt->request); - /* set REQ_SPECIAL - we have a command + cmd->request->special = cmd; + if (blk_rq_tagged(cmd->request)) + blk_queue_end_tag(q, cmd->request); + + /* + * set REQ_SPECIAL - we have a command * clear REQ_DONTPREP - we assume the sg table has been * nuked so we need to set it up again. */ - SCpnt->request->flags |= REQ_SPECIAL; - SCpnt->request->flags &= ~REQ_DONTPREP; - __elv_add_request(q, SCpnt->request, 0, 0); + cmd->request->flags |= REQ_SPECIAL; + cmd->request->flags &= ~REQ_DONTPREP; + __elv_add_request(q, cmd->request, 0, 0); } /* @@ -242,8 +240,8 @@ */ __blk_run_queue(q); - SDpnt = (Scsi_Device *) q->queuedata; - SHpnt = SDpnt->host; + sdev = q->queuedata; + shost = sdev->host; /* * If this is a single-lun device, and we are currently finished @@ -252,15 +250,15 @@ * with special case code, then spin off separate versions and * use function pointers to pick the right one. */ - if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0 && - !SHpnt->host_blocked && !SHpnt->host_self_blocked && - !((SHpnt->can_queue > 0) && (SHpnt->host_busy >= - SHpnt->can_queue))) { - list_for_each_entry(SDpnt2, &SDpnt->same_target_siblings, + if (sdev->single_lun && blk_queue_empty(q) && sdev->device_busy ==0 && + !shost->host_blocked && !shost->host_self_blocked && + !((shost->can_queue > 0) && (shost->host_busy >= + shost->can_queue))) { + list_for_each_entry(sdev2, &sdev->same_target_siblings, same_target_siblings) { - if (!SDpnt2->device_blocked && - !blk_queue_empty(SDpnt2->request_queue)) { - __blk_run_queue(SDpnt2->request_queue); + if (!sdev2->device_blocked && + !blk_queue_empty(sdev2->request_queue)) { + __blk_run_queue(sdev2->request_queue); break; } } @@ -275,22 +273,21 @@ * other device might have become starved along the way. */ all_clear = 1; - if (SHpnt->some_device_starved) { - list_for_each_entry(SDpnt, &SHpnt->my_devices, siblings) { - if ((SHpnt->can_queue > 0 && (SHpnt->host_busy >= SHpnt->can_queue)) - || (SHpnt->host_blocked) - || (SHpnt->host_self_blocked)) { + if (shost->some_device_starved) { + list_for_each_entry(sdev, &shost->my_devices, siblings) { + if (shost->can_queue > 0 && + shost->host_busy >= shost->can_queue) break; - } - if (SDpnt->device_blocked || !SDpnt->starved) { + if (shost->host_blocked || shost->host_self_blocked) + break; + if (sdev->device_blocked || !sdev->starved) continue; - } - __blk_run_queue(SDpnt->request_queue); + __blk_run_queue(sdev->request_queue); all_clear = 0; } - if (SDpnt == NULL && all_clear) { - SHpnt->some_device_starved = 0; - } + + if (sdev == NULL && all_clear) + shost->some_device_starved = 0; } spin_unlock_irqrestore(q->queue_lock, flags); } @@ -301,7 +298,7 @@ * Purpose: Post-processing of completed commands called from interrupt * handler or a bottom-half handler. * - * Arguments: SCpnt - command that is complete. + * Arguments: cmd - command that is complete. * uptodate - 1 if I/O indicates success, 0 for I/O error. * sectors - number of sectors we want to mark. * requeue - indicates whether we should requeue leftovers. @@ -318,13 +315,11 @@ * We are guaranteeing that the request queue will be goosed * at some point during this call. */ -static Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, - int uptodate, - int sectors, - int requeue) +static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate, + int sectors, int requeue) { - request_queue_t *q = SCpnt->device->request_queue; - struct request *req = SCpnt->request; + request_queue_t *q = cmd->device->request_queue; + struct request *req = cmd->request; unsigned long flags; ASSERT_LOCK(q->queue_lock, 0); @@ -334,15 +329,14 @@ * to queue the remainder of them. */ if (end_that_request_first(req, uptodate, sectors)) { - if (!requeue) - return SCpnt; - - /* - * Bleah. Leftovers again. Stick the leftovers in - * the front of the queue, and goose the queue again. - */ - scsi_queue_next_request(q, SCpnt); - return SCpnt; + if (requeue) { + /* + * Bleah. Leftovers again. Stick the leftovers in + * the front of the queue, and goose the queue again. + */ + scsi_queue_next_request(q, cmd); + } + return cmd; } add_disk_randomness(req->rq_disk); @@ -357,39 +351,39 @@ * This will goose the queue request function at the end, so we don't * need to worry about launching another command. */ - __scsi_release_command(SCpnt); + scsi_put_command(cmd); scsi_queue_next_request(q, NULL); return NULL; } -static struct scatterlist *scsi_alloc_sgtable(Scsi_Cmnd *SCpnt, int gfp_mask) +static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, int gfp_mask) { struct scsi_host_sg_pool *sgp; struct scatterlist *sgl; - BUG_ON(!SCpnt->use_sg); + BUG_ON(!cmd->use_sg); - switch (SCpnt->use_sg) { + switch (cmd->use_sg) { case 1 ... 8: - SCpnt->sglist_len = 0; + cmd->sglist_len = 0; break; case 9 ... 16: - SCpnt->sglist_len = 1; + cmd->sglist_len = 1; break; case 17 ... 32: - SCpnt->sglist_len = 2; + cmd->sglist_len = 2; break; case 33 ... 64: - SCpnt->sglist_len = 3; + cmd->sglist_len = 3; break; case 65 ... MAX_PHYS_SEGMENTS: - SCpnt->sglist_len = 4; + cmd->sglist_len = 4; break; default: return NULL; } - sgp = scsi_sg_pools + SCpnt->sglist_len; + sgp = scsi_sg_pools + cmd->sglist_len; sgl = mempool_alloc(sgp->pool, gfp_mask); if (sgl) memset(sgl, 0, sgp->size); @@ -406,13 +400,12 @@ mempool_free(sgl, sgp->pool); } - /* * Function: scsi_release_buffers() * * Purpose: Completion processing for block device I/O requests. * - * Arguments: SCpnt - command that we are bailing. + * Arguments: cmd - command that we are bailing. * * Lock status: Assumed that no lock is held upon entry. * @@ -424,28 +417,28 @@ * the scatter-gather table, and potentially any bounce * buffers. */ -static void scsi_release_buffers(Scsi_Cmnd * SCpnt) +static void scsi_release_buffers(struct scsi_cmnd *cmd) { - struct request *req = SCpnt->request; + struct request *req = cmd->request; - ASSERT_LOCK(SCpnt->host->host_lock, 0); + ASSERT_LOCK(cmd->device->host->host_lock, 0); /* * Free up any indirection buffers we allocated for DMA purposes. */ - if (SCpnt->use_sg) - scsi_free_sgtable(SCpnt->request_buffer, SCpnt->sglist_len); - else if (SCpnt->request_buffer != req->buffer) - kfree(SCpnt->request_buffer); + if (cmd->use_sg) + scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); + else if (cmd->request_buffer != req->buffer) + kfree(cmd->request_buffer); /* * Zero these out. They now point to freed memory, and it is * dangerous to hang onto the pointers. */ - SCpnt->buffer = NULL; - SCpnt->bufflen = 0; - SCpnt->request_buffer = NULL; - SCpnt->request_bufflen = 0; + cmd->buffer = NULL; + cmd->bufflen = 0; + cmd->request_buffer = NULL; + cmd->request_bufflen = 0; } /* @@ -476,7 +469,7 @@ * * Purpose: Completion processing for block device I/O requests. * - * Arguments: SCpnt - command that is finished. + * Arguments: cmd - command that is finished. * * Lock status: Assumed that no lock is held upon entry. * @@ -488,13 +481,13 @@ * (the normal case for most drivers), we don't need * the logic to deal with cleaning up afterwards. */ -void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, +void scsi_io_completion(struct scsi_cmnd *cmd, int good_sectors, int block_sectors) { - int result = SCpnt->result; - int this_count = SCpnt->bufflen >> 9; - request_queue_t *q = SCpnt->device->request_queue; - struct request *req = SCpnt->request; + int result = cmd->result; + int this_count = cmd->bufflen >> 9; + request_queue_t *q = cmd->device->request_queue; + struct request *req = cmd->request; int clear_errors = 1; /* @@ -517,44 +510,43 @@ * For the case of a READ, we need to copy the data out of the * bounce buffer and into the real buffer. */ - if (SCpnt->use_sg) - scsi_free_sgtable(SCpnt->buffer, SCpnt->sglist_len); - else if (SCpnt->buffer != req->buffer) { + if (cmd->use_sg) + scsi_free_sgtable(cmd->buffer, cmd->sglist_len); + else if (cmd->buffer != req->buffer) { if (rq_data_dir(req) == READ) { unsigned long flags; char *to = bio_kmap_irq(req->bio, &flags); - memcpy(to, SCpnt->buffer, SCpnt->bufflen); + memcpy(to, cmd->buffer, cmd->bufflen); bio_kunmap_irq(to, &flags); } - kfree(SCpnt->buffer); + kfree(cmd->buffer); } if (blk_pc_request(req)) { /* SG_IO ioctl from block level */ req->errors = (driver_byte(result) & DRIVER_SENSE) ? (CHECK_CONDITION << 1) : (result & 0xff); - if (!result) - req->data_len -= SCpnt->bufflen; - else { + if (result) { clear_errors = 0; - if (SCpnt->sense_buffer[0] & 0x70) { - int len = 8 + SCpnt->sense_buffer[7]; + if (cmd->sense_buffer[0] & 0x70) { + int len = 8 + cmd->sense_buffer[7]; if (len > SCSI_SENSE_BUFFERSIZE) len = SCSI_SENSE_BUFFERSIZE; - memcpy(req->sense, SCpnt->sense_buffer, len); + memcpy(req->sense, cmd->sense_buffer, len); req->sense_len = len; } - } + } else + req->data_len -= cmd->bufflen; } /* * Zero these out. They now point to freed memory, and it is * dangerous to hang onto the pointers. */ - SCpnt->buffer = NULL; - SCpnt->bufflen = 0; - SCpnt->request_buffer = NULL; - SCpnt->request_bufflen = 0; + cmd->buffer = NULL; + cmd->bufflen = 0; + cmd->request_buffer = NULL; + cmd->request_bufflen = 0; /* * Next deal with any sectors which we were able to correctly @@ -563,7 +555,7 @@ if (good_sectors >= 0) { SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, %d sectors done.\n", req->nr_sectors, good_sectors)); - SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n ", SCpnt->use_sg)); + SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n ", cmd->use_sg)); if (clear_errors) req->errors = 0; @@ -578,13 +570,13 @@ * requeueing right here - we will requeue down below * when we handle the bad sectors. */ - SCpnt = scsi_end_request(SCpnt, 1, good_sectors, result == 0); + cmd = scsi_end_request(cmd, 1, good_sectors, result == 0); /* * If the command completed without error, then either finish off the * rest of the command, or start a new one. */ - if (result == 0 || SCpnt == NULL ) { + if (result == 0 || cmd == NULL ) { return; } } @@ -600,28 +592,28 @@ * Not yet implemented. A read will fail after being remapped, * a write will call the strategy routine again. */ - if (SCpnt->device->remap) { + if (cmd->device->remap) { result = 0; } #endif } - if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) { + if ((cmd->sense_buffer[0] & 0x7f) == 0x70) { /* * If the device is in the process of becoming ready, * retry. */ - if (SCpnt->sense_buffer[12] == 0x04 && - SCpnt->sense_buffer[13] == 0x01) { - scsi_queue_next_request(q, SCpnt); + if (cmd->sense_buffer[12] == 0x04 && + cmd->sense_buffer[13] == 0x01) { + scsi_queue_next_request(q, cmd); return; } - if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) { - if (SCpnt->device->removable) { + if ((cmd->sense_buffer[2] & 0xf) == UNIT_ATTENTION) { + if (cmd->device->removable) { /* detected disc change. set a bit * and quietly refuse further access. */ - SCpnt->device->changed = 1; - SCpnt = scsi_end_request(SCpnt, 0, + cmd->device->changed = 1; + cmd = scsi_end_request(cmd, 0, this_count, 1); return; } else { @@ -631,7 +623,7 @@ * media change, so we just retry the * request and see what happens. */ - scsi_queue_next_request(q, SCpnt); + scsi_queue_next_request(q, cmd); return; } } @@ -643,35 +635,35 @@ * past the end of the disk. */ - switch (SCpnt->sense_buffer[2]) { + switch (cmd->sense_buffer[2]) { case ILLEGAL_REQUEST: - if (SCpnt->device->ten) { - SCpnt->device->ten = 0; + if (cmd->device->ten) { + cmd->device->ten = 0; /* * This will cause a retry with a 6-byte * command. */ - scsi_queue_next_request(q, SCpnt); + scsi_queue_next_request(q, cmd); result = 0; } else { - SCpnt = scsi_end_request(SCpnt, 0, this_count, 1); + cmd = scsi_end_request(cmd, 0, this_count, 1); return; } break; case NOT_READY: printk(KERN_INFO "Device %s not ready.\n", req->rq_disk ? req->rq_disk->disk_name : ""); - SCpnt = scsi_end_request(SCpnt, 0, this_count, 1); + cmd = scsi_end_request(cmd, 0, this_count, 1); return; break; case MEDIUM_ERROR: case VOLUME_OVERFLOW: printk("scsi%d: ERROR on channel %d, id %d, lun %d, CDB: ", - SCpnt->host->host_no, (int) SCpnt->channel, - (int) SCpnt->target, (int) SCpnt->lun); - print_command(SCpnt->data_cmnd); - print_sense("sd", SCpnt); - SCpnt = scsi_end_request(SCpnt, 0, block_sectors, 1); + cmd->device->host->host_no, (int) cmd->device->channel, + (int) cmd->device->id, (int) cmd->device->lun); + print_command(cmd->data_cmnd); + print_sense("sd", cmd); + cmd = scsi_end_request(cmd, 0, block_sectors, 1); return; default: break; @@ -683,28 +675,28 @@ * recovery reasons. Just retry the request * and see what happens. */ - scsi_queue_next_request(q, SCpnt); + scsi_queue_next_request(q, cmd); return; } if (result) { - struct Scsi_Device_Template *STpnt; + struct Scsi_Device_Template *sdt; - STpnt = scsi_get_request_dev(SCpnt->request); + sdt = scsi_get_request_dev(cmd->request); printk("SCSI %s error : host %d channel %d id %d lun %d return code = %x\n", - (STpnt ? STpnt->name : "device"), - SCpnt->device->host->host_no, - SCpnt->device->channel, - SCpnt->device->id, - SCpnt->device->lun, result); + (sdt ? sdt->name : "device"), + cmd->device->host->host_no, + cmd->device->channel, + cmd->device->id, + cmd->device->lun, result); if (driver_byte(result) & DRIVER_SENSE) - print_sense("sd", SCpnt); + print_sense("sd", cmd); /* * Mark a single buffer as not uptodate. Queue the remainder. * We sometimes get this cruft in the event that a medium error * isn't properly reported. */ - SCpnt = scsi_end_request(SCpnt, 0, req->current_nr_sectors, 1); + cmd = scsi_end_request(cmd, 0, req->current_nr_sectors, 1); return; } } @@ -714,26 +706,26 @@ * * Purpose: SCSI I/O initialize function. * - * Arguments: SCpnt - Command descriptor we wish to initialize + * Arguments: cmd - Command descriptor we wish to initialize * * Returns: 0 on success * BLKPREP_DEFER if the failure is retryable * BLKPREP_KILL if the failure is fatal */ -static int scsi_init_io(Scsi_Cmnd *SCpnt) +static int scsi_init_io(struct scsi_cmnd *cmd) { - struct request *req = SCpnt->request; + struct request *req = cmd->request; struct scatterlist *sgpnt; - int count, ret = 0; + int count; /* * if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer */ if ((req->flags & REQ_BLOCK_PC) && !req->bio) { - SCpnt->request_bufflen = req->data_len; - SCpnt->request_buffer = req->data; + cmd->request_bufflen = req->data_len; + cmd->request_buffer = req->data; req->buffer = req->data; - SCpnt->use_sg = 0; + cmd->use_sg = 0; return 0; } @@ -742,113 +734,112 @@ * but now we do (it makes highmem I/O easier to support without * kmapping pages) */ - SCpnt->use_sg = req->nr_phys_segments; + cmd->use_sg = req->nr_phys_segments; /* * if sg table allocation fails, requeue request later. */ - sgpnt = scsi_alloc_sgtable(SCpnt, GFP_ATOMIC); + sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC); if (unlikely(!sgpnt)) { req->flags |= REQ_SPECIAL; - ret = BLKPREP_DEFER; - goto out; + return BLKPREP_DEFER; } - SCpnt->request_buffer = (char *) sgpnt; - SCpnt->request_bufflen = req->nr_sectors << 9; + cmd->request_buffer = (char *) sgpnt; + cmd->request_bufflen = req->nr_sectors << 9; if (blk_pc_request(req)) - SCpnt->request_bufflen = req->data_len; + cmd->request_bufflen = req->data_len; req->buffer = NULL; /* * Next, walk the list, and fill in the addresses and sizes of * each segment. */ - count = blk_rq_map_sg(req->q, req, SCpnt->request_buffer); + count = blk_rq_map_sg(req->q, req, cmd->request_buffer); /* * mapped well, send it off */ - if (count <= SCpnt->use_sg) { - SCpnt->use_sg = count; + if (likely(count <= cmd->use_sg)) { + cmd->use_sg = count; return 0; } printk(KERN_ERR "Incorrect number of segments after building list\n"); - printk(KERN_ERR "counted %d, received %d\n", count, SCpnt->use_sg); + printk(KERN_ERR "counted %d, received %d\n", count, cmd->use_sg); printk(KERN_ERR "req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors, req->current_nr_sectors); - /* - * kill it. there should be no leftover blocks in this request - */ - SCpnt = scsi_end_request(SCpnt, 0, req->nr_sectors, 1); - BUG_ON(SCpnt); - ret = BLKPREP_KILL; -out: - return ret; + /* release the command and kill it */ + scsi_put_command(cmd); + return BLKPREP_KILL; } -int scsi_prep_fn(struct request_queue *q, struct request *req) +/* + * The target associated with myself can only handle one active command at + * a time. Scan through all of the luns on the same target as myself, + * return 1 if any are active. + */ +static int check_all_luns(struct scsi_device *myself) { - struct Scsi_Device_Template *STpnt; - Scsi_Cmnd *SCpnt; - Scsi_Device *SDpnt; + struct scsi_device *sdev; + + list_for_each_entry(sdev, &myself->same_target_siblings, + same_target_siblings) + if (sdev->device_busy) + return 1; + return 0; +} - SDpnt = (Scsi_Device *) q->queuedata; - BUG_ON(!SDpnt); +int scsi_prep_fn(struct request_queue *q, struct request *req) +{ + struct Scsi_Device_Template *sdt; + struct scsi_device *sdev = q->queuedata; + struct scsi_cmnd *cmd; /* * Find the actual device driver associated with this command. * The SPECIAL requests are things like character device or * ioctls, which did not originate from ll_rw_blk. Note that - * the special field is also used to indicate the SCpnt for + * the special field is also used to indicate the cmd for * the remainder of a partially fulfilled request that can * come up when there is a medium error. We have to treat * these two cases differently. We differentiate by looking * at request->cmd, as this tells us the real story. */ if (req->flags & REQ_SPECIAL) { - Scsi_Request *SRpnt; + struct scsi_request *sreq = req->special; - STpnt = NULL; - SCpnt = (Scsi_Cmnd *) req->special; - SRpnt = (Scsi_Request *) req->special; - - if( SRpnt->sr_magic == SCSI_REQ_MAGIC ) { - SCpnt = scsi_allocate_device(SRpnt->sr_device, 0); - if (!SCpnt) + if (sreq->sr_magic == SCSI_REQ_MAGIC) { + cmd = scsi_get_command(sreq->sr_device, GFP_ATOMIC); + if (unlikely(!cmd)) return BLKPREP_DEFER; - scsi_init_cmd_from_req(SCpnt, SRpnt); - } - + scsi_init_cmd_from_req(cmd, sreq); + } else + cmd = req->special; } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { /* * Now try and find a command block that we can use. */ - if (req->special) { - SCpnt = (Scsi_Cmnd *) req->special; - } else { - SCpnt = scsi_allocate_device(SDpnt, 0); - } - /* - * if command allocation failure, wait a bit - */ - if (unlikely(!SCpnt)) - return BLKPREP_DEFER; + if (!req->special) { + cmd = scsi_get_command(sdev, GFP_ATOMIC); + if (unlikely(!cmd)) + return BLKPREP_DEFER; + } else + cmd = req->special; /* pull a tag out of the request if we have one */ - SCpnt->tag = req->tag; + cmd->tag = req->tag; } else { blk_dump_rq_flags(req, "SCSI bad req"); return BLKPREP_KILL; } /* note the overloading of req->special. When the tag - * is active it always means SCpnt. If the tag goes + * is active it always means cmd. If the tag goes * back for re-queueing, it may be reset */ - req->special = SCpnt; - SCpnt->request = req; + req->special = cmd; + cmd->request = req; /* * FIXME: drop the lock here because the functions below @@ -857,7 +848,6 @@ * lock. We hope REQ_STARTED prevents anything untoward from * happening now. */ - if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) { int ret; @@ -873,25 +863,30 @@ * some kinds of consistency checking may cause the * request to be rejected immediately. */ - STpnt = scsi_get_request_dev(req); - BUG_ON(!STpnt); + sdt = scsi_get_request_dev(req); + BUG_ON(!sdt); /* * This sets up the scatter-gather table (allocating if * required). */ - if ((ret = scsi_init_io(SCpnt))) + ret = scsi_init_io(cmd); + if (ret) /* BLKPREP_KILL return also releases the command */ return ret; /* * Initialize the actual SCSI command for this request. */ - if (!STpnt->init_command(SCpnt)) { - scsi_release_buffers(SCpnt); + if (unlikely(!sdt->init_command(cmd))) { + scsi_release_buffers(cmd); + scsi_put_command(cmd); return BLKPREP_KILL; } } - /* The request is now prepped, no need to come back here */ + + /* + * The request is now prepped, no need to come back here + */ req->flags |= REQ_DONTPREP; return BLKPREP_OK; } @@ -899,48 +894,34 @@ /* * Function: scsi_request_fn() * - * Purpose: Generic version of request function for SCSI hosts. + * Purpose: Main strategy routine for SCSI. * * Arguments: q - Pointer to actual queue. * * Returns: Nothing * * Lock status: IO request lock assumed to be held when called. - * - * Notes: The theory is that this function is something which individual - * drivers could also supply if they wished to. The problem - * is that we have 30 some odd low-level drivers in the kernel - * tree already, and it would be most difficult to retrofit - * this crap into all of them. Thus this function has the job - * of acting as a generic queue manager for all of those existing - * drivers. */ -void scsi_request_fn(request_queue_t * q) +void scsi_request_fn(request_queue_t *q) { + struct scsi_device *sdev = q->queuedata; + struct Scsi_Host *shost = sdev->host; + struct scsi_cmnd *cmd; struct request *req; - Scsi_Cmnd *SCpnt; - Scsi_Device *SDpnt; - struct Scsi_Host *SHpnt; ASSERT_LOCK(q->queue_lock, 1); - SDpnt = (Scsi_Device *) q->queuedata; - if (!SDpnt) { - panic("Missing device"); - } - SHpnt = SDpnt->host; - /* * To start with, we keep looping until the queue is empty, or until * the host is no longer able to accept any more requests. */ - while (1 == 1) { + for (;;) { /* * Check this again - each time we loop through we will have * released the lock and grabbed it again, so each time * we need to check to see if the queue is plugged or not. */ - if (SHpnt->in_recovery || blk_queue_plugged(q)) + if (shost->in_recovery || blk_queue_plugged(q)) return; /* @@ -951,33 +932,43 @@ */ req = elv_next_request(q); - if(SHpnt->host_busy == 0 && SHpnt->host_blocked) { + if (sdev->device_busy >= sdev->queue_depth) + break; + + if (sdev->single_lun && check_all_luns(sdev)) + break; + + if (shost->host_busy == 0 && shost->host_blocked) { /* unblock after host_blocked iterates to zero */ - if(--SHpnt->host_blocked == 0) { - SCSI_LOG_MLQUEUE(3, printk("scsi%d unblocking host at zero depth\n", SHpnt->host_no)); + if (--shost->host_blocked == 0) { + SCSI_LOG_MLQUEUE(3, + printk("scsi%d unblocking host at zero depth\n", + shost->host_no)); } else { blk_plug_device(q); break; } } - if(SDpnt->device_busy == 0 && SDpnt->device_blocked) { + + if (sdev->device_busy == 0 && sdev->device_blocked) { /* unblock after device_blocked iterates to zero */ - if(--SDpnt->device_blocked == 0) { - SCSI_LOG_MLQUEUE(3, printk("scsi%d (%d:%d) unblocking device at zero depth\n", SHpnt->host_no, SDpnt->id, SDpnt->lun)); + if (--sdev->device_blocked == 0) { + SCSI_LOG_MLQUEUE(3, + printk("scsi%d (%d:%d) unblocking device at zero depth\n", + shost->host_no, sdev->id, sdev->lun)); } else { blk_plug_device(q); break; } } + /* * If the device cannot accept another request, then quit. */ - if (SDpnt->device_blocked) { + if (sdev->device_blocked) break; - } - if ((SHpnt->can_queue > 0 && (SHpnt->host_busy >= SHpnt->can_queue)) - || (SHpnt->host_blocked) - || (SHpnt->host_self_blocked)) { + if ((shost->can_queue > 0 && shost->host_busy >= shost->can_queue) || + shost->host_blocked || shost->host_self_blocked) { /* * If we are unable to process any commands at all for * this device, then we consider it to be starved. @@ -986,14 +977,13 @@ * little help getting it started again * once the host isn't quite so busy. */ - if (SDpnt->device_busy == 0) { - SDpnt->starved = 1; - SHpnt->some_device_starved = 1; + if (sdev->device_busy == 0) { + sdev->starved = 1; + shost->some_device_starved = 1; } break; - } else { - SDpnt->starved = 0; - } + } else + sdev->starved = 0; /* * If we couldn't find a request that could be queued, then we @@ -1002,21 +992,22 @@ if (blk_queue_empty(q)) break; - if(!req) { + if (!req) { /* If the device is busy, a returning I/O * will restart the queue. Otherwise, we have * to plug the queue */ - if(SDpnt->device_busy == 0) + if(sdev->device_busy == 0) blk_plug_device(q); break; } - SCpnt = (struct scsi_cmnd *)req->special; + cmd = req->special; - /* Should be impossible for a correctly prepared request + /* + * Should be impossible for a correctly prepared request * please mail the stack trace to linux-scsi@vger.kernel.org */ - BUG_ON(!SCpnt); + BUG_ON(!cmd); /* * Finally, before we release the lock, we copy the @@ -1026,27 +1017,27 @@ * reason to search the list, because all of the * commands in this queue are for the same device. */ - if(!(blk_queue_tagged(q) && (blk_queue_start_tag(q, req) == 0))) + if (!(blk_queue_tagged(q) && (blk_queue_start_tag(q, req) == 0))) blkdev_dequeue_request(req); /* * Now bump the usage count for both the host and the * device. */ - SHpnt->host_busy++; - SDpnt->device_busy++; + shost->host_busy++; + sdev->device_busy++; spin_unlock_irq(q->queue_lock); /* * Finally, initialize any error handling parameters, and set up * the timers for timeouts. */ - scsi_init_cmd_errh(SCpnt); + scsi_init_cmd_errh(cmd); /* * Dispatch the command to the low-level driver. */ - scsi_dispatch_cmd(SCpnt); + scsi_dispatch_cmd(cmd); /* * Now we need to grab the lock again. We are about to mess @@ -1062,7 +1053,7 @@ * Purpose: Utility function used by low-level drivers to prevent further * commands from being queued to the device. * - * Arguments: SHpnt - Host in question + * Arguments: shost - Host in question * * Returns: Nothing * @@ -1072,9 +1063,9 @@ * get unblocked other than the low-level driver calling * scsi_unblock_requests(). */ -void scsi_block_requests(struct Scsi_Host * SHpnt) +void scsi_block_requests(struct Scsi_Host *shost) { - SHpnt->host_self_blocked = 1; + shost->host_self_blocked = 1; } /* @@ -1083,7 +1074,7 @@ * Purpose: Utility function used by low-level drivers to allow further * commands from being queued to the device. * - * Arguments: SHpnt - Host in question + * Arguments: shost - Host in question * * Returns: Nothing * @@ -1097,14 +1088,17 @@ * internals of the scsi mid-layer won't require wholesale * changes to drivers that use this feature. */ -void scsi_unblock_requests(struct Scsi_Host * SHpnt) +void scsi_unblock_requests(struct Scsi_Host *shost) { - Scsi_Device *SDloop; + struct scsi_device *sdev; + + shost->host_self_blocked = 0; - SHpnt->host_self_blocked = 0; - /* Now that we are unblocked, try to start the queues. */ - list_for_each_entry(SDloop, &SHpnt->my_devices, siblings) - scsi_queue_next_request(SDloop->request_queue, NULL); + /* + * Now that we are unblocked, try to start the queues. + */ + list_for_each_entry(sdev, &shost->my_devices, siblings) + scsi_queue_next_request(sdev->request_queue, NULL); } /* @@ -1113,7 +1107,7 @@ * Purpose: Utility function used by low-level drivers to report that * they have observed a bus reset on the bus being handled. * - * Arguments: SHpnt - Host in question + * Arguments: shost - Host in question * channel - channel on which reset was observed. * * Returns: Nothing @@ -1128,13 +1122,14 @@ * The main purpose of this is to make sure that a CHECK_CONDITION * is properly treated. */ -void scsi_report_bus_reset(struct Scsi_Host * SHpnt, int channel) +void scsi_report_bus_reset(struct Scsi_Host *shost, int channel) { - Scsi_Device *SDloop; - list_for_each_entry(SDloop, &SHpnt->my_devices, siblings) { - if (channel == SDloop->channel) { - SDloop->was_reset = 1; - SDloop->expecting_cc_ua = 1; + struct scsi_device *sdev; + + list_for_each_entry(sdev, &shost->my_devices, siblings) { + if (channel == sdev->channel) { + sdev->was_reset = 1; + sdev->expecting_cc_ua = 1; } } } @@ -1148,11 +1143,11 @@ * The details of the implementation remain to be settled, however the * stubs are here now so that the actual drivers will properly compile. */ -void scsi_register_blocked_host(struct Scsi_Host * SHpnt) +void scsi_register_blocked_host(struct Scsi_Host * shost) { } -void scsi_deregister_blocked_host(struct Scsi_Host * SHpnt) +void scsi_deregister_blocked_host(struct Scsi_Host * shost) { } diff -Nru a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c --- a/drivers/scsi/scsi_proc.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/scsi_proc.c Sun Feb 9 21:13:28 2003 @@ -345,10 +345,9 @@ i = 0; for (shpnt = scsi_host_get_next(NULL); shpnt; shpnt = scsi_host_get_next(shpnt)) { - printk(KERN_INFO " %d %d %d : %d %d\n", + printk(KERN_INFO " %d %d : %d %d\n", shpnt->host_failed, shpnt->host_busy, - atomic_read(&shpnt->host_active), shpnt->host_blocked, shpnt->host_self_blocked); } @@ -360,15 +359,18 @@ printk(KERN_INFO "h:c:t:l (dev sect nsect cnumsec sg) " "(ret all flg) (to/cmd to ito) cmd snse result\n"); list_for_each_entry(SDpnt, &shpnt->my_devices, siblings) { - for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) { + unsigned long flags; + + spin_lock_irqsave(&SDpnt->list_lock, flags); + list_for_each_entry(SCpnt, &SDpnt->cmd_list, list) { /* (0) h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) (to/cmd to ito) cmd snse result %d %x */ printk(KERN_INFO "(%3d) %2d:%1d:%2d:%2d (%6s %4llu %4ld %4ld %4x %1d) (%1d %1d 0x%2x) (%4d %4d %4d) 0x%2.2x 0x%2.2x 0x%8.8x\n", i++, - SCpnt->host->host_no, - SCpnt->channel, - SCpnt->target, - SCpnt->lun, + SCpnt->device->host->host_no, + SCpnt->device->channel, + SCpnt->device->id, + SCpnt->device->lun, SCpnt->request->rq_disk ? SCpnt->request->rq_disk->disk_name : "?", @@ -390,6 +392,7 @@ SCpnt->sense_buffer[2], SCpnt->result); } + spin_unlock_irqrestore(&SDpnt->list_lock, flags); } } } diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c --- a/drivers/scsi/scsi_scan.c Sun Feb 9 21:13:35 2003 +++ b/drivers/scsi/scsi_scan.c Sun Feb 9 21:13:35 2003 @@ -449,6 +449,8 @@ sdev->online = TRUE; INIT_LIST_HEAD(&sdev->siblings); INIT_LIST_HEAD(&sdev->same_target_siblings); + INIT_LIST_HEAD(&sdev->cmd_list); + spin_lock_init(&sdev->list_lock); /* * Some low level driver could use device->type */ @@ -471,10 +473,6 @@ sdev->request_queue->queuedata = sdev; scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); - scsi_build_commandblocks(sdev); - if (sdev->current_queue_depth == 0) { - goto out_bail; - } init_waitqueue_head(&sdev->scpnt_wait); if (shost->hostt->slave_alloc) @@ -515,7 +513,6 @@ } else if (sdev->request_queue) scsi_free_queue(sdev->request_queue); - scsi_release_commandblocks(sdev); kfree(sdev); return NULL; } @@ -535,7 +532,6 @@ if (sdev->request_queue) scsi_free_queue(sdev->request_queue); - scsi_release_commandblocks(sdev); if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); if (sdev->inquiry) diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c --- a/drivers/scsi/scsi_syms.c Sun Feb 9 21:13:32 2003 +++ b/drivers/scsi/scsi_syms.c Sun Feb 9 21:13:32 2003 @@ -39,8 +39,6 @@ EXPORT_SYMBOL(scsicam_bios_param); EXPORT_SYMBOL(scsi_partsize); EXPORT_SYMBOL(scsi_bios_ptable); -EXPORT_SYMBOL(scsi_allocate_device); -EXPORT_SYMBOL(scsi_do_cmd); EXPORT_SYMBOL(scsi_ioctl); EXPORT_SYMBOL(print_command); EXPORT_SYMBOL(print_sense); @@ -50,7 +48,6 @@ EXPORT_SYMBOL(scsi_sense_key_string); EXPORT_SYMBOL(scsi_extd_sense_format); EXPORT_SYMBOL(kernel_scsi_ioctl); -EXPORT_SYMBOL(scsi_release_command); EXPORT_SYMBOL(print_Scsi_Cmnd); EXPORT_SYMBOL(scsi_block_when_processing_errors); EXPORT_SYMBOL(scsi_ioctl_send_command); diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c --- a/drivers/scsi/scsi_sysfs.c Sun Feb 9 21:13:29 2003 +++ b/drivers/scsi/scsi_sysfs.c Sun Feb 9 21:13:29 2003 @@ -210,8 +210,7 @@ * Create the actual show/store functions and data structures. */ sdev_rd_attr (device_blocked, "%d\n"); -sdev_rd_attr (current_queue_depth, "%d\n"); -sdev_rd_attr (new_queue_depth, "%d\n"); +sdev_rd_attr (queue_depth, "%d\n"); sdev_rd_attr (type, "%d\n"); sdev_rd_attr (scsi_level, "%d\n"); sdev_rd_attr (access_count, "%d\n"); @@ -222,8 +221,7 @@ static struct device_attribute * const sdev_attrs[] = { &dev_attr_device_blocked, - &dev_attr_current_queue_depth, - &dev_attr_new_queue_depth, + &dev_attr_queue_depth, &dev_attr_type, &dev_attr_scsi_level, &dev_attr_access_count, diff -Nru a/drivers/scsi/scsiiom.c b/drivers/scsi/scsiiom.c --- a/drivers/scsi/scsiiom.c Sun Feb 9 21:13:28 2003 +++ b/drivers/scsi/scsiiom.c Sun Feb 9 21:13:28 2003 @@ -1591,15 +1591,15 @@ //dc390_Going_remove (pDCB, pSRB); dc390_remove_dev (pACB, pDCB); DCB_removed = 1; - if( (pcmd->target == pACB->pScsiHost->max_id - 1) && - ((pcmd->lun == 0) || (pcmd->lun == pACB->pScsiHost->max_lun - 1)) ) + if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) && + ((pcmd->device->lun == 0) || (pcmd->device->lun == pACB->pScsiHost->max_lun - 1)) ) pACB->scan_devices = 0; } else { /* device present: add */ - if( (pcmd->target == pACB->pScsiHost->max_id - 1) && - (pcmd->lun == pACB->pScsiHost->max_lun - 1) ) + if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) && + (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) ) pACB->scan_devices = END_SCAN ; /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */ } @@ -1624,8 +1624,8 @@ dc390_add_dev (pACB, pDCB, ptr); if (pACB->scan_devices) pACB->DeviceCnt++; } - if( (pcmd->target == pACB->pScsiHost->max_id - 1) && - (pcmd->lun == pACB->pScsiHost->max_lun - 1) ) + if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) && + (pcmd->device->lun == pACB->pScsiHost->max_lun - 1) ) pACB->scan_devices = 0; }; diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c --- a/drivers/scsi/sg.c Sun Feb 9 21:13:31 2003 +++ b/drivers/scsi/sg.c Sun Feb 9 21:13:31 2003 @@ -19,7 +19,7 @@ */ #include #ifdef CONFIG_PROC_FS -static char *sg_version_str = "Version: 3.5.27 (20020812)"; +static char *sg_version_str = "Version: 3.5.27 (20030130)"; #endif static int sg_version_num = 30527; /* 2 digits for each component */ /* @@ -842,7 +842,7 @@ __put_user((int) sdp->device->type, &sg_idp->scsi_type); __put_user((short) sdp->device->host->cmd_per_lun, &sg_idp->h_cmd_per_lun); - __put_user((short) sdp->device->new_queue_depth, + __put_user((short) sdp->device->queue_depth, &sg_idp->d_queue_depth); __put_user(0, &sg_idp->unused[0]); __put_user(0, &sg_idp->unused[1]); @@ -1455,9 +1455,9 @@ sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0; memset(&sdp->sg_driverfs_dev, 0, sizeof (struct device)); - sprintf(sdp->sg_driverfs_dev.bus_id, "%s:gen", + snprintf(sdp->sg_driverfs_dev.bus_id, BUS_ID_SIZE, "%s:gen", scsidp->sdev_driverfs_dev.bus_id); - sprintf(sdp->sg_driverfs_dev.name, "%sgeneric", + snprintf(sdp->sg_driverfs_dev.name, DEVICE_NAME_SIZE, "%sgeneric", scsidp->sdev_driverfs_dev.name); sdp->sg_driverfs_dev.parent = &scsidp->sdev_driverfs_dev; sdp->sg_driverfs_dev.bus = scsidp->sdev_driverfs_dev.bus; @@ -2982,7 +2982,7 @@ scsidp->host->host_no, scsidp->channel, scsidp->id, scsidp->lun, (int) scsidp->type, (int) scsidp->access_count, - (int) scsidp->new_queue_depth, + (int) scsidp->queue_depth, (int) scsidp->device_busy, (int) scsidp->online); else diff -Nru a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c --- a/drivers/scsi/sim710.c Sun Feb 9 21:13:35 2003 +++ b/drivers/scsi/sim710.c Sun Feb 9 21:13:35 2003 @@ -22,96 +22,41 @@ * Some multiboard fixes from Rolf Eike Beer. * Auto probing of EISA config space from Trevor Hemsley. * - * Various bits of code in this driver have been copied from 53c7,8xx,c, - * which is coyright Drew Eckhardt. The scripts for the SCSI chip are - * compiled with the script compiler written by Drew. - * - * This is a simple driver for the NCR53c710. More complex drivers - * for this chip (e.g. 53c7xx.c) require that the scsi chip be able to - * do DMA block moves between memory and on-chip registers, which can - * be a problem if those registers are in the I/O address space. There - * can also be problems on hardware where the registers are memory - * mapped, if the design is such that memory-to-memory transfers initiated - * by the scsi chip cannot access the chip registers. - * - * This driver is designed to avoid these problems and is intended to - * work with any Intel machines using 53c710 chips, including various - * Compaq and NCR machines. It was initially written for the Tadpole - * TP34V VME board which is 68030 based. - * - * The driver supports boot-time parameters similar to - * sim710=addr:0x9000,irq:15 - * and insmod parameters similar to - * sim710="addr:0x9000 irq:15" - * - * Multiple controllers can also be set up by command line, provided the - * addr: parameter is specified first for each controller. e.g. - * sim710="addr:0x9000 irq:15 addr:0x8000 irq:14" - * - * To seperate the different options, ' ', '+', and ',' can be used, except - * that ',' can not be used in module parameters. ' ' can be a pain, because - * it needs to be quoted, which causes problems with some installers. - * The command line above is completely equivalent to - * sim710="addr:0x9000+irq:15+addr:0x8000+irq:14" - * - * The complete list of options are: - * - * addr:0x9000 Specifies the base I/O port (or address) of the 53C710. - * irq:15 Specifies the IRQ number used by the 53c710. - * debug:0xffff Generates lots of debug output. - * ignore:0x0a Makes the driver ignore SCSI IDs 0 and 2. - * nodisc:0x70 Prevents disconnects from IDs 6, 5 and 4. - * noneg:0x10 Prevents SDTR negotiation on ID 4. - * disabled:1 Completely disables the driver. When present, overrides - * all other options. - * - * The driver will auto-probe chip addresses and IRQs now, so typically no - * parameters are needed. Auto-probing of addresses is disabled if any addr: - * parameters are specified. - * - * Current limitations: - * - * o Async only - * o Severely lacking in error recovery - * o 'debug:' should be per host really. + * Rewritten to use 53c700.c by James.Bottomley@SteelEye.com * */ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include +#ifdef CONFIG_MCA #include -#include -#include -#include -#include -#include -#include -#include -#include +#endif +#ifdef CONFIG_EISA +#include +#endif -/* All targets are I/O mapped at the moment */ -#define IO_MAPPED +#include "scsi.h" +#include "hosts.h" +#include "53c700.h" -#if defined(CONFIG_MCA) +/* Must be enough for both EISA and MCA */ +#define MAX_SLOTS 8 +static __u8 __initdata id_array[MAX_SLOTS] = { [0 ... MAX_SLOTS-1] = 7 }; + +/* info is used to communicate global data across the driver register + * because the struct device_driver doesn't have any info fields. Sigh */ +struct sim710_info { + Scsi_Host_Template *tpnt; + int found; +}; -/* - * For each known microchannel card using the 53c710 we need a list - * of possible IRQ and IO settings, as well as their corresponding - * bit assignment in pos[]. This might get cumbersome if there - * are more than a few cards (I only know of 2 at this point). - */ +static __initdata struct sim710_info sim710_global_info; -#define MCA_53C710_IDS { 0x01bb, 0x01ba, 0x004f } +#if defined(CONFIG_MCA) /* CARD ID 01BB and 01BA use the same pos values */ @@ -130,63 +75,6 @@ #endif -#include "scsi.h" -#include "hosts.h" -#include "sim710.h" - -#include - -#define DEBUG -#undef DEBUG_LIMIT_INTS /* Define to 10 to hang driver after 10 ints */ - -/* Debug options available via the "debug:0x1234" parameter */ - -#define DEB_NONE 0x0000 /* Nothing */ -#define DEB_HALT 0x0001 /* Detailed trace of chip halt funtion */ -#define DEB_REGS 0x0002 /* All chip register read/writes */ -#define DEB_SYNC 0x0004 /* Sync/async negotiation */ -#define DEB_PMM 0x0008 /* Phase mis-match handling */ -#define DEB_INTS 0x0010 /* General interrupt trace */ -#define DEB_TOUT 0x0020 /* Selection timeouts */ -#define DEB_RESUME 0x0040 /* Resume addresses for the script */ -#define DEB_CMND 0x0080 /* Commands and status returned */ -#define DEB_FIXUP 0x0100 /* Fixup of scsi addresses */ -#define DEB_DISC 0x0200 /* Disconnect/reselect handling */ - -#define DEB_ANY 0xffff /* Any and all debug options */ - -#ifdef DEBUG -#define DEB(m,x) if (sim710_debug & m) x -int sim710_debug; -#else -#define DEB(m,x) -#endif - -/* Redefine scsi_done to force renegotiation of (a)sync transfers - * following any failed command. - */ - -#define SCSI_DONE(cmd) { \ - DEB(DEB_CMND, printk("scsi%d: Complete %08x\n", \ - host->host_no, cmd->result)); \ - if (cmd->result) \ - hostdata->negotiate |= (1 << cmd->target); \ - cmd->scsi_done(cmd); \ - } - -#ifndef offsetof -#define offsetof(t, m) ((size_t) (&((t *)0)->m)) -#endif - -#define STATE_INITIALISED 0 -#define STATE_HALTED 1 -#define STATE_IDLE 2 -#define STATE_BUSY 3 -#define STATE_DISABLED 4 - -#define MAXBOARDS 4 /* Increase this and the sizes of the - arrays below, if you need more.. */ - #ifdef MODULE char *sim710; /* command line passed by insmod */ @@ -199,1583 +87,294 @@ #endif -static int sim710_errors; /* Count of error interrupts */ -static int sim710_intrs; /* Count of all interrupts */ -static int ignore_ids[MAXBOARDS]; /* Accept all SCSI IDs */ -static int opt_nodisc[MAXBOARDS]; /* Allow disconnect on all IDs */ -static int opt_noneg[MAXBOARDS]; /* Allow SDTR negotiation on all IDs */ -static int hostdata_order; /* Encoded size of hostdata for free_pages() */ -static int no_of_boards; /* Actual number of boards/chips */ -static unsigned int bases[MAXBOARDS]; /* Base addresses of chips */ -static unsigned int irq_vectors[MAXBOARDS]; /* IRQ vectors used by chips */ - -/* The SCSI Script!!! */ - -#include "sim710_d.h" - -/* Now define offsets in the DSA, as (A_dsa_xxx/4) */ - -#define DSA_SELECT (A_dsa_select/4) -#define DSA_MSGOUT (A_dsa_msgout/4) -#define DSA_CMND (A_dsa_cmnd/4) -#define DSA_STATUS (A_dsa_status/4) -#define DSA_MSGIN (A_dsa_msgin/4) -#define DSA_DATAIN (A_dsa_datain/4) -#define DSA_DATAOUT (A_dsa_dataout/4) -#define DSA_SIZE (A_dsa_size/4) - -#define MAX_SG 128 /* Scatter/Gather elements */ - -#define MAX_MSGOUT 8 -#define MAX_MSGIN 8 -#define MAX_CMND 12 -#define MAX_STATUS 1 - -struct sim710_hostdata{ - int state; - Scsi_Cmnd * issue_queue; - Scsi_Cmnd * running; - int chip; - u8 negotiate; - u8 reselected_identify; - u8 msgin_buf[MAX_MSGIN]; - u8 msg_reject; - u32 test1_src __attribute__ ((aligned (4))); - u32 test1_dst; - - struct sim710_target { - Scsi_Cmnd *cur_cmd; - u32 resume_offset; - u32 data_in_jump; - u32 data_out_jump; - u32 dsa[DSA_SIZE]; /* SCSI Script DSA area */ - u8 dsa_msgout[MAX_MSGOUT]; - u8 dsa_msgin[MAX_MSGIN]; - u8 dsa_cdb[MAX_CMND]; - u8 dsa_status[MAX_STATUS]; - } target[8]; - - u32 script[sizeof(SCRIPT)/4] __attribute__ ((aligned (4))); -}; - - -/* Template to request asynchronous transfers */ - -static const unsigned char async_message[] = { - EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 0, 0 /* asynchronous */}; - - -static void sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs); -static void do_sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs); -static __inline__ void run_process_issue_queue(struct sim710_hostdata *); -static void process_issue_queue (struct sim710_hostdata *, unsigned long flags); -static int full_reset(struct Scsi_Host * host); - - -/* - * Function : static void ncr_dump (struct Scsi_Host *host) - * - * Purpose : Dump (possibly) useful info - * - * Inputs : host - pointer to this host adapter's structure - */ - -static void -ncr_dump (struct Scsi_Host *host) -{ - unsigned long flags; - struct sim710_hostdata *hostdata = (struct sim710_hostdata *) - host->hostdata[0]; - - save_flags(flags); - cli(); - printk("scsi%d: Chip register contents:\n", host->host_no); - printk(" (script at virt %p, bus %lx)\n", - hostdata->script, virt_to_bus(hostdata->script)); - printk(" 00 sien: %02x sdid: %02x scntl1:%02x scntl0:%02x\n" - " 04 socl: %02x sodl: %02x sxfer: %02x scid: %02x\n" - " 08 sbcl: %02x sbdl: %02x sidl: %02x sfbr: %02x\n" - " 0C sstat2:%02x sstat1:%02x sstat0:%02x dstat: %02x\n" - " 10 dsa: %08x\n" - " 14 ctest3:%02x ctest2:%02x ctest1:%02x ctest0:%02x\n" - " 18 ctest7:%02x ctest6:%02x ctest5:%02x ctest4:%02x\n" - " 1C temp: %08x\n" - " 20 lcrc: %02x ctest8:%02x istat: %02x dfifo: %02x\n" - " 24 dbc: %08x dnad: %08x dsp: %08x\n" - " 30 dsps: %08x scratch:%08x\n" - " 38 dcntl: %02x dwt: %02x dien: %02x dmode: %02x\n" - " 3C adder: %08x\n", - NCR_read8(SIEN_REG), NCR_read8(SDID_REG), NCR_read8(SCNTL1_REG), - NCR_read8(SCNTL0_REG), NCR_read8(SOCL_REG), NCR_read8(SODL_REG), - NCR_read8(SXFER_REG), NCR_read8(SCID_REG), NCR_read8(SBCL_REG), - NCR_read8(SBDL_REG), NCR_read8(SIDL_REG), NCR_read8(SFBR_REG), - NCR_read8(SSTAT2_REG), NCR_read8(SSTAT1_REG), NCR_read8(SSTAT0_REG), - NCR_read8(DSTAT_REG), NCR_read32(DSA_REG), NCR_read8(CTEST3_REG), - NCR_read8(CTEST2_REG), NCR_read8(CTEST1_REG), NCR_read8(CTEST0_REG), - NCR_read8(CTEST7_REG), NCR_read8(CTEST6_REG), NCR_read8(CTEST5_REG), - NCR_read8(CTEST4_REG), NCR_read8(TEMP_REG), NCR_read8(LCRC_REG), - NCR_read8(CTEST8_REG), NCR_read8(ISTAT_REG), NCR_read8(DFIFO_REG), - NCR_read32(DBC_REG), NCR_read32(DNAD_REG), NCR_read32(DSP_REG), - NCR_read32(DSPS_REG), NCR_read32(SCRATCH_REG), NCR_read8(DCNTL_REG), - NCR_read8(DWT_REG), NCR_read8(DIEN_REG), NCR_read8(DMODE_REG), - NCR_read32(ADDER_REG)); - - restore_flags(flags); -} - - -/* - * Function: int param_setup(char *str) - */ +#ifdef MODULE +#define ARG_SEP ' ' +#else +#define ARG_SEP ',' +#endif __init int param_setup(char *str) { - char *cur = str; - char *p, *pc, *pv; - int val; - int c; - - no_of_boards = 0; - while (no_of_boards < MAXBOARDS && cur != NULL && - (pc = strchr(cur, ':')) != NULL) { - char *pe; - - val = 0; - pv = pc; - c = *++pv; + char *pos = str, *next; + int slot = -1; - val = (int) simple_strtoul(pv, &pe, 0); + while(pos != NULL && (next = strchr(pos, ':')) != NULL) { + int val = (int)simple_strtoul(++next, NULL, 0); - if (!strncmp(cur, "addr:", 5)) { - bases[no_of_boards++] = val; - } -#ifdef DEBUG - else if (!strncmp(cur, "debug:", 6)) { - sim710_debug = val; - } -#endif - else if (no_of_boards == 0) { - printk("sim710: Invalid parameters, addr: must come first\n"); - no_of_boards = -1; - return 1; - } - else if (!strncmp(cur, "irq:", 4)) - irq_vectors[no_of_boards-1] = val; - else if (!strncmp(cur, "ignore:", 7)) - ignore_ids[no_of_boards-1] = val; - else if (!strncmp(cur, "nodisc:", 7)) - opt_nodisc[no_of_boards-1] = val; - else if (!strncmp(cur, "noneg:", 6)) - opt_noneg[no_of_boards-1] = val; - else if (!strncmp(cur, "disabled:", 9)) { - no_of_boards = -1; - return 1; - } - else { - printk("sim710: unexpected boot option '%.*s'\n", (int)(pc-cur+1), cur); - no_of_boards = -1; - return 1; + if(!strncmp(pos, "slot:", 5)) + slot = val; + else if(!strncmp(pos, "id:", 3)) { + if(slot == -1) { + printk(KERN_WARNING "sim710: Must specify slot for id parameter\n"); + } else if(slot > MAX_SLOTS) { + printk(KERN_WARNING "sim710: Illegal slot %d for id %d\n", slot, val); + } else { + id_array[slot] = val; + } + } + if((pos = strchr(pos, ARG_SEP)) != NULL) + pos++; } - - /* Allow ',', ' ', or '+' seperators. Used to be ',' at boot and - * ' ' for module load, some installers crap out on the space and - * insmod doesn't like the comma. - */ - if ((p = strchr(cur, ',')) || (p = strchr(cur, ' ')) || - (p = strchr(cur, '+'))) - cur = p + 1; - else - break; - } - return 1; + return 1; } #ifndef MODULE __setup("sim710=", param_setup); #endif - -/* - * Function: static const char *sbcl_to_phase (int sbcl) - */ - -static const char * -sbcl_to_phase (int sbcl) { - switch (sbcl & SBCL_PHASE_MASK) { - case SBCL_PHASE_DATAIN: - return "DATAIN"; - case SBCL_PHASE_DATAOUT: - return "DATAOUT"; - case SBCL_PHASE_MSGIN: - return "MSGIN"; - case SBCL_PHASE_MSGOUT: - return "MSGOUT"; - case SBCL_PHASE_CMDOUT: - return "CMDOUT"; - case SBCL_PHASE_STATIN: - return "STATUSIN"; - default: - return "unknown"; - } -} - - -/* - * Function : static int ncr_halt (struct Scsi_Host *host) - * - * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip - * - * Inputs : host - SCSI chip to halt - * - * Returns : 0 on success - */ - -static int -ncr_halt (struct Scsi_Host *host) -{ - unsigned long flags; - unsigned char istat, tmp; - struct sim710_hostdata *hostdata = (struct sim710_hostdata *) - host->hostdata[0]; - int stage; - int timeout; - int res = 0; - - save_flags(flags); - cli(); - /* Stage 0 : eat all interrupts - Stage 1 : set ABORT - Stage 2 : eat all but abort interrupts - Stage 3 : eat all interrupts - We loop for 50000 times with a delay of 10us which should give us - about half a second. - */ - for (stage = 0, timeout = 50000; timeout; timeout--) { - if (stage == 1) { - DEB(DEB_HALT, printk("ncr_halt: writing ISTAT_ABRT\n")); - NCR_write8(ISTAT_REG, ISTAT_ABRT); - ++stage; - } - istat = NCR_read8 (ISTAT_REG); - if (istat & ISTAT_SIP) { - DEB(DEB_HALT, printk("ncr_halt: got ISTAT_SIP, istat=%02x\n", istat)); - tmp = NCR_read8(SSTAT0_REG); - DEB(DEB_HALT, printk("ncr_halt: got SSTAT0_REG=%02x\n", tmp)); - } else if (istat & ISTAT_DIP) { - DEB(DEB_HALT, printk("ncr_halt: got ISTAT_DIP, istat=%02x\n", istat)); - tmp = NCR_read8(DSTAT_REG); - DEB(DEB_HALT, printk("ncr_halt: got DSTAT_REG=%02x\n", tmp)); - if (stage == 2) { - if (tmp & DSTAT_ABRT) { - DEB(DEB_HALT, printk("ncr_halt: got DSTAT_ABRT, clearing istat\n")); - NCR_write8(ISTAT_REG, 0); - ++stage; - } else { - res = 1; - break; - } - } - } - if (!(istat & (ISTAT_SIP|ISTAT_DIP))) { - if (stage == 0) - ++stage; - else if (stage == 3) - break; - } - udelay(10); - } - restore_flags(flags); - - if (timeout == 0 || res) { - printk(KERN_ALERT "scsi%d: could not halt NCR chip\n", host->host_no); - return 1; - } - else { - hostdata->state = STATE_HALTED; - return 0; - } -} - -/* - * Function : static void sim710_soft_reset (struct Scsi_Host *host) - * - * Purpose : perform a soft reset of the NCR53c7xx chip - * - * Inputs : host - pointer to this host adapter's structure - * - * Preconditions : sim710_init must have been called for this - * host. - * - */ - -static void -sim710_soft_reset (struct Scsi_Host *host) -{ - unsigned long flags; - - save_flags(flags); - cli(); - /* - * Do a soft reset of the chip so that everything is - * reinitialized to the power-on state. - * - * Basically follow the procedure outlined in the NCR53c700 - * data manual under Chapter Six, How to Use, Steps Necessary to - * Start SCRIPTS, with the exception of actually starting the - * script and setting up the synchronous transfer gunk. - */ - - /* XXX Should we reset the scsi bus here? */ - - NCR_write8(SCNTL1_REG, SCNTL1_RST); /* Reset the bus */ - udelay(50); - NCR_write8(SCNTL1_REG, 0); - - udelay(500); - - NCR_write8(ISTAT_REG, ISTAT_10_SRST); /* Reset the chip */ - udelay(50); - NCR_write8(ISTAT_REG, 0); - - mdelay(1000); /* Let devices recover */ - - NCR_write32(SCRATCH_REG, 0); - NCR_write8(DCNTL_REG, DCNTL_10_COM | DCNTL_700_CF_3); - NCR_write8(CTEST7_REG, CTEST7_10_CDIS|CTEST7_STD); - NCR_write8(DMODE_REG, DMODE_10_BL_8 | DMODE_10_FC2); - NCR_write8(SCID_REG, 1 << host->this_id); - NCR_write8(SBCL_REG, 0); - NCR_write8(SXFER_REG, 0); - NCR_write8(SCNTL1_REG, SCNTL1_ESR_700); - NCR_write8(SCNTL0_REG, SCNTL0_EPC | SCNTL0_EPG_700 | SCNTL0_ARB1 | - SCNTL0_ARB2); - - NCR_write8(DIEN_REG, DIEN_700_BF | - DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_700_OPC); - - NCR_write8(SIEN_REG_700, - SIEN_PAR | SIEN_700_STO | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA); - - restore_flags(flags); -} - - -/* - * Function : static void sim710_driver_init (struct Scsi_Host *host) - * - * Purpose : Initialize internal structures, as required on startup, or - * after a SCSI bus reset. - * - * Inputs : host - pointer to this host adapter's structure - */ - -static void -sim710_driver_init (struct Scsi_Host *host) -{ - struct sim710_hostdata *hostdata = (struct sim710_hostdata *) - host->hostdata[0]; - int i; - - hostdata->running = NULL; - memcpy (hostdata->script, SCRIPT, sizeof(SCRIPT)); - for (i = 0; i < PATCHES; i++) - hostdata->script[LABELPATCHES[i]] += isa_virt_to_bus(hostdata->script); - patch_abs_32 (hostdata->script, 0, reselected_identify, - isa_virt_to_bus((void *)&(hostdata->reselected_identify))); - patch_abs_32 (hostdata->script, 0, msgin_buf, - isa_virt_to_bus((void *)&(hostdata->msgin_buf[0]))); - patch_abs_32 (hostdata->script, 0, msg_reject, - isa_virt_to_bus((void *)&(hostdata->msg_reject))); - patch_abs_32 (hostdata->script, 0, test1_src, - isa_virt_to_bus((void *)&(hostdata->test1_src))); - patch_abs_32 (hostdata->script, 0, test1_dst, - isa_virt_to_bus((void *)&(hostdata->test1_dst))); - hostdata->state = STATE_INITIALISED; - hostdata->negotiate = 0xff; -} - - -/* Handle incoming Synchronous data transfer request. If our negotiate - * flag is set then this is a response to our request, otherwise it is - * spurious request from the target. Don't really expect target initiated - * SDTRs, because we always negotiate on the first command. Could still - * get them though.. - * The chip is currently paused with ACK asserted on the last byte of the - * SDTR. - * resa is the resume address if the message is in response to our outgoing - * SDTR. Only possible on initial identify. - * resb is the resume address if the message exchange is initiated by the - * target. - */ - -static u32 -handle_sdtr (struct Scsi_Host * host, Scsi_Cmnd * cmd, u32 resa, u32 resb) -{ - struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0]; - struct sim710_target *targdata = hostdata->target + cmd->target; - u32 resume_offset; - - if (resa && hostdata->negotiate & (1 << cmd->target)) { - DEB(DEB_SYNC, printk("scsi%d: Response to host SDTR = %02x %02x\n", - host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4])); - /* We always issue an SDTR with the identify, so we must issue - * the CDB next. - */ - resume_offset = resa; - hostdata->negotiate &= ~(1 << cmd->target); - } - else { - DEB(DEB_SYNC, printk("scsi%d: Target initiated SDTR = %02x %02x\n", - host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4])); - memcpy(targdata->dsa_msgout, async_message, sizeof(async_message)); - targdata->dsa[DSA_MSGOUT] = sizeof(async_message); - /* I guess the target could do this anytime; we have to send our - * response, and then continue (sending the CDB if not already done). - */ - resume_offset = resb; - } - return resume_offset; -} - - -/* - * Function : static int datapath_residual (Scsi_Host *host) - * - * Purpose : return residual data count of what's in the chip. - * - * Inputs : host - SCSI host - */ - -static int -datapath_residual (struct Scsi_Host *host) { - int count, synchronous, sstat; - unsigned int ddir; - - count = ((NCR_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) - - (NCR_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK; - synchronous = NCR_read8 (SXFER_REG) & SXFER_MO_MASK; - ddir = NCR_read8 (CTEST0_REG_700) & CTEST0_700_DDIR; - - if (ddir) { - /* Receive */ - if (synchronous) - count += (NCR_read8 (SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT; - else - if (NCR_read8 (SSTAT1_REG) & SSTAT1_ILF) - ++count; - } else { - /* Send */ - sstat = NCR_read8 (SSTAT1_REG); - if (sstat & SSTAT1_OLF) - ++count; - if (synchronous && (sstat & SSTAT1_ORF)) - ++count; - } - return count; -} - - -static u32 -handle_idd (struct Scsi_Host * host, Scsi_Cmnd * cmd) +__init int +sim710_probe_common(struct device *dev, unsigned long base_addr, + int irq, int clock, int differential, int scsi_id) { - struct sim710_hostdata *hostdata = - (struct sim710_hostdata *)host->hostdata[0]; - struct sim710_target *targdata = hostdata->target + cmd->target; - u32 resume_offset = 0, index; - - index = (u32)((u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script); - - switch (index) { - case Ent_wait_disc_complete/4 + 2: - cmd->result = targdata->dsa_status[0]; - SCSI_DONE(cmd); - targdata->cur_cmd = NULL; - resume_offset = Ent_reselect; - break; - case Ent_wait_disc2/4 + 2: - /* Disconnect after command - just wait for a reselect */ - targdata->resume_offset = Ent_resume_msgin2a; - resume_offset = Ent_reselect; - break; - case Ent_wait_disc3/4 + 2: - /* Disconnect after the data phase */ - targdata->resume_offset = Ent_resume_msgin3a; - resume_offset = Ent_reselect; - break; - case Ent_wait_disc1/4 + 2: - /* Disconnect before command - not expected */ - targdata->resume_offset = Ent_resume_msgin1a; - resume_offset = Ent_reselect; - break; - default: - printk("scsi%d: Unexpected Illegal Instruction, script[%04x]\n", - host->host_no, index); - sim710_errors++; - /* resume_offset is zero, which will cause host reset */ - } - return resume_offset; -} + struct Scsi_Host * host = NULL; + struct NCR_700_Host_Parameters *hostdata = + kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + printk(KERN_NOTICE "sim710: %s\n", dev->name); + printk(KERN_NOTICE "sim710: irq = %d, clock = %d, base = 0x%lx, scsi_id = %d\n", + irq, clock, base_addr, scsi_id); -/* Handle a phase mismatch. - */ - -static u32 -handle_phase_mismatch (struct Scsi_Host * host, Scsi_Cmnd * cmd) -{ - struct sim710_hostdata *hostdata = - (struct sim710_hostdata *)host->hostdata[0]; - struct sim710_target *targdata = hostdata->target + cmd->target; - u32 resume_offset = 0, index; - unsigned char sbcl; - - sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK; - index = (u32)((u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script); - - DEB(DEB_PMM, printk("scsi%d: Phase mismatch, phase %s (%x) at script[0x%x]\n", - host->host_no, sbcl_to_phase(sbcl), sbcl, index)); - DEB(DEB_PMM, print_command(cmd->cmnd)); - - if (index == Ent_done_ident/4) { - /* Sending initial message out - probably rejecting our sync - * negotiation request. - */ - NCR_write8(SOCL_REG, 0); /* Negate ATN */ - if (sbcl == SBCL_PHASE_MSGIN) - resume_offset = Ent_resume_rej_ident; - else if (sbcl == SBCL_PHASE_CMDOUT) { - /* Some old devices (SQ555) switch to cmdout after the first - * byte of an identify message, regardless of whether we - * have more bytes to send! - */ - printk("scsi%d: Unexpected switch to CMDOUT during IDENTIFY\n", - host->host_no); - resume_offset = Ent_resume_cmd; + if(hostdata == NULL) { + printk(KERN_ERR "sim710: Failed to allocate host data\n"); + goto out; } - else if (sbcl == SBCL_PHASE_STATIN) { - /* Some devices do this on parity error, at least */ - printk("scsi%d: Unexpected switch to STATUSIN on initial message out\n", - host->host_no); - resume_offset = Ent_end_data_trans; - } - else { - printk("scsi%d: Unexpected phase change to %s on initial msgout\n", - host->host_no, sbcl_to_phase(sbcl)); - /* resume_offset is zero, which will cause a host reset */ - } - hostdata->negotiate &= ~(1 << cmd->target); - } - else if (index > Ent_patch_input_data/4 && - index < Ent_patch_output_data/4) { - /* DataIn transfer phase */ - u32 sg_id, oaddr, olen, naddr, nlen; - int residual; - - sg_id = (index - Ent_patch_input_data/4 - 4) / 2; - targdata->data_in_jump = hostdata->script[Ent_patch_input_data/4+1] = - isa_virt_to_bus(hostdata->script + Ent_patch_input_data/4 + sg_id * 2 + 2); - olen = targdata->dsa[DSA_DATAIN + sg_id * 2]; - oaddr = targdata->dsa[DSA_DATAIN + sg_id * 2 + 1]; - residual = datapath_residual (host); - if (residual) - printk("scsi%d: Residual count %d on DataIn - NOT expected!!!", - host->host_no, residual); - naddr = NCR_read32(DNAD_REG) - residual; - nlen = (NCR_read32(DBC_REG) & 0x00ffffff) + residual; - DEB(DEB_PMM, printk("scsi%d: DIN sg %d, old %08x/%08x, new %08x/%08x (%d)\n", - host->host_no, sg_id, oaddr, olen, naddr, nlen, residual)); - if (oaddr+olen != naddr+nlen) { - printk("scsi%d: PMM DIN counts error: 0x%x + 0x%x != 0x%x + 0x%x", - host->host_no, oaddr, olen, naddr, nlen); - } - else { - targdata->dsa[DSA_DATAIN + sg_id * 2] = nlen; - targdata->dsa[DSA_DATAIN + sg_id * 2 + 1] = naddr; - resume_offset = Ent_resume_pmm; - } - } - else if (index > Ent_patch_output_data/4 && - index <= Ent_end_data_trans/4) { - /* Dataout transfer phase */ - u32 sg_id, oaddr, olen, naddr, nlen; - int residual; - - sg_id = (index - Ent_patch_output_data/4 - 4) / 2; - targdata->data_out_jump = hostdata->script[Ent_patch_output_data/4+1] = - isa_virt_to_bus(hostdata->script + Ent_patch_output_data/4 + sg_id * 2 + 2); - olen = targdata->dsa[DSA_DATAOUT + sg_id * 2]; - oaddr = targdata->dsa[DSA_DATAOUT + sg_id * 2 + 1]; - residual = datapath_residual (host); - naddr = NCR_read32(DNAD_REG) - residual; - nlen = (NCR_read32(DBC_REG) & 0x00ffffff) + residual; - DEB(DEB_PMM, printk("scsi%d: DOUT sg %d, old %08x/%08x, new %08x/%08x (%d)\n", - host->host_no, sg_id, oaddr, olen, naddr, nlen, residual)); - if (oaddr+olen != naddr+nlen) { - printk("scsi%d: PMM DOUT counts error: 0x%x + 0x%x != 0x%x + 0x%x", - host->host_no, oaddr, olen, naddr, nlen); - } - else { - targdata->dsa[DSA_DATAOUT + sg_id * 2] = nlen; - targdata->dsa[DSA_DATAOUT + sg_id * 2 + 1] = naddr; - resume_offset = Ent_resume_pmm; - } - } - else if (sbcl == SBCL_PHASE_STATIN) { - /* Change to Status In at some random point; probably wants to report a - * parity error or similar. - */ - printk("scsi%d: Unexpected phase change to STATUSIN at index 0x%x\n", - host->host_no, index); - resume_offset = Ent_end_data_trans; - } - else { - printk("scsi%d: Unexpected phase change to %s at index 0x%x\n", - host->host_no, sbcl_to_phase(sbcl), index); - /* resume_offset is zero, which will cause a host reset */ - } - /* Flush DMA FIFO */ - NCR_write8 (CTEST8_REG, CTEST8_10_CLF); - while (NCR_read8 (CTEST8_REG) & CTEST8_10_CLF); - - return resume_offset; -} - - -static u32 -handle_script_int(struct Scsi_Host * host, Scsi_Cmnd * cmd) -{ - struct sim710_hostdata *hostdata = - (struct sim710_hostdata *)host->hostdata[0]; - struct sim710_target *targdata = hostdata->target + cmd->target; - u32 dsps, resume_offset = 0; - unsigned char sbcl; - - dsps = NCR_read32(DSPS_REG); - - switch (dsps) { - case A_int_cmd_complete: - cmd->result = targdata->dsa_status[0]; - SCSI_DONE(cmd); - targdata->cur_cmd = NULL; - resume_offset = Ent_reselect; - break; - case A_int_msg_sdtr1: - resume_offset = handle_sdtr(host, cmd, - Ent_resume_msgin1a, Ent_resume_msgin1b); - break; - case A_int_msg_sdtr2: - resume_offset = handle_sdtr(host, cmd, 0, Ent_resume_msgin2b); - break; - case A_int_msg_sdtr3: - resume_offset = handle_sdtr(host, cmd, 0, Ent_resume_msgin3b); - break; - case A_int_disc1: - /* Disconnect before command - not expected */ - targdata->resume_offset = Ent_resume_msgin1a; - resume_offset = Ent_reselect; - break; - case A_int_disc2: - /* Disconnect after command - just wait for a reselect */ - targdata->resume_offset = Ent_resume_msgin2a; - resume_offset = Ent_reselect; - break; - case A_int_disc3: - /* Disconnect after the data phase */ - targdata->resume_offset = Ent_resume_msgin3a; - resume_offset = Ent_reselect; - break; - case A_int_reselected: - hostdata->script[Ent_patch_output_data/4+1] = targdata->data_out_jump; - hostdata->script[Ent_patch_input_data/4+1] = targdata->data_in_jump; - NCR_write32(DSA_REG, isa_virt_to_bus(targdata->dsa)); - resume_offset = targdata->resume_offset; - break; - case A_int_data_bad_phase: - sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK; - printk("scsi%d: int_data_bad_phase, phase %s (%x)\n", - host->host_no, sbcl_to_phase(sbcl), sbcl); - break; - case A_int_bad_msg1: - case A_int_bad_msg2: - case A_int_bad_msg3: - case A_int_cmd_bad_phase: - case A_int_no_msgout1: - case A_int_no_msgout2: - case A_int_no_msgout3: - case A_int_not_cmd_complete: - case A_int_sel_no_ident: - case A_int_sel_not_cmd: - case A_int_status_not_msgin: - case A_int_resel_not_msgin: - case A_int_selected: - case A_int_not_rej: - default: - sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK; - printk("scsi%d: Unimplemented script interrupt: %08x, phase %s\n", - host->host_no, dsps, sbcl_to_phase(sbcl)); - sim710_errors++; - /* resume_offset is zero, which will cause a host reset */ - } - return resume_offset; -} - - -/* A quick wrapper for sim710_intr_handle to grab the spin lock */ - -static void -do_sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs) -{ - struct Scsi_Host *host = dev_id; - unsigned long flags; + memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); - spin_lock_irqsave(host->host_lock, flags); - sim710_intr_handle(irq, host, regs); - spin_unlock_irqrestore(host->host_lock, flags); -} - - -/* A "high" level interrupt handler */ - -static void -sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs) -{ - struct Scsi_Host * host = (struct Scsi_Host *)dev_id; - struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0]; - Scsi_Cmnd * cmd; - unsigned char istat, dstat; - unsigned char sstat0; - u32 scratch, dsps, resume_offset = 0; - - istat = NCR_read8(ISTAT_REG); - if (!(istat & (ISTAT_SIP|ISTAT_DIP))) - return; - else { - sim710_intrs++; - dsps = NCR_read32(DSPS_REG); - hostdata->state = STATE_HALTED; - sstat0 = dstat = 0; - scratch = NCR_read32(SCRATCH_REG); - if (istat & ISTAT_SIP) { - sstat0 = NCR_read8(SSTAT0_REG); - } - if (istat & ISTAT_DIP) { - udelay(10); /* Some comment somewhere about 10cycles - * between accesses to sstat0 and dstat ??? */ - dstat = NCR_read8(DSTAT_REG); - } - DEB(DEB_INTS, printk("scsi%d: Int %d, istat %02x, sstat0 %02x " - "dstat %02x, dsp [%04x], scratch %02x\n", - host->host_no, sim710_intrs, istat, sstat0, dstat, - (u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script, - scratch)); - if (scratch & 0x100) { - u8 *p = hostdata->msgin_buf; - - DEB(DEB_INTS, printk(" msgin_buf: %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3])); - } - if ((dstat & DSTAT_SIR) && dsps == A_int_reselected) { - /* Reselected. Identify the target from LCRC_REG, and - * update current command. If we were trying to select - * a device, then that command needs to go back on the - * issue_queue for later. - */ - unsigned char lcrc = NCR_read8(LCRC_REG_10); - int id = 0; - - if (!(lcrc & 0x7f)) { - printk("scsi%d: Reselected with LCRC = %02x\n", - host->host_no, lcrc); - cmd = NULL; - } - else { - while (!(lcrc & 1)) { - id++; - lcrc >>= 1; - } - DEB(DEB_DISC, printk("scsi%d: Reselected by ID %d\n", - host->host_no, id)); - if (hostdata->running) { - /* Clear SIGP */ - (void)NCR_read8(CTEST2_REG_700); - - DEB(DEB_DISC, printk("scsi%d: Select of %d interrupted " - "by reselect from %d (%p)\n", - host->host_no, hostdata->running->target, - id, hostdata->target[id].cur_cmd)); - cmd = hostdata->running; - hostdata->target[cmd->target].cur_cmd = NULL; - cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue; - hostdata->issue_queue = cmd; - } - cmd = hostdata->running = hostdata->target[id].cur_cmd; - } + if(request_region(base_addr, 64, "sim710") == NULL) { + printk(KERN_ERR "sim710: Failed to reserve IO region 0x%lx\n", + base_addr); + goto out_free; } - else - cmd = hostdata->running; - if (!cmd) { - printk("scsi%d: No active command!\n", host->host_no); - printk("scsi%d: Int %d, istat %02x, sstat0 %02x " - "dstat %02x, dsp [%04x], scratch %02x, dsps %08x\n", - host->host_no, sim710_intrs, istat, sstat0, dstat, - (u32 *)(isa_bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script, - NCR_read32(SCRATCH_REG), dsps); - /* resume_offset is zero, which will cause a host reset */ - } - else if (sstat0 & SSTAT0_700_STO) { - DEB(DEB_TOUT, printk("scsi%d: Selection timeout\n", host->host_no)); - cmd->result = DID_NO_CONNECT << 16; - SCSI_DONE(cmd); - hostdata->target[cmd->target].cur_cmd = NULL; - resume_offset = Ent_reselect; - } - else if (sstat0 & (SSTAT0_SGE|SSTAT0_UDC|SSTAT0_RST|SSTAT0_PAR)) { - printk("scsi%d: Serious error, sstat0 = %02x\n", host->host_no, - sstat0); - sim710_errors++; - /* resume_offset is zero, which will cause a host reset */ - } - else if (dstat & (DSTAT_BF|DSTAT_ABRT|DSTAT_SSI|DSTAT_WTD)) { - printk("scsi%d: Serious error, dstat = %02x\n", host->host_no, - dstat); - sim710_errors++; - /* resume_offset is zero, which will cause a host reset */ - } - else if (dstat & DSTAT_SIR) - resume_offset = handle_script_int(host, cmd); - else if (sstat0 & SSTAT0_MA) - resume_offset = handle_phase_mismatch(host, cmd); - else if (dstat & DSTAT_IID) { - /* This can be due to a quick reselect while doing a WAIT - * DISCONNECT. - */ - resume_offset = handle_idd(host, cmd); - } - else { - sim710_errors++; - printk("scsi%d: Spurious interrupt!\n", host->host_no); - /* resume_offset is zero, which will cause a host reset */ - } - } + /* Fill in the three required pieces of hostdata */ + hostdata->base = base_addr; + hostdata->differential = differential; + hostdata->clock = clock; + hostdata->chip710 = 1; - if (resume_offset) { - if (resume_offset == Ent_reselect) { - hostdata->running = NULL; - hostdata->state = STATE_IDLE; + /* and register the chip */ + if((host = NCR_700_detect(sim710_global_info.tpnt, hostdata)) == NULL) { + printk(KERN_ERR "sim710: No host detected; card configuration problem?\n"); + goto out_release; } - else - hostdata->state = STATE_BUSY; - DEB(DEB_RESUME, printk("scsi%d: Resuming at script[0x%x]\n", - host->host_no, resume_offset/4)); -#ifdef DEBUG_LIMIT_INTS - if (sim710_intrs < DEBUG_LIMIT_INTS) -#endif - { - NCR_write32(SCRATCH_REG, 0); - NCR_write32(DSP_REG, - isa_virt_to_bus(hostdata->script+resume_offset/4)); - } - if (resume_offset == Ent_reselect) - run_process_issue_queue(hostdata); - } - else { - printk("scsi%d: Failed to handle interrupt. Failing commands " - "and resetting SCSI bus and chip\n", host->host_no); - mdelay(1000); /* Give chance to read screen!! */ - full_reset(host); - } - -} + host->irq = irq; + host->this_id = scsi_id; -static void -run_command (struct sim710_hostdata *hostdata, Scsi_Cmnd *cmd) -{ - struct Scsi_Host *host = cmd->host; - struct sim710_target *targdata = hostdata->target + cmd->target; - int i, datain, dataout, sg_start; - u32 *dip, *dop, dsa; - - DEB(DEB_CMND, printk("scsi%d: id%d starting ", host->host_no, - cmd->target)); - DEB(DEB_CMND, print_command(cmd->cmnd)); - - switch (cmd->cmnd[0]) { - case INQUIRY: - case MODE_SENSE: - case READ_6: - case READ_10: - case READ_CAPACITY: - case REQUEST_SENSE: - case READ_BLOCK_LIMITS: - case READ_TOC: - datain = 1; - dataout = 0; - break; - case MODE_SELECT: - case WRITE_6: - case WRITE_10: - datain = 0; - dataout = 1; - break; - case TEST_UNIT_READY: - case ALLOW_MEDIUM_REMOVAL: - case START_STOP: - datain = dataout = 0; - break; - default: - datain = dataout = 1; - } - - memcpy(targdata->dsa_cdb, cmd->cmnd, MAX_CMND); - - targdata->dsa_msgout[0] = - IDENTIFY((opt_nodisc[hostdata->chip] & (1<target)) ? 0 : 1 ,0); - if (hostdata->negotiate & (1 << cmd->target)) { - if (opt_noneg[hostdata->chip] & (1 << cmd->target)) { - hostdata->negotiate ^= (1 << cmd->target); - targdata->dsa[DSA_MSGOUT] = 1; - } - else { - DEB(DEB_SYNC, printk("scsi%d: Negotiating async transfers " - "for ID %d\n", - host->host_no, cmd->target)); - memcpy(targdata->dsa_msgout+1, async_message, sizeof(async_message)); - targdata->dsa[DSA_MSGOUT] = sizeof(async_message) + 1; - } - } - else - targdata->dsa[DSA_MSGOUT] = 1; - - targdata->dsa_msgin[0] = 0xff; - targdata->dsa_status[0] = 0xff; - - targdata->dsa[DSA_SELECT] = (1 << cmd->target) << 16; - targdata->dsa[DSA_MSGOUT+1] = isa_virt_to_bus(targdata->dsa_msgout); - targdata->dsa[DSA_CMND] = cmd->cmd_len; - targdata->dsa[DSA_CMND+1] = isa_virt_to_bus(targdata->dsa_cdb); - targdata->dsa[DSA_STATUS] = 1; - targdata->dsa[DSA_STATUS+1] = isa_virt_to_bus(targdata->dsa_status); - targdata->dsa[DSA_MSGIN] = 1; - targdata->dsa[DSA_MSGIN+1] = isa_virt_to_bus(targdata->dsa_msgin); - - sg_start = (MAX_SG - (cmd->use_sg ? cmd->use_sg : 1)) * 2; - dip = targdata->dsa + DSA_DATAIN + sg_start; - dop = targdata->dsa + DSA_DATAOUT + sg_start; - - for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; i++) { - struct scatterlist *sgl = &((struct scatterlist *)cmd->buffer)[i]; - void *vbuf = cmd->use_sg ? - (page_address(sgl->page) + sgl->offset) : - (cmd->request_buffer); - u32 bbuf = isa_virt_to_bus(vbuf); - u32 cnt = cmd->use_sg ? sgl->length : cmd->request_bufflen; - - if (datain) { - *dip++ = cnt; - *dip++ = bbuf; - } - if (dataout) { - *dop++ = cnt; - *dop++ = bbuf; + if(request_irq(irq, NCR_700_intr, SA_SHIRQ, "sim710", host)) { + printk(KERN_ERR "sim710: irq problem with %d, detaching\n", + irq); + goto out_unregister; } - } - targdata->data_out_jump = hostdata->script[Ent_patch_output_data/4+1] = - isa_virt_to_bus(hostdata->script + Ent_patch_output_data/4 + sg_start + 2); - targdata->data_in_jump = hostdata->script[Ent_patch_input_data/4+1] = - isa_virt_to_bus(hostdata->script + Ent_patch_input_data/4 + sg_start + 2); - - for (i = 0, dsa = isa_virt_to_bus(targdata->dsa); i < 4; i++) { - u32 v = hostdata->script[Ent_patch_new_dsa/4 + i * 2]; - - v &= ~0x0000ff00; - v |= (dsa & 0xff) << 8; - hostdata->script[Ent_patch_new_dsa/4 + i * 2] = v; - dsa >>= 8; - } - hostdata->running = targdata->cur_cmd = cmd; - hostdata->state = STATE_BUSY; - NCR_write8(ISTAT_REG, ISTAT_10_SIGP); -} - - -static volatile int process_issue_queue_running = 0; - -static __inline__ void -run_process_issue_queue(struct sim710_hostdata *hostdata) -{ - unsigned long flags; - save_flags (flags); - cli(); - if (!process_issue_queue_running) { - process_issue_queue_running = 1; - process_issue_queue(hostdata, flags); - /* - * process_issue_queue_running is cleared in process_issue_queue - * once it can't do more work, and process_issue_queue exits with - * interrupts disabled. - */ - } - restore_flags (flags); -} + scsi_set_device(host, dev); + hostdata->dev = dev; + sim710_global_info.found++; -/* - * Function : process_issue_queue (hostdata, flags) - * - * Purpose : Start next command for any idle target. - * - * NOTE : process_issue_queue exits with interrupts *disabled*, so the - * caller must reenable them if it desires. - * - * NOTE : process_issue_queue should be called from both - * sim710_queue_command() and from the interrupt handler - * after command completion. - */ - -static void -process_issue_queue (struct sim710_hostdata *hostdata, unsigned long flags) -{ - Scsi_Cmnd *tmp, *prev; - int done; - - /* - * We run (with interrupts disabled) until we're sure that none of - * the host adapters have anything that can be done, at which point - * we set process_issue_queue_running to 0 and exit. - * - * Interrupts are enabled before doing various other internal - * instructions, after we've decided that we need to run through - * the loop again. - * - */ - - do { - cli(); /* Freeze request queues */ - done = 1; - if (hostdata->issue_queue) { - if (hostdata->state == STATE_DISABLED) { - tmp = (Scsi_Cmnd *) hostdata->issue_queue; - hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr; - tmp->result = (DID_BAD_TARGET << 16); - tmp->scsi_done (tmp); - done = 0; - } - else if (hostdata->state == STATE_IDLE) { - for (tmp = hostdata->issue_queue, prev = NULL; tmp; - prev = tmp, tmp = (Scsi_Cmnd *) tmp->SCp.ptr) { - if (hostdata->target[tmp->target].cur_cmd == NULL) { - if (prev) - prev->SCp.ptr = tmp->SCp.ptr; - else - hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr; - tmp->SCp.ptr = NULL; - run_command (hostdata, tmp); - done = 0; - } /* if target/lun is not busy */ - } /* scan issue queue for work */ - } /* host is idle */ - } /* if hostdata->issue_queue */ - if (!done) - restore_flags (flags); - } while (!done); - process_issue_queue_running = 0; -} - - -int -sim710_queuecommand(Scsi_Cmnd * cmd, void (*done)(Scsi_Cmnd *)) -{ - struct Scsi_Host *host = cmd->host; - struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0]; - Scsi_Cmnd *tmp; - unsigned long flags; - - if (cmd->lun) { - /* Silently ignore luns other than zero! */ - cmd->result = (DID_BAD_TARGET << 16); - done(cmd); - return 0; - } - - DEB(DEB_CMND, printk("scsi%d: id%d queuing ", host->host_no, - cmd->target)); - DEB(DEB_CMND, print_command(cmd->cmnd)); - - cmd->scsi_done = done; - cmd->host_scribble = NULL; - cmd->SCp.ptr = NULL; - cmd->SCp.buffer = NULL; - - save_flags(flags); - cli(); - - if (ignore_ids[hostdata->chip] & (1 << cmd->target)) { - printk("scsi%d: ignoring target %d\n", host->host_no, cmd->target); - cmd->result = (DID_BAD_TARGET << 16); - done(cmd); - restore_flags (flags); - return 0; - } -#ifdef DEBUG_LIMIT_INTS - if (sim710_intrs > DEBUG_LIMIT_INTS) { - cmd->result = (DID_BAD_TARGET << 16); - done(cmd); - restore_flags (flags); return 0; - } -#endif - if (cmd->use_sg > MAX_SG) - panic ("cmd->use_sg = %d\n", cmd->use_sg); - if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { - cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue; - hostdata->issue_queue = cmd; - } else { - for (tmp = hostdata->issue_queue; tmp->SCp.ptr; - tmp = (Scsi_Cmnd *) tmp->SCp.ptr); - tmp->SCp.ptr = (unsigned char *) cmd; - } - restore_flags (flags); - run_process_issue_queue(hostdata); - return 0; + out_unregister: + scsi_unregister(host); + out_release: + release_region(host->base, 64); + out_free: + kfree(hostdata); + out: + return -ENODEV; } +#ifdef CONFIG_MCA +static short sim710_mca_id_table[] = { 0x01bb, 0x01ba, 0x004f, 0}; __init int -sim710_detect(Scsi_Host_Template * tpnt) +sim710_mca_probe(struct device *dev) { - unsigned char scsi_id; - unsigned int base_addr; - struct Scsi_Host * host = NULL; - struct sim710_hostdata *hostdata; - unsigned long timeout; - unsigned long irq_mask; - int requested_irq; - int probed_irq; - u32 dsps; - int chips = 0; - int limit; - int indx; - int revision; - int size; - volatile u8 tmp; - struct Scsi_Host *our_hosts[MAXBOARDS+1]; - -#ifdef MODULE - if (sim710) - param_setup(sim710); -#endif - - if (no_of_boards < 0) { - printk("sim710: NCR53C710 driver disabled\n"); - return 0; - } - -#ifdef CONFIG_MCA - /* If board details have been specified via boot/module parameters, - * then don't bother probing. - */ - if (no_of_boards == 0) { - int slot; + struct mca_device *mca_dev = to_mca_device(dev); + int slot = mca_dev->slot; int pos[3]; - int mca_53c710_ids[] = MCA_53C710_IDS; - int *id_to_check = mca_53c710_ids; + unsigned int base; + int irq_vector; + short id = sim710_mca_id_table[mca_dev->index]; static int io_004f_by_pos[] = MCA_004F_IO_PORTS; static int irq_004f_by_pos[] = MCA_004F_IRQS; static int io_01bb_by_pos[] = MCA_01BB_IO_PORTS; static int irq_01bb_by_pos[] = MCA_01BB_IRQS; + char *name; + int clock; - while ( *id_to_check && no_of_boards < MAXBOARDS) { - if (!MCA_bus) - return 0; - - if ((slot = mca_find_adapter(*id_to_check, 0)) != MCA_NOTFOUND) { - - pos[0] = mca_read_stored_pos(slot, 2); - pos[1] = mca_read_stored_pos(slot, 3); - pos[2] = mca_read_stored_pos(slot, 4); - - /* - * 01BB & 01BA port base by bits 7,6,5,4,3,2 in pos[2] - * - * 000000 001010 0x2800 - * 000001 001011 0x2C00 - * 000010 0x0800 001100 0x3000 - * 000011 0x0C00 001101 0x3400 - * 000100 0x1000 001110 0x3800 - * 000101 0x1400 001111 0x3C00 - * 000110 0x1800 010000 0x4000 - * 000111 0x1C00 010001 0x4400 - * 001000 0x2000 010010 0x4800 - * 001001 0x2400 010011 0x4C00 - * 010100 0x5000 - * - * 00F4 port base by bits 3,2,1 in pos[0] - * - * 000 001 0x200 - * 010 0x300 011 0x400 - * 100 0x500 101 0x600 - * - * 01BB & 01BA IRQ is specified in pos[0] bits 7 and 6: - * - * 00 3 10 11 - * 01 5 11 14 - * - * 00F4 IRQ specified by bits 6,5,4 in pos[0] - * - * 100 5 101 9 - * 110 14 - */ - - if ( *id_to_check == 0x01bb || *id_to_check == 0x01ba ) { - bases[no_of_boards] = io_01bb_by_pos[(pos[2] & 0xFC) >> 2]; - irq_vectors[no_of_boards] = - irq_01bb_by_pos[((pos[0] & 0xC0) >> 6)]; - if (bases[no_of_boards] == 0x0000) - printk("sim710: NCR53C710 Adapter ID 0x01bb is disabled.\n"); - else { - no_of_boards++; - if ( *id_to_check == 0x01bb ) - mca_set_adapter_name( slot, - "NCR 3360/3430 SCSI SubSystem" ); - else - mca_set_adapter_name(slot, - "NCR Dual SIOP SCSI Host Adapter Board"); - } - } - else if ( *id_to_check == 0x004f ) { - bases[no_of_boards] = io_004f_by_pos[((pos[0] & 0x0E) >> 1)]; - irq_vectors[no_of_boards] = - irq_004f_by_pos[((pos[0] & 0x70) >> 4) - 4]; - if (bases[no_of_boards] == 0x0000) - printk("sim710: NCR53C710 Adapter ID 0x004f is disabled.\n"); - else { - no_of_boards++; - mca_set_adapter_name(slot, - "NCR 53c710 SCSI Host Adapter Board"); - } - } - } - id_to_check++; - } - } -#endif + pos[0] = mca_device_read_stored_pos(mca_dev, 2); + pos[1] = mca_device_read_stored_pos(mca_dev, 3); + pos[2] = mca_device_read_stored_pos(mca_dev, 4); + + /* + * 01BB & 01BA port base by bits 7,6,5,4,3,2 in pos[2] + * + * 000000 001010 0x2800 + * 000001 001011 0x2C00 + * 000010 0x0800 001100 0x3000 + * 000011 0x0C00 001101 0x3400 + * 000100 0x1000 001110 0x3800 + * 000101 0x1400 001111 0x3C00 + * 000110 0x1800 010000 0x4000 + * 000111 0x1C00 010001 0x4400 + * 001000 0x2000 010010 0x4800 + * 001001 0x2400 010011 0x4C00 + * 010100 0x5000 + * + * 00F4 port base by bits 3,2,1 in pos[0] + * + * 000 001 0x200 + * 010 0x300 011 0x400 + * 100 0x500 101 0x600 + * + * 01BB & 01BA IRQ is specified in pos[0] bits 7 and 6: + * + * 00 3 10 11 + * 01 5 11 14 + * + * 00F4 IRQ specified by bits 6,5,4 in pos[0] + * + * 100 5 101 9 + * 110 14 + */ + + if (id == 0x01bb || id == 0x01ba) { + base = io_01bb_by_pos[(pos[2] & 0xFC) >> 2]; + irq_vector = + irq_01bb_by_pos[((pos[0] & 0xC0) >> 6)]; + + clock = 50; + if (id == 0x01bb) + name = "NCR 3360/3430 SCSI SubSystem"; + else + name = "NCR Dual SIOP SCSI Host Adapter Board"; + } else if ( id == 0x004f ) { + base = io_004f_by_pos[((pos[0] & 0x0E) >> 1)]; + irq_vector = + irq_004f_by_pos[((pos[0] & 0x70) >> 4) - 4]; + clock = 50; + name = "NCR 53c710 SCSI Host Adapter Board"; + } else { + return -ENODEV; + } + strncpy(dev->name, name, sizeof(dev->name)); + mca_device_set_claim(mca_dev, 1); + base = mca_device_transform_ioport(mca_dev, base); + irq_vector = mca_device_transform_irq(mca_dev, irq_vector); + + return sim710_probe_common(dev, base, irq_vector, clock, + 0, id_array[slot]); +} + +struct mca_driver sim710_mca_driver = { + .id_table = sim710_mca_id_table, + .driver = { + .name = "sim710", + .bus = &mca_bus_type, + .probe = sim710_mca_probe, + }, +}; + +#endif /* CONFIG_MCA */ #ifdef CONFIG_EISA - /* Auto probe, if no boards specified in boot parameters */ - if (no_of_boards == 0) { - int io_addr; - /* reverse probe, so my on-board controller at 0x9000 is always scsi0 */ - for (io_addr = 0x9000; no_of_boards < MAXBOARDS && io_addr >= 0x1000; io_addr -= 0x1000) { - if (request_region(io_addr, 0x40, "sim710") != NULL) { - int id0 = inw(io_addr + 0xc80); - int id1 = inw(io_addr + 0xc82); - /* The on-board controller on my Proliant 2000 is 0x1044, - * my EISA card is 0x1144. - */ - if (id0 == 0x110e && (id1 == 0x1044 || id1 == 0x1144)) { - bases[no_of_boards] = io_addr; +struct eisa_device_id sim710_eisa_ids[] = { + { "CPQ4410" }, + { "CPQ4411" }, + { "HWP0C80" }, + { "" } +}; + +__init int +sim710_eisa_probe(struct device *dev) +{ + struct eisa_device *edev = to_eisa_device(dev); + unsigned long io_addr = edev->base_addr; + char eisa_cpq_irqs[] = { 11, 14, 15, 10, 9, 0 }; + char eisa_hwp_irqs[] = { 3, 4, 5, 7, 12, 10, 11, 0}; + char *eisa_irqs; + unsigned char irq_index; + unsigned char irq, differential = 0, scsi_id = 7; + + if(strcmp(edev->id.sig, "HWP0C80") == 0) { + eisa_irqs = eisa_hwp_irqs; + irq_index = (inb(io_addr + 0xc85) & 0x7) - 1; #if 0 - /* This should detect the IRQ, but I havn't proved it for - * myself. Leave the old probe code active for now, as - * no-one has reported problems with it. - */ - switch (inb(io_addr + 0xc88)) { - case (0x00): - irq_vectors[no_of_boards] = 11; - break; - case (0x01): - irq_vectors[no_of_boards] = 14; - break; - case (0x02): - irq_vectors[no_of_boards] = 15; - break; - case (0x03): - irq_vectors[no_of_boards] = 10; - break; - case (0x04): - irq_vectors[no_of_boards] = 9; - break; - default: - printk("sim710.c: irq nasty\n"); - } -#endif - no_of_boards++; - } - release_region(io_addr, 64); - } - } - } + /* this doesn't seem to work at the moment */ + scsi_id = ffs(inb(io_addr + 0x4)); #endif - - if (!no_of_boards) { - printk("sim710: No NCR53C710 adapter found.\n"); - return 0; - } - - size = sizeof(struct sim710_hostdata); - hostdata_order = 0; - while (size > (PAGE_SIZE << hostdata_order)) - hostdata_order++; - size = PAGE_SIZE << hostdata_order; - - DEB(DEB_ANY, printk("sim710: hostdata %d bytes, size %d, order %d\n", - sizeof(struct sim710_hostdata), size, hostdata_order)); - - tpnt->proc_name = "sim710"; - - memset(our_hosts, 0, sizeof(our_hosts)); - for (indx = 0; indx < no_of_boards; indx++) { - unsigned long page = __get_free_pages(GFP_ATOMIC, hostdata_order); - if(page == 0UL) - { - printk(KERN_WARNING "sim710: out of memory registering board %d.\n", indx); - break; - } - host = scsi_register(tpnt, 4); - if(host == NULL) { - free_pages(host->hostdata[0], hostdata_order); - break; - } - our_hosts[chips] = host; - host->hostdata[0] = page; - hostdata = (struct sim710_hostdata *)host->hostdata[0]; - memset(hostdata, 0, size); - scsi_id = 7; - base_addr = bases[indx]; - requested_irq = irq_vectors[indx]; - printk("scsi%d: Configuring Sim710 (SCSI-ID %d) at %x, IRQ %d\n", - host->host_no, scsi_id, base_addr, requested_irq); - DEB(DEB_ANY, printk("sim710: hostdata = %p (%d bytes), dsa0 = %p\n", - hostdata, sizeof(struct sim710_hostdata), - hostdata->target[0].dsa)); - hostdata->chip = indx; - host->irq = requested_irq; - host->this_id = scsi_id; - host->unique_id = base_addr; - host->base = base_addr; - hostdata->msg_reject = MESSAGE_REJECT; - - if (ncr_halt(host)) { - free_pages(host->hostdata[0], hostdata_order); - scsi_unregister (host); - printk("scsi%d: Failed to initialise 53c710 at address %x\n", - host->host_no, base_addr); - continue; - } - DEB(DEB_ANY,ncr_dump(host)); - revision = (NCR_read8(CTEST8_REG) & 0xF0) >> 4; - printk("scsi%d: Revision 0x%x\n",host->host_no,revision); - sim710_soft_reset(host); - - sim710_driver_init(host); - - request_region((u32)host->base, 64, "sim710"); - /* Now run test1 */ - hostdata->test1_src = 0x53c710aa; - hostdata->test1_dst = 0x76543210; - NCR_write32(DSPS_REG, 0x89abcdef); - irq_mask = probe_irq_on(); - NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_test1/4)); - timeout = 5; - while (hostdata->test1_dst != hostdata->test1_src && timeout--) - mdelay(100); - tmp = NCR_read8(ISTAT_REG); - tmp = NCR_read8(SSTAT0_REG); - udelay(10); - tmp = NCR_read8(DSTAT_REG); - probed_irq = probe_irq_off(irq_mask); - if (requested_irq == 0) { - if (probed_irq > 0) { - printk("scsi%d: Chip is using IRQ %d\n", host->host_no, - probed_irq); - requested_irq = host->irq = probed_irq; - } - else { - printk("scsi%d: Failed to probe for IRQ (returned %d)\n", - host->host_no, probed_irq); - ncr_halt(host); - free_pages(host->hostdata[0], hostdata_order); - scsi_unregister (host); - release_region((u32)host->base, 64); - continue; - } + } else { + eisa_irqs = eisa_cpq_irqs; + irq_index = inb(io_addr + 0xc88); } - else if (probed_irq > 0 && probed_irq != requested_irq) - printk("scsi%d: WARNING requested IRQ %d, but probed as %d\n", - host->host_no, requested_irq, probed_irq); - else if (probed_irq <= 0) - printk("scsi%d: WARNING IRQ probe failed, (returned %d)\n", - host->host_no, probed_irq); - - dsps = NCR_read32(DSPS_REG); - if (hostdata->test1_dst != 0x53c710aa || dsps != A_int_test1) { - if (hostdata->test1_dst != 0x53c710aa) - printk("scsi%d: test 1 FAILED: data: exp 0x53c710aa, got 0x%08x\n", - host->host_no, hostdata->test1_dst); - if (dsps != A_int_test1) - printk("scsi%d: test 1 FAILED: dsps: exp 0x%08x, got 0x%08x\n", - host->host_no, A_int_test1, dsps); - ncr_dump(host); - ncr_halt(host); - free_pages(host->hostdata[0], hostdata_order); - scsi_unregister (host); - release_region((u32)host->base, 64); - continue; - } - printk("scsi%d: test 1 completed ok.\n", host->host_no); - NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_reselect/4)); - hostdata->state = STATE_IDLE; - chips++; - } - /* OK, now run down our_hosts[] calling request_irq(... SA_SHIRQ ...). - * Couldn't call request_irq earlier, as probing would have failed. - */ - for (indx = 0, limit = chips; indx < limit; indx++) { - host = our_hosts[indx]; - if (request_irq(host->irq, do_sim710_intr_handle, - SA_INTERRUPT | SA_SHIRQ, "sim710", host)) - { - printk("scsi%d : IRQ%d not free, detaching\n", - host->host_no, host->irq); - ncr_halt(host); - free_pages(host->hostdata[0], hostdata_order); - scsi_unregister (host); - chips--; + if(irq_index >= strlen(eisa_irqs)) { + printk("sim710.c: irq nasty\n"); + return -ENODEV; } - } - - return chips; -} - -int -sim710_abort(Scsi_Cmnd * cmd) -{ - struct Scsi_Host * host = cmd->host; - printk("scsi%d: Unable to abort command for target %d\n", - host->host_no, cmd->target); - return FAILED; + irq = eisa_irqs[irq_index]; + + return sim710_probe_common(dev, io_addr, irq, 50, + differential, scsi_id); } -/* - * This is a device reset. Need to select and send a Bus Device Reset msg. - */ +struct eisa_driver sim710_eisa_driver = { + .id_table = sim710_eisa_ids, + .driver = { + .name = "sim710", + .probe = sim710_eisa_probe, + .remove = __devexit_p(sim710_device_remove), + }, +}; -int -sim710_dev_reset(Scsi_Cmnd * SCpnt) -{ - struct Scsi_Host * host = SCpnt->host; +#endif /* CONFIG_EISA */ - printk("scsi%d: Unable to send Bus Device Reset for target %d\n", - host->host_no, SCpnt->target); - return FAILED; -} - -/* - * This is bus reset. We need to reset the bus and fail any active commands. - */ int -sim710_bus_reset(Scsi_Cmnd * SCpnt) +sim710_release(struct Scsi_Host *host) { - struct Scsi_Host * host = SCpnt->host; + struct D700_Host_Parameters *hostdata = + (struct D700_Host_Parameters *)host->hostdata[0]; - printk("scsi%d: Unable to do SCSI bus reset\n", host->host_no); - return FAILED; + NCR_700_release(host); + kfree(hostdata); + free_irq(host->irq, host); + /* should do a refcount here and unregister the drivers when + * it reaches zero */ + return 1; } -static int -full_reset(struct Scsi_Host * host) +int __init +sim710_detect(Scsi_Host_Template *tpnt) { - struct sim710_hostdata *hostdata = (struct sim710_hostdata *) - host->hostdata[0]; - int target; - Scsi_Cmnd *cmd; - - u32 istat, dstat = 0, sstat0 = 0, sstat1 = 0, dsp, dsps, scratch; - unsigned long flags; - - save_flags(flags); - cli(); - - istat = NCR_read8(ISTAT_REG); - if (istat & ISTAT_SIP) { - sstat0 = NCR_read8(SSTAT0_REG); - sstat1 = NCR_read8(SSTAT1_REG); - udelay(10); - } - if (istat & ISTAT_DIP) - dstat = NCR_read8(DSTAT_REG); - - if (ncr_halt(host)) { - restore_flags(flags); - return FAILED; - } - restore_flags(flags); - dsp = NCR_read32(DSP_REG); - dsps = NCR_read32(DSPS_REG); - scratch = NCR_read32(SCRATCH_REG); - printk("scsi%d: istat = %02x, sstat0 = %02x, sstat1 = %02x, dstat = %02x\n", - host->host_no, istat, sstat0, sstat1, dstat); - printk("scsi%d: dsp = %08x (script[0x%04x]), dsps = %08x, scratch = %08x\n", - host->host_no, dsp, - ((u32)bus_to_virt(dsp) - (u32)hostdata->script)/4, dsps, scratch); - - for (target = 0; target < 7; target++) { - if ((cmd = hostdata->target[target].cur_cmd)) { - printk("scsi%d: Failing command for ID%d\n", - host->host_no, target); - cmd->result = DID_RESET << 16; - cmd->scsi_done(cmd); - hostdata->target[target].cur_cmd = NULL; - } - } - - sim710_soft_reset(host); - sim710_driver_init(host); - - NCR_write32(DSP_REG, isa_virt_to_bus(hostdata->script+Ent_reselect/4)); - hostdata->state = STATE_IDLE; - - run_process_issue_queue(hostdata); - - return SUCCESS; -} - -/* - * This is host reset. We need to reset the chip and the bus. - */ - -int -sim710_host_reset(Scsi_Cmnd * SCpnt) -{ - struct Scsi_Host * host = SCpnt->host; - - printk("scsi%d: >>>>>>>>>>>> Host reset <<<<<<<<<<<<\n", host->host_no); - - return full_reset(host); -} + sim710_global_info.tpnt = tpnt; + sim710_global_info.found = 0; #ifdef MODULE + if (sim710) + param_setup(sim710); +#endif -int -sim710_release(struct Scsi_Host *host) -{ - ncr_halt(host); - free_pages(host->hostdata[0], hostdata_order); - free_irq(host->irq, host); - release_region((u32)host->base, 64); - return 1; -} +#ifdef CONFIG_MCA + if(MCA_bus) + mca_register_driver(&sim710_mca_driver); +#endif +#ifdef CONFIG_EISA + eisa_driver_register(&sim710_eisa_driver); #endif + return sim710_global_info.found; +} -static Scsi_Host_Template driver_template = SIM710_SCSI; +static Scsi_Host_Template driver_template = { + .name = "LSI (Symbios) 710 MCA/EISA", + .proc_name = "sim710", + .detect = sim710_detect, + .release = sim710_release, + .this_id = 7, +}; #include "scsi_module.c" diff -Nru a/drivers/scsi/sim710.h b/drivers/scsi/sim710.h --- a/drivers/scsi/sim710.h Sun Feb 9 21:13:32 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,851 +0,0 @@ -#ifndef _SIM710_H -#define _SIM710_H - -/* - * sim710.h - Copyright (C) 1999 Richard Hirst - */ - -#include - -int sim710_detect(Scsi_Host_Template *); -int sim710_command(Scsi_Cmnd *); -int sim710_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); -int sim710_abort(Scsi_Cmnd * SCpnt); -int sim710_bus_reset(Scsi_Cmnd * SCpnt); -int sim710_dev_reset(Scsi_Cmnd * SCpnt); -int sim710_host_reset(Scsi_Cmnd * SCpnt); -#ifdef MODULE -int sim710_release(struct Scsi_Host *); -#else -#define sim710_release NULL -#endif - -#include - -#define SIM710_SCSI { .proc_name = "sim710", \ - .name = "53c710", \ - .detect = sim710_detect, \ - .release = sim710_release, \ - .queuecommand = sim710_queuecommand, \ - .eh_abort_handler = sim710_abort, \ - .eh_device_reset_handler = sim710_dev_reset, \ - .eh_bus_reset_handler = sim710_bus_reset, \ - .eh_host_reset_handler = sim710_host_reset, \ - .can_queue = 8, \ - .this_id = 7, \ - .sg_tablesize = 128, \ - .cmd_per_lun = 1, \ - .use_clustering = DISABLE_CLUSTERING } - -#ifndef HOSTS_C - -#ifdef __BIG_ENDIAN -#define bE 3 /* 0 for little endian, 3 for big endian */ -#else -#define bE 0 -#endif - -/* SCSI control 0 rw, default = 0xc0 */ -#define SCNTL0_REG (0x00^bE) -#define SCNTL0_ARB1 0x80 /* 0 0 = simple arbitration */ -#define SCNTL0_ARB2 0x40 /* 1 1 = full arbitration */ -#define SCNTL0_STRT 0x20 /* Start Sequence */ -#define SCNTL0_WATN 0x10 /* Select with ATN */ -#define SCNTL0_EPC 0x08 /* Enable parity checking */ -/* Bit 2 is reserved on 800 series chips */ -#define SCNTL0_EPG_700 0x04 /* Enable parity generation */ -#define SCNTL0_AAP 0x02 /* ATN/ on parity error */ -#define SCNTL0_TRG 0x01 /* Target mode */ - -/* SCSI control 1 rw, default = 0x00 */ - -#define SCNTL1_REG (0x01^bE) -#define SCNTL1_EXC 0x80 /* Extra Clock Cycle of Data setup */ -#define SCNTL1_ADB 0x40 /* contents of SODL on bus */ -#define SCNTL1_ESR_700 0x20 /* Enable SIOP response to selection - and reselection */ -#define SCNTL1_CON 0x10 /* Connected */ -#define SCNTL1_RST 0x08 /* SCSI RST/ */ -#define SCNTL1_AESP 0x04 /* Force bad parity */ -#define SCNTL1_SND_700 0x02 /* Start SCSI send */ -#define SCNTL1_IARB_800 0x02 /* Immediate Arbitration, start - arbitration immediately after - busfree is detected */ -#define SCNTL1_RCV_700 0x01 /* Start SCSI receive */ -#define SCNTL1_SST_800 0x01 /* Start SCSI transfer */ - -/* SCSI control 2 rw, */ - -#define SCNTL2_REG_800 (0x02^bE) -#define SCNTL2_800_SDU 0x80 /* SCSI disconnect unexpected */ - -/* SCSI control 3 rw */ - -#define SCNTL3_REG_800 (0x03^bE) -#define SCNTL3_800_SCF_SHIFT 4 -#define SCNTL3_800_SCF_MASK 0x70 -#define SCNTL3_800_SCF2 0x40 /* Synchronous divisor */ -#define SCNTL3_800_SCF1 0x20 /* 0x00 = SCLK/3 */ -#define SCNTL3_800_SCF0 0x10 /* 0x10 = SCLK/1 */ - /* 0x20 = SCLK/1.5 - 0x30 = SCLK/2 - 0x40 = SCLK/3 */ - -#define SCNTL3_800_CCF_SHIFT 0 -#define SCNTL3_800_CCF_MASK 0x07 -#define SCNTL3_800_CCF2 0x04 /* 0x00 50.01 to 66 */ -#define SCNTL3_800_CCF1 0x02 /* 0x01 16.67 to 25 */ -#define SCNTL3_800_CCF0 0x01 /* 0x02 25.01 - 37.5 - 0x03 37.51 - 50 - 0x04 50.01 - 66 */ - -/* - * SCSI destination ID rw - the appropriate bit is set for the selected - * target ID. This is written by the SCSI SCRIPTS processor. - * default = 0x00 - */ -#define SDID_REG_700 (0x02^bE) -#define SDID_REG_800 (0x06^bE) - -#define GP_REG_800 (0x07^bE) /* General purpose IO */ -#define GP_800_IO1 0x02 -#define GP_800_IO2 0x01 - -/* SCSI interrupt enable rw, default = 0x00 */ -#define SIEN_REG_700 (0x03^bE) -#define SIEN0_REG_800 (0x40^bE) -#define SIEN_MA 0x80 /* Phase mismatch (ini) or ATN (tgt) */ -#define SIEN_FC 0x40 /* Function complete */ -#define SIEN_700_STO 0x20 /* Selection or reselection timeout */ -#define SIEN_800_SEL 0x20 /* Selected */ -#define SIEN_700_SEL 0x10 /* Selected or reselected */ -#define SIEN_800_RESEL 0x10 /* Reselected */ -#define SIEN_SGE 0x08 /* SCSI gross error */ -#define SIEN_UDC 0x04 /* Unexpected disconnect */ -#define SIEN_RST 0x02 /* SCSI RST/ received */ -#define SIEN_PAR 0x01 /* Parity error */ - -/* - * SCSI chip ID rw - * NCR53c700 : - * When arbitrating, the highest bit is used, when reselection or selection - * occurs, the chip responds to all IDs for which a bit is set. - * default = 0x00 - */ -#define SCID_REG (0x04^bE) -/* Bit 7 is reserved on 800 series chips */ -#define SCID_800_RRE 0x40 /* Enable response to reselection */ -#define SCID_800_SRE 0x20 /* Enable response to selection */ -/* Bits four and three are reserved on 800 series chips */ -#define SCID_800_ENC_MASK 0x07 /* Encoded SCSI ID */ - -/* SCSI transfer rw, default = 0x00 */ -#define SXFER_REG (0x05^bE) -#define SXFER_DHP 0x80 /* Disable halt on parity */ - -#define SXFER_TP2 0x40 /* Transfer period msb */ -#define SXFER_TP1 0x20 -#define SXFER_TP0 0x10 /* lsb */ -#define SXFER_TP_MASK 0x70 -/* FIXME : SXFER_TP_SHIFT == 5 is right for '8xx chips */ -#define SXFER_TP_SHIFT 5 -#define SXFER_TP_4 0x00 /* Divisors */ -#define SXFER_TP_5 0x10<<1 -#define SXFER_TP_6 0x20<<1 -#define SXFER_TP_7 0x30<<1 -#define SXFER_TP_8 0x40<<1 -#define SXFER_TP_9 0x50<<1 -#define SXFER_TP_10 0x60<<1 -#define SXFER_TP_11 0x70<<1 - -#define SXFER_MO3 0x08 /* Max offset msb */ -#define SXFER_MO2 0x04 -#define SXFER_MO1 0x02 -#define SXFER_MO0 0x01 /* lsb */ -#define SXFER_MO_MASK 0x0f -#define SXFER_MO_SHIFT 0 - -/* - * SCSI output data latch rw - * The contents of this register are driven onto the SCSI bus when - * the Assert Data Bus bit of the SCNTL1 register is set and - * the CD, IO, and MSG bits of the SOCL register match the SCSI phase - */ -#define SODL_REG_700 (0x06^bE) -#define SODL_REG_800 (0x54^bE) - - -/* - * SCSI output control latch rw, default = 0 - * Note that when the chip is being manually programmed as an initiator, - * the MSG, CD, and IO bits must be set correctly for the phase the target - * is driving the bus in. Otherwise no data transfer will occur due to - * phase mismatch. - */ - -#define SOCL_REG (0x07^bE) -#define SOCL_REQ 0x80 /* REQ */ -#define SOCL_ACK 0x40 /* ACK */ -#define SOCL_BSY 0x20 /* BSY */ -#define SOCL_SEL 0x10 /* SEL */ -#define SOCL_ATN 0x08 /* ATN */ -#define SOCL_MSG 0x04 /* MSG */ -#define SOCL_CD 0x02 /* C/D */ -#define SOCL_IO 0x01 /* I/O */ - -/* - * SCSI first byte received latch ro - * This register contains the first byte received during a block MOVE - * SCSI SCRIPTS instruction, including - * - * Initiator mode Target mode - * Message in Command - * Status Message out - * Data in Data out - * - * It also contains the selecting or reselecting device's ID and our - * ID. - * - * Note that this is the register the various IF conditionals can - * operate on. - */ -#define SFBR_REG (0x08^bE) - -/* - * SCSI input data latch ro - * In initiator mode, data is latched into this register on the rising - * edge of REQ/. In target mode, data is latched on the rising edge of - * ACK/ - */ -#define SIDL_REG_700 (0x09^bE) -#define SIDL_REG_800 (0x50^bE) - -/* - * SCSI bus data lines ro - * This register reflects the instantaneous status of the SCSI data - * lines. Note that SCNTL0 must be set to disable parity checking, - * otherwise reading this register will latch new parity. - */ -#define SBDL_REG_700 (0x0a^bE) -#define SBDL_REG_800 (0x58^bE) - -#define SSID_REG_800 (0x0a^bE) -#define SSID_800_VAL 0x80 /* Exactly two bits asserted at sel */ -#define SSID_800_ENCID_MASK 0x07 /* Device which performed operation */ - - - -/* - * SCSI bus control lines rw, - * instantaneous readout of control lines - */ -#define SBCL_REG (0x0b^bE) -#define SBCL_REQ 0x80 /* REQ ro */ -#define SBCL_ACK 0x40 /* ACK ro */ -#define SBCL_BSY 0x20 /* BSY ro */ -#define SBCL_SEL 0x10 /* SEL ro */ -#define SBCL_ATN 0x08 /* ATN ro */ -#define SBCL_MSG 0x04 /* MSG ro */ -#define SBCL_CD 0x02 /* C/D ro */ -#define SBCL_IO 0x01 /* I/O ro */ -#define SBCL_PHASE_CMDOUT SBCL_CD -#define SBCL_PHASE_DATAIN SBCL_IO -#define SBCL_PHASE_DATAOUT 0 -#define SBCL_PHASE_MSGIN (SBCL_CD|SBCL_IO|SBCL_MSG) -#define SBCL_PHASE_MSGOUT (SBCL_CD|SBCL_MSG) -#define SBCL_PHASE_STATIN (SBCL_CD|SBCL_IO) -#define SBCL_PHASE_MASK (SBCL_CD|SBCL_IO|SBCL_MSG) -/* - * Synchronous SCSI Clock Control bits - * 0 - set by DCNTL - * 1 - SCLK / 1.0 - * 2 - SCLK / 1.5 - * 3 - SCLK / 2.0 - */ -#define SBCL_SSCF1 0x02 /* wo, -66 only */ -#define SBCL_SSCF0 0x01 /* wo, -66 only */ -#define SBCL_SSCF_MASK 0x03 - -/* - * XXX note : when reading the DSTAT and STAT registers to clear interrupts, - * insure that 10 clocks elapse between the two - */ -/* DMA status ro */ -#define DSTAT_REG (0x0c^bE) -#define DSTAT_DFE 0x80 /* DMA FIFO empty */ -#define DSTAT_800_MDPE 0x40 /* Master Data Parity Error */ -#define DSTAT_BF 0x20 /* Bus Fault */ -#define DSTAT_ABRT 0x10 /* Aborted - set on error */ -#define DSTAT_SSI 0x08 /* SCRIPTS single step interrupt */ -#define DSTAT_SIR 0x04 /* SCRIPTS interrupt received - - set when INT instruction is - executed */ -#define DSTAT_WTD 0x02 /* Watchdog timeout detected */ -#define DSTAT_OPC 0x01 /* Illegal instruction */ -#define DSTAT_IID 0x01 /* Same thing, different name */ - - -#define SSTAT0_REG (0x0d^bE) /* SCSI status 0 ro */ -#define SIST0_REG_800 (0x42^bE) /* SCSI status 0 ro */ -#define SSTAT0_MA 0x80 /* ini : phase mismatch, - * tgt : ATN/ asserted - */ -#define SSTAT0_CMP 0x40 /* function complete */ -#define SSTAT0_700_STO 0x20 /* Selection or reselection timeout */ -#define SSTAT0_800_SEL 0x20 /* Selected */ -#define SSTAT0_700_SEL 0x10 /* Selected or reselected */ -#define SIST0_800_RSL 0x10 /* Reselected */ -#define SSTAT0_SGE 0x08 /* SCSI gross error */ -#define SSTAT0_UDC 0x04 /* Unexpected disconnect */ -#define SSTAT0_RST 0x02 /* SCSI RST/ received */ -#define SSTAT0_PAR 0x01 /* Parity error */ - -#define SSTAT1_REG (0x0e^bE) /* SCSI status 1 ro */ -#define SSTAT1_ILF 0x80 /* SIDL full */ -#define SSTAT1_ORF 0x40 /* SODR full */ -#define SSTAT1_OLF 0x20 /* SODL full */ -#define SSTAT1_AIP 0x10 /* Arbitration in progress */ -#define SSTAT1_LOA 0x08 /* Lost arbitration */ -#define SSTAT1_WOA 0x04 /* Won arbitration */ -#define SSTAT1_RST 0x02 /* Instant readout of RST/ */ -#define SSTAT1_SDP 0x01 /* Instant readout of SDP/ */ - -#define SSTAT2_REG (0x0f^bE) /* SCSI status 2 ro */ -#define SSTAT2_FF3 0x80 /* number of bytes in synchronous */ -#define SSTAT2_FF2 0x40 /* data FIFO */ -#define SSTAT2_FF1 0x20 -#define SSTAT2_FF0 0x10 -#define SSTAT2_FF_MASK 0xf0 -#define SSTAT2_FF_SHIFT 4 - -/* - * Latched signals, latched on the leading edge of REQ/ for initiators, - * ACK/ for targets. - */ -#define SSTAT2_SDP 0x08 /* SDP */ -#define SSTAT2_MSG 0x04 /* MSG */ -#define SSTAT2_CD 0x02 /* C/D */ -#define SSTAT2_IO 0x01 /* I/O */ -#define SSTAT2_PHASE_CMDOUT SSTAT2_CD -#define SSTAT2_PHASE_DATAIN SSTAT2_IO -#define SSTAT2_PHASE_DATAOUT 0 -#define SSTAT2_PHASE_MSGIN (SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG) -#define SSTAT2_PHASE_MSGOUT (SSTAT2_CD|SSTAT2_MSG) -#define SSTAT2_PHASE_STATIN (SSTAT2_CD|SSTAT2_IO) -#define SSTAT2_PHASE_MASK (SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG) - - -#define DSA_REG 0x10 /* DATA structure address */ - -#define CTEST0_REG_700 (0x14^bE) /* Chip test 0 ro */ -#define CTEST0_REG_800 (0x18^bE) /* Chip test 0 ro */ -/* 0x80 - 0x04 are reserved */ -#define CTEST0_700_RTRG 0x02 /* Real target mode */ -#define CTEST0_700_DDIR 0x01 /* Data direction, 1 = - * SCSI bus to host, 0 = - * host to SCSI. - */ - -#define CTEST1_REG_700 (0x15^bE) /* Chip test 1 ro */ -#define CTEST1_REG_800 (0x19^bE) /* Chip test 1 ro */ -#define CTEST1_FMT3 0x80 /* Identify which byte lanes are empty */ -#define CTEST1_FMT2 0x40 /* in the DMA FIFO */ -#define CTEST1_FMT1 0x20 -#define CTEST1_FMT0 0x10 - -#define CTEST1_FFL3 0x08 /* Identify which bytes lanes are full */ -#define CTEST1_FFL2 0x04 /* in the DMA FIFO */ -#define CTEST1_FFL1 0x02 -#define CTEST1_FFL0 0x01 - -#define CTEST2_REG_700 (0x16^bE) /* Chip test 2 ro */ -#define CTEST2_REG_800 (0x1a^bE) /* Chip test 2 ro */ - -#define CTEST2_800_DDIR 0x80 /* 1 = SCSI->host */ -#define CTEST2_800_SIGP 0x40 /* A copy of SIGP in ISTAT. - Reading this register clears */ -#define CTEST2_800_CIO 0x20 /* Configured as IO */. -#define CTEST2_800_CM 0x10 /* Configured as memory */ - -/* 0x80 - 0x40 are reserved on 700 series chips */ -#define CTEST2_700_SOFF 0x20 /* SCSI Offset Compare, - * As an initiator, this bit is - * one when the synchronous offset - * is zero, as a target this bit - * is one when the synchronous - * offset is at the maximum - * defined in SXFER - */ -#define CTEST2_700_SFP 0x10 /* SCSI FIFO parity bit, - * reading CTEST3 unloads a byte - * from the FIFO and sets this - */ -#define CTEST2_700_DFP 0x08 /* DMA FIFO parity bit, - * reading CTEST6 unloads a byte - * from the FIFO and sets this - */ -#define CTEST2_TEOP 0x04 /* SCSI true end of process, - * indicates a totally finished - * transfer - */ -#define CTEST2_DREQ 0x02 /* Data request signal */ -/* 0x01 is reserved on 700 series chips */ -#define CTEST2_800_DACK 0x01 - -/* - * Chip test 3 ro - * Unloads the bottom byte of the eight deep SCSI synchronous FIFO, - * check SSTAT2 FIFO full bits to determine size. Note that a GROSS - * error results if a read is attempted on this register. Also note - * that 16 and 32 bit reads of this register will cause corruption. - */ -#define CTEST3_REG_700 (0x17^bE) -/* Chip test 3 rw */ -#define CTEST3_REG_800 (0x1b^bE) -#define CTEST3_800_V3 0x80 /* Chip revision */ -#define CTEST3_800_V2 0x40 -#define CTEST3_800_V1 0x20 -#define CTEST3_800_V0 0x10 -#define CTEST3_800_FLF 0x08 /* Flush DMA FIFO */ -#define CTEST3_800_CLF 0x04 /* Clear DMA FIFO */ -#define CTEST3_800_FM 0x02 /* Fetch mode pin */ -/* bit 0 is reserved on 800 series chips */ - -#define CTEST4_REG_700 (0x18^bE) /* Chip test 4 rw */ -#define CTEST4_REG_800 (0x21^bE) /* Chip test 4 rw */ -/* 0x80 is reserved on 700 series chips */ -#define CTEST4_800_BDIS 0x80 /* Burst mode disable */ -#define CTEST4_ZMOD 0x40 /* High impedance mode */ -#define CTEST4_SZM 0x20 /* SCSI bus high impedance */ -#define CTEST4_700_SLBE 0x10 /* SCSI loopback enabled */ -#define CTEST4_800_SRTM 0x10 /* Shadow Register Test Mode */ -#define CTEST4_700_SFWR 0x08 /* SCSI FIFO write enable, - * redirects writes from SODL - * to the SCSI FIFO. - */ -#define CTEST4_800_MPEE 0x08 /* Enable parity checking - during master cycles on PCI - bus */ - -/* - * These bits send the contents of the CTEST6 register to the appropriate - * byte lane of the 32 bit DMA FIFO. Normal operation is zero, otherwise - * the high bit means the low two bits select the byte lane. - */ -#define CTEST4_FBL2 0x04 -#define CTEST4_FBL1 0x02 -#define CTEST4_FBL0 0x01 -#define CTEST4_FBL_MASK 0x07 -#define CTEST4_FBL_0 0x04 /* Select DMA FIFO byte lane 0 */ -#define CTEST4_FBL_1 0x05 /* Select DMA FIFO byte lane 1 */ -#define CTEST4_FBL_2 0x06 /* Select DMA FIFO byte lane 2 */ -#define CTEST4_FBL_3 0x07 /* Select DMA FIFO byte lane 3 */ -#define CTEST4_800_SAVE (CTEST4_800_BDIS) - - -#define CTEST5_REG_700 (0x19^bE) /* Chip test 5 rw */ -#define CTEST5_REG_800 (0x22^bE) /* Chip test 5 rw */ -/* - * Clock Address Incrementor. When set, it increments the - * DNAD register to the next bus size boundary. It automatically - * resets itself when the operation is complete. - */ -#define CTEST5_ADCK 0x80 -/* - * Clock Byte Counter. When set, it decrements the DBC register to - * the next bus size boundary. - */ -#define CTEST5_BBCK 0x40 -/* - * Reset SCSI Offset. Setting this bit to 1 clears the current offset - * pointer in the SCSI synchronous offset counter (SSTAT). This bit - * is set to 1 if a SCSI Gross Error Condition occurs. The offset should - * be cleared when a synchronous transfer fails. When written, it is - * automatically cleared after the SCSI synchronous offset counter is - * reset. - */ -/* Bit 5 is reserved on 800 series chips */ -#define CTEST5_700_ROFF 0x20 -/* - * Master Control for Set or Reset pulses. When 1, causes the low - * four bits of register to set when set, 0 causes the low bits to - * clear when set. - */ -#define CTEST5_MASR 0x10 -#define CTEST5_DDIR 0x08 /* DMA direction */ -/* - * Bits 2-0 are reserved on 800 series chips - */ -#define CTEST5_700_EOP 0x04 /* End of process */ -#define CTEST5_700_DREQ 0x02 /* Data request */ -#define CTEST5_700_DACK 0x01 /* Data acknowledge */ - -/* - * Chip test 6 rw - writing to this register writes to the byte - * lane in the DMA FIFO as determined by the FBL bits in the CTEST4 - * register. - */ -#define CTEST6_REG_700 (0x1a^bE) -#define CTEST6_REG_800 (0x23^bE) - -#define CTEST7_REG (0x1b^bE) /* Chip test 7 rw */ -#define CTEST7_10_CDIS 0x80 /* Cache burst disable */ -#define CTEST7_10_SC1 0x40 /* Snoop control bits */ -#define CTEST7_10_SC0 0x20 -#define CTEST7_10_SC_MASK 0x60 -#define CTEST7_STD 0x10 /* Selection timeout disable */ -#define CTEST7_DFP 0x08 /* DMA FIFO parity bit for CTEST6 */ -#define CTEST7_EVP 0x04 /* 1 = host bus even parity, 0 = odd */ -#define CTEST7_10_TT1 0x02 /* Transfer type */ -#define CTEST7_DIFF 0x01 /* Differential mode */ - -#define CTEST7_SAVE ( CTEST7_EVP | CTEST7_DIFF ) - - -#define TEMP_REG 0x1c /* through 0x1f Temporary stack rw */ - -#define DFIFO_REG (0x20^bE) /* DMA FIFO rw */ -/* - * 0x80 is reserved on the NCR53c710, the CLF and FLF bits have been - * moved into the CTEST8 register. - */ -#define DFIFO_BO6 0x40 -#define DFIFO_BO5 0x20 -#define DFIFO_BO4 0x10 -#define DFIFO_BO3 0x08 -#define DFIFO_BO2 0x04 -#define DFIFO_BO1 0x02 -#define DFIFO_BO0 0x01 -#define DFIFO_10_BO_MASK 0x7f /* 7 bit counter */ - -/* - * Interrupt status rw - * Note that this is the only register which can be read while SCSI - * SCRIPTS are being executed. - */ -#define ISTAT_REG_700 (0x21^bE) -#define ISTAT_REG_800 (0x14^bE) -#define ISTAT_ABRT 0x80 /* Software abort, write - *1 to abort, wait for interrupt. */ -#define ISTAT_10_SRST 0x40 /* software reset */ -#define ISTAT_10_SIGP 0x20 /* signal script */ -#define ISTAT_CON 0x08 /* 1 when connected */ -#define ISTAT_800_INTF 0x04 /* Interrupt on the fly */ -#define ISTAT_700_PRE 0x04 /* Pointer register empty. - * Set to 1 when DSPS and DSP - * registers are empty in pipeline - * mode, always set otherwise. - */ -#define ISTAT_SIP 0x02 /* SCSI interrupt pending from - * SCSI portion of SIOP see - * SSTAT0 - */ -#define ISTAT_DIP 0x01 /* DMA interrupt pending - * see DSTAT - */ - -#define CTEST8_REG (0x22^bE) /* Chip test 8 rw */ -#define CTEST8_10_V3 0x80 /* Chip revision */ -#define CTEST8_10_V2 0x40 -#define CTEST8_10_V1 0x20 -#define CTEST8_10_V0 0x10 -#define CTEST8_10_V_MASK 0xf0 -#define CTEST8_10_FLF 0x08 /* Flush FIFOs */ -#define CTEST8_10_CLF 0x04 /* Clear FIFOs */ -#define CTEST8_10_FM 0x02 /* Fetch pin mode */ -#define CTEST8_10_SM 0x01 /* Snoop pin mode */ - - -#define LCRC_REG_10 (0x23^bE) - -/* - * 0x24 through 0x27 are the DMA byte counter register. Instructions - * write their high 8 bits into the DCMD register, the low 24 bits into - * the DBC register. - * - * Function is dependent on the command type being executed. - */ - - -#define DBC_REG 0x24 -/* - * For Block Move Instructions, DBC is a 24 bit quantity representing - * the number of bytes to transfer. - * For Transfer Control Instructions, DBC is bit fielded as follows : - */ -/* Bits 20 - 23 should be clear */ -#define DBC_TCI_TRUE (1 << 19) /* Jump when true */ -#define DBC_TCI_COMPARE_DATA (1 << 18) /* Compare data */ -#define DBC_TCI_COMPARE_PHASE (1 << 17) /* Compare phase with DCMD field */ -#define DBC_TCI_WAIT_FOR_VALID (1 << 16) /* Wait for REQ */ -/* Bits 8 - 15 are reserved on some implementations ? */ -#define DBC_TCI_MASK_MASK 0xff00 /* Mask for data compare */ -#define DBC_TCI_MASK_SHIFT 8 -#define DBC_TCI_DATA_MASK 0xff /* Data to be compared */ -#define DBC_TCI_DATA_SHIFT 0 - -#define DBC_RWRI_IMMEDIATE_MASK 0xff00 /* Immediate data */ -#define DBC_RWRI_IMMEDIATE_SHIFT 8 /* Amount to shift */ -#define DBC_RWRI_ADDRESS_MASK 0x3f0000 /* Register address */ -#define DBC_RWRI_ADDRESS_SHIFT 16 - - -/* - * DMA command r/w - */ -#define DCMD_REG (0x27^bE) -#define DCMD_TYPE_MASK 0xc0 /* Masks off type */ -#define DCMD_TYPE_BMI 0x00 /* Indicates a Block Move instruction */ -#define DCMD_BMI_IO 0x01 /* I/O, CD, and MSG bits selecting */ -#define DCMD_BMI_CD 0x02 /* the phase for the block MOVE */ -#define DCMD_BMI_MSG 0x04 /* instruction */ - -#define DCMD_BMI_OP_MASK 0x18 /* mask for opcode */ -#define DCMD_BMI_OP_MOVE_T 0x00 /* MOVE */ -#define DCMD_BMI_OP_MOVE_I 0x08 /* MOVE Initiator */ - -#define DCMD_BMI_INDIRECT 0x20 /* Indirect addressing */ - -#define DCMD_TYPE_TCI 0x80 /* Indicates a Transfer Control - instruction */ -#define DCMD_TCI_IO 0x01 /* I/O, CD, and MSG bits selecting */ -#define DCMD_TCI_CD 0x02 /* the phase for the block MOVE */ -#define DCMD_TCI_MSG 0x04 /* instruction */ -#define DCMD_TCI_OP_MASK 0x38 /* mask for opcode */ -#define DCMD_TCI_OP_JUMP 0x00 /* JUMP */ -#define DCMD_TCI_OP_CALL 0x08 /* CALL */ -#define DCMD_TCI_OP_RETURN 0x10 /* RETURN */ -#define DCMD_TCI_OP_INT 0x18 /* INT */ - -#define DCMD_TYPE_RWRI 0x40 /* Indicates I/O or register Read/Write - instruction */ -#define DCMD_RWRI_OPC_MASK 0x38 /* Opcode mask */ -#define DCMD_RWRI_OPC_WRITE 0x28 /* Write SFBR to register */ -#define DCMD_RWRI_OPC_READ 0x30 /* Read register to SFBR */ -#define DCMD_RWRI_OPC_MODIFY 0x38 /* Modify in place */ - -#define DCMD_RWRI_OP_MASK 0x07 -#define DCMD_RWRI_OP_MOVE 0x00 -#define DCMD_RWRI_OP_SHL 0x01 -#define DCMD_RWRI_OP_OR 0x02 -#define DCMD_RWRI_OP_XOR 0x03 -#define DCMD_RWRI_OP_AND 0x04 -#define DCMD_RWRI_OP_SHR 0x05 -#define DCMD_RWRI_OP_ADD 0x06 -#define DCMD_RWRI_OP_ADDC 0x07 - -#define DCMD_TYPE_MMI 0xc0 /* Indicates a Memory Move instruction - (three words) */ - - -#define DNAD_REG 0x28 /* through 0x2b DMA next address for - data */ -#define DSP_REG 0x2c /* through 0x2f DMA SCRIPTS pointer rw */ -#define DSPS_REG 0x30 /* through 0x33 DMA SCRIPTS pointer - save rw */ -#define DMODE_BL1 0x80 /* Burst length bits */ -#define DMODE_BL0 0x40 -#define DMODE_BL_MASK 0xc0 -/* Burst lengths (800) */ -#define DMODE_BL_2 0x00 /* 2 transfer */ -#define DMODE_BL_4 0x40 /* 4 transfers */ -#define DMODE_BL_8 0x80 /* 8 transfers */ -#define DMODE_BL_16 0xc0 /* 16 transfers */ - -#define DMODE_10_BL_1 0x00 /* 1 transfer */ -#define DMODE_10_BL_2 0x40 /* 2 transfers */ -#define DMODE_10_BL_4 0x80 /* 4 transfers */ -#define DMODE_10_BL_8 0xc0 /* 8 transfers */ -#define DMODE_10_FC2 0x20 /* Driven to FC2 pin */ -#define DMODE_10_FC1 0x10 /* Driven to FC1 pin */ -#define DMODE_710_PD 0x08 /* Program/data on FC0 pin */ -#define DMODE_710_UO 0x02 /* User prog. output */ - -#define DMODE_MAN 0x01 /* Manual start mode, - * requires a 1 to be written - * to the start DMA bit in the DCNTL - * register to run scripts - */ - -/* NCR53c800 series only */ -#define SCRATCHA_REG_800 0x34 /* through 0x37 Scratch A rw */ -/* NCR53c710 only */ -#define SCRATCHB_REG_10 0x34 /* through 0x37 scratch rw */ - -#define DMODE_REG (0x38^bE) /* DMA mode rw, NCR53c710 and newer */ -#define DMODE_800_SIOM 0x20 /* Source IO = 1 */ -#define DMODE_800_DIOM 0x10 /* Destination IO = 1 */ -#define DMODE_800_ERL 0x08 /* Enable Read Line */ - -#define DIEN_REG (0x39^bE) /* DMA interrupt enable rw */ -/* 0x80, 0x40, and 0x20 are reserved on 700-series chips */ -#define DIEN_800_MDPE 0x40 /* Master data parity error */ -#define DIEN_800_BF 0x20 /* BUS fault */ -#define DIEN_700_BF 0x20 /* BUS fault */ -#define DIEN_ABRT 0x10 /* Enable aborted interrupt */ -#define DIEN_SSI 0x08 /* Enable single step interrupt */ -#define DIEN_SIR 0x04 /* Enable SCRIPTS INT command - * interrupt - */ -#define DIEN_700_WTD 0x02 /* Enable watchdog timeout interrupt */ -#define DIEN_700_OPC 0x01 /* Enable illegal instruction - * interrupt - */ -#define DIEN_800_IID 0x01 /* Same meaning, different name */ - -/* - * DMA watchdog timer rw - * set in 16 CLK input periods. - */ -#define DWT_REG (0x3a^bE) - -/* DMA control rw */ -#define DCNTL_REG (0x3b^bE) -#define DCNTL_700_CF1 0x80 /* Clock divisor bits */ -#define DCNTL_700_CF0 0x40 -#define DCNTL_700_CF_MASK 0xc0 -/* Clock divisors Divisor SCLK range (MHZ) */ -#define DCNTL_700_CF_2 0x00 /* 2.0 37.51-50.00 */ -#define DCNTL_700_CF_1_5 0x40 /* 1.5 25.01-37.50 */ -#define DCNTL_700_CF_1 0x80 /* 1.0 16.67-25.00 */ -#define DCNTL_700_CF_3 0xc0 /* 3.0 50.01-66.67 (53c700-66) */ - -#define DCNTL_700_S16 0x20 /* Load scripts 16 bits at a time */ -#define DCNTL_SSM 0x10 /* Single step mode */ -#define DCNTL_700_LLM 0x08 /* Low level mode, can only be set - * after selection */ -#define DCNTL_800_IRQM 0x08 /* Totem pole IRQ pin */ -#define DCNTL_STD 0x04 /* Start DMA / SCRIPTS */ -/* 0x02 is reserved */ -#define DCNTL_10_COM 0x01 /* 700 software compatibility mode */ -#define DCNTL_10_EA 0x20 /* Enable Ack - needed for MVME16x */ - -#define SCRATCHB_REG_800 0x5c /* through 0x5f scratch b rw */ -/* NCR53c710 only */ -#define ADDER_REG_10 0x3c /* Adder, NCR53c710 only */ - -#define SIEN1_REG_800 (0x41^bE) -#define SIEN1_800_STO 0x04 /* selection/reselection timeout */ -#define SIEN1_800_GEN 0x02 /* general purpose timer */ -#define SIEN1_800_HTH 0x01 /* handshake to handshake */ - -#define SIST1_REG_800 (0x43^bE) -#define SIST1_800_STO 0x04 /* selection/reselection timeout */ -#define SIST1_800_GEN 0x02 /* general purpose timer */ -#define SIST1_800_HTH 0x01 /* handshake to handshake */ - -#define SLPAR_REG_800 (0x44^bE) /* Parity */ - -#define MACNTL_REG_800 (0x46^bE) /* Memory access control */ -#define MACNTL_800_TYP3 0x80 -#define MACNTL_800_TYP2 0x40 -#define MACNTL_800_TYP1 0x20 -#define MACNTL_800_TYP0 0x10 -#define MACNTL_800_DWR 0x08 -#define MACNTL_800_DRD 0x04 -#define MACNTL_800_PSCPT 0x02 -#define MACNTL_800_SCPTS 0x01 - -#define GPCNTL_REG_800 (0x47^bE) /* General Purpose Pin Control */ - -/* Timeouts are expressed such that 0=off, 1=100us, doubling after that */ -#define STIME0_REG_800 (0x48^bE) /* SCSI Timer Register 0 */ -#define STIME0_800_HTH_MASK 0xf0 /* Handshake to Handshake timeout */ -#define STIME0_800_HTH_SHIFT 4 -#define STIME0_800_SEL_MASK 0x0f /* Selection timeout */ -#define STIME0_800_SEL_SHIFT 0 - -#define STIME1_REG_800 (0x49^bE) -#define STIME1_800_GEN_MASK 0x0f /* General purpose timer */ - -#define RESPID_REG_800 (0x4a^bE) /* Response ID, bit fielded. 8 - bits on narrow chips, 16 on WIDE */ - -#define STEST0_REG_800 (0x4c^bE) -#define STEST0_800_SLT 0x08 /* Selection response logic test */ -#define STEST0_800_ART 0x04 /* Arbitration priority encoder test */ -#define STEST0_800_SOZ 0x02 /* Synchronous offset zero */ -#define STEST0_800_SOM 0x01 /* Synchronous offset maximum */ - -#define STEST1_REG_800 (0x4d^bE) -#define STEST1_800_SCLK 0x80 /* Disable SCSI clock */ - -#define STEST2_REG_800 (0x4e^bE) -#define STEST2_800_SCE 0x80 /* Enable SOCL/SODL */ -#define STEST2_800_ROF 0x40 /* Reset SCSI sync offset */ -#define STEST2_800_SLB 0x10 /* Enable SCSI loopback mode */ -#define STEST2_800_SZM 0x08 /* SCSI high impedance mode */ -#define STEST2_800_EXT 0x02 /* Extend REQ/ACK filter 30 to 60ns */ -#define STEST2_800_LOW 0x01 /* SCSI low level mode */ - -#define STEST3_REG_800 (0x4f^bE) -#define STEST3_800_TE 0x80 /* Enable active negation */ -#define STEST3_800_STR 0x40 /* SCSI FIFO test read */ -#define STEST3_800_HSC 0x20 /* Halt SCSI clock */ -#define STEST3_800_DSI 0x10 /* Disable single initiator response */ -#define STEST3_800_TTM 0x04 /* Time test mode */ -#define STEST3_800_CSF 0x02 /* Clear SCSI FIFO */ -#define STEST3_800_STW 0x01 /* SCSI FIFO test write */ - -#define ISTAT_REG ISTAT_REG_700 -#define SCRATCH_REG SCRATCHB_REG_10 -#define ADDER_REG ADDER_REG_10 -#define SIEN_REG SIEN_REG_700 -#define SDID_REG SDID_REG_700 -#define CTEST0_REG CTEST0_REG_700 -#define CTEST1_REG CTEST1_REG_700 -#define CTEST2_REG CTEST2_REG_700 -#define CTEST3_REG CTEST3_REG_700 -#define CTEST4_REG CTEST4_REG_700 -#define CTEST5_REG CTEST5_REG_700 -#define CTEST6_REG CTEST6_REG_700 -#define SODL_REG SODL_REG_700 -#define SBDL_REG SBDL_REG_700 -#define SIDL_REG SIDL_REG_700 -#define LCRC_REG LCRC_REG_10 - -#ifdef MEM_MAPPED -#define NCR_read8(address) \ - (unsigned int)readb((u32)(host->base) + ((u32)(address))) - -#define NCR_read32(address) \ - (unsigned int) readl((u32)(host->base) + (u32)(address)) - -#define NCR_write8(address,value) \ - { DEB(DEB_REGS, printk("NCR: %02x => %08x\n", (u32)(value), ((u32)(host->base) + (u32)(address)))); \ - *(volatile unsigned char *) \ - ((u32)(host->base) + (u32)(address)) = (value); } - -#define NCR_write32(address,value) \ - { DEB(DEB_REGS, printk("NCR: %08x => %08x\n", (u32)(value), ((u32)(host->base) + (u32)(address)))); \ - *(volatile unsigned long *) \ - ((u32)(host->base) + (u32)(address)) = (value); } -#else -#define NCR_read8(address) \ - inb((u32)(host->base) + (address)) - -#define NCR_read32(address) \ - inl((u32)(host->base) + (address)) - -#define NCR_write8(address,value) \ - { DEB(DEB_REGS, printk("NCR: %02x => %08x\n", (u32)(value), ((u32)(host->base) + (u32)(address)))); \ - outb((value), (u32)(host->base) + (u32)(address)); } - -#define NCR_write32(address,value) \ - { DEB(DEB_REGS, printk("NCR: %08x => %08x\n", (u32)(value), ((u32)(host->base) + (u32)(address)))); \ - outl((value), (u32)(host->base) + (u32)(address)); } -#endif - -/* Patch arbitrary 32 bit words in the script */ -#define patch_abs_32(script, offset, symbol, value) \ - for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof \ - (u32)); ++i) { \ - (script)[A_##symbol##_used[i] - (offset)] += (value); \ - DEB(DEB_FIXUP, printk("scsi%d: %s reference %d at 0x%x in %s is now 0x%x\n",\ - host->host_no, #symbol, i, A_##symbol##_used[i] - \ - (int)(offset), #script, (script)[A_##symbol##_used[i] - \ - (offset)])); \ - } - -#endif -#endif diff -Nru a/drivers/scsi/sim710.scr b/drivers/scsi/sim710.scr --- a/drivers/scsi/sim710.scr Sun Feb 9 21:13:28 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,576 +0,0 @@ -/* - * sim710.scr - Copyright (C) 1999 Richard Hirst - */ - -/* Offsets from DSA, allow 128 elements of scatter/gather */ - -ABSOLUTE dsa_select = 0 -ABSOLUTE dsa_msgout = 8 -ABSOLUTE dsa_cmnd = 16 -ABSOLUTE dsa_status = 24 -ABSOLUTE dsa_msgin = 32 -ABSOLUTE dsa_datain = 40 /* 8 * 128 = 1024 bytes */ -ABSOLUTE dsa_dataout = 1064 /* 8 * 128 = 1024 bytes */ -ABSOLUTE dsa_size = 2088 - -ABSOLUTE reselected_identify = 0 -ABSOLUTE msgin_buf = 0 -ABSOLUTE msg_reject = 0 -ABSOLUTE test1_src = 0 -ABSOLUTE test1_dst = 0 - -/* Interrupt values passed back to driver */ - -ABSOLUTE int_bad_msg1 = 0xab930006 -ABSOLUTE int_bad_msg2 = 0xab930007 -ABSOLUTE int_bad_msg3 = 0xab930008 -ABSOLUTE int_cmd_bad_phase = 0xab930009 -ABSOLUTE int_cmd_complete = 0xab93000a -ABSOLUTE int_data_bad_phase = 0xab93000b -ABSOLUTE int_msg_sdtr1 = 0xab93000c -ABSOLUTE int_msg_sdtr2 = 0xab93000d -ABSOLUTE int_msg_sdtr3 = 0xab93000e -ABSOLUTE int_no_msgout1 = 0xab93000f -ABSOLUTE int_no_msgout2 = 0xab930010 -ABSOLUTE int_no_msgout3 = 0xab930011 -ABSOLUTE int_not_cmd_complete = 0xab930012 -ABSOLUTE int_sel_no_ident = 0xab930013 -ABSOLUTE int_sel_not_cmd = 0xab930014 -ABSOLUTE int_status_not_msgin = 0xab930015 -ABSOLUTE int_resel_not_msgin = 0xab930016 -ABSOLUTE int_reselected = 0xab930017 -ABSOLUTE int_selected = 0xab930018 -ABSOLUTE int_disc1 = 0xab930019 -ABSOLUTE int_disc2 = 0xab93001a -ABSOLUTE int_disc3 = 0xab93001b -ABSOLUTE int_not_rej = 0xab93001c -ABSOLUTE int_test1 = 0xab93001d - -/* Bit field settings used to record status in SCRATCH0 */ - -ABSOLUTE had_select = 0x01 -ABSOLUTE had_msgout = 0x02 -ABSOLUTE had_cmdout = 0x04 -ABSOLUTE had_datain = 0x08 -ABSOLUTE had_dataout = 0x10 -ABSOLUTE had_status = 0x20 -ABSOLUTE had_msgin = 0x40 -ABSOLUTE had_extmsg = 0x80 - -/* Bit field settings used to record status in SCRATCH1 */ - -ABSOLUTE did_reject = 0x01 - -/* These scripts are heavily based on the examples in the NCR 53C710 - * Programmer's Guide (Preliminary). - */ - -ENTRY do_select -do_select: - CLEAR TARGET - ; Enable selection timer - MOVE CTEST7 & 0xef TO CTEST7 - SELECT ATN FROM dsa_select, reselect - JUMP get_status, WHEN STATUS - ; Disable selection timer - MOVE CTEST7 | 0x10 TO CTEST7 - MOVE SCRATCH0 | had_select TO SCRATCH0 - INT int_sel_no_ident, IF NOT MSG_OUT - MOVE SCRATCH0 | had_msgout TO SCRATCH0 - MOVE FROM dsa_msgout, when MSG_OUT -ENTRY done_ident -done_ident: - JUMP get_status, IF STATUS -redo_msgin1: - JUMP get_msgin1, WHEN MSG_IN - INT int_sel_not_cmd, IF NOT CMD -ENTRY resume_cmd -resume_cmd: - MOVE SCRATCH0 | had_cmdout TO SCRATCH0 - MOVE FROM dsa_cmnd, WHEN CMD -ENTRY resume_pmm -resume_pmm: -redo_msgin2: - JUMP get_msgin2, WHEN MSG_IN - JUMP get_status, IF STATUS - JUMP input_data, IF DATA_IN - JUMP output_data, IF DATA_OUT - INT int_cmd_bad_phase - -get_status: - ; Disable selection timer - MOVE CTEST7 | 0x10 TO CTEST7 - MOVE FROM dsa_status, WHEN STATUS - INT int_status_not_msgin, WHEN NOT MSG_IN - MOVE FROM dsa_msgin, WHEN MSG_IN - INT int_not_cmd_complete, IF NOT 0x00 - CLEAR ACK -ENTRY wait_disc_complete -wait_disc_complete: - WAIT DISCONNECT - INT int_cmd_complete - -input_data: - MOVE SCRATCH0 | had_datain TO SCRATCH0 -ENTRY patch_input_data -patch_input_data: - JUMP 0 - MOVE FROM dsa_datain+0x0000, WHEN DATA_IN - MOVE FROM dsa_datain+0x0008, WHEN DATA_IN - MOVE FROM dsa_datain+0x0010, WHEN DATA_IN - MOVE FROM dsa_datain+0x0018, WHEN DATA_IN - MOVE FROM dsa_datain+0x0020, WHEN DATA_IN - MOVE FROM dsa_datain+0x0028, WHEN DATA_IN - MOVE FROM dsa_datain+0x0030, WHEN DATA_IN - MOVE FROM dsa_datain+0x0038, WHEN DATA_IN - MOVE FROM dsa_datain+0x0040, WHEN DATA_IN - MOVE FROM dsa_datain+0x0048, WHEN DATA_IN - MOVE FROM dsa_datain+0x0050, WHEN DATA_IN - MOVE FROM dsa_datain+0x0058, WHEN DATA_IN - MOVE FROM dsa_datain+0x0060, WHEN DATA_IN - MOVE FROM dsa_datain+0x0068, WHEN DATA_IN - MOVE FROM dsa_datain+0x0070, WHEN DATA_IN - MOVE FROM dsa_datain+0x0078, WHEN DATA_IN - MOVE FROM dsa_datain+0x0080, WHEN DATA_IN - MOVE FROM dsa_datain+0x0088, WHEN DATA_IN - MOVE FROM dsa_datain+0x0090, WHEN DATA_IN - MOVE FROM dsa_datain+0x0098, WHEN DATA_IN - MOVE FROM dsa_datain+0x00a0, WHEN DATA_IN - MOVE FROM dsa_datain+0x00a8, WHEN DATA_IN - MOVE FROM dsa_datain+0x00b0, WHEN DATA_IN - MOVE FROM dsa_datain+0x00b8, WHEN DATA_IN - MOVE FROM dsa_datain+0x00c0, WHEN DATA_IN - MOVE FROM dsa_datain+0x00c8, WHEN DATA_IN - MOVE FROM dsa_datain+0x00d0, WHEN DATA_IN - MOVE FROM dsa_datain+0x00d8, WHEN DATA_IN - MOVE FROM dsa_datain+0x00e0, WHEN DATA_IN - MOVE FROM dsa_datain+0x00e8, WHEN DATA_IN - MOVE FROM dsa_datain+0x00f0, WHEN DATA_IN - MOVE FROM dsa_datain+0x00f8, WHEN DATA_IN - MOVE FROM dsa_datain+0x0100, WHEN DATA_IN - MOVE FROM dsa_datain+0x0108, WHEN DATA_IN - MOVE FROM dsa_datain+0x0110, WHEN DATA_IN - MOVE FROM dsa_datain+0x0118, WHEN DATA_IN - MOVE FROM dsa_datain+0x0120, WHEN DATA_IN - MOVE FROM dsa_datain+0x0128, WHEN DATA_IN - MOVE FROM dsa_datain+0x0130, WHEN DATA_IN - MOVE FROM dsa_datain+0x0138, WHEN DATA_IN - MOVE FROM dsa_datain+0x0140, WHEN DATA_IN - MOVE FROM dsa_datain+0x0148, WHEN DATA_IN - MOVE FROM dsa_datain+0x0150, WHEN DATA_IN - MOVE FROM dsa_datain+0x0158, WHEN DATA_IN - MOVE FROM dsa_datain+0x0160, WHEN DATA_IN - MOVE FROM dsa_datain+0x0168, WHEN DATA_IN - MOVE FROM dsa_datain+0x0170, WHEN DATA_IN - MOVE FROM dsa_datain+0x0178, WHEN DATA_IN - MOVE FROM dsa_datain+0x0180, WHEN DATA_IN - MOVE FROM dsa_datain+0x0188, WHEN DATA_IN - MOVE FROM dsa_datain+0x0190, WHEN DATA_IN - MOVE FROM dsa_datain+0x0198, WHEN DATA_IN - MOVE FROM dsa_datain+0x01a0, WHEN DATA_IN - MOVE FROM dsa_datain+0x01a8, WHEN DATA_IN - MOVE FROM dsa_datain+0x01b0, WHEN DATA_IN - MOVE FROM dsa_datain+0x01b8, WHEN DATA_IN - MOVE FROM dsa_datain+0x01c0, WHEN DATA_IN - MOVE FROM dsa_datain+0x01c8, WHEN DATA_IN - MOVE FROM dsa_datain+0x01d0, WHEN DATA_IN - MOVE FROM dsa_datain+0x01d8, WHEN DATA_IN - MOVE FROM dsa_datain+0x01e0, WHEN DATA_IN - MOVE FROM dsa_datain+0x01e8, WHEN DATA_IN - MOVE FROM dsa_datain+0x01f0, WHEN DATA_IN - MOVE FROM dsa_datain+0x01f8, WHEN DATA_IN - MOVE FROM dsa_datain+0x0200, WHEN DATA_IN - MOVE FROM dsa_datain+0x0208, WHEN DATA_IN - MOVE FROM dsa_datain+0x0210, WHEN DATA_IN - MOVE FROM dsa_datain+0x0218, WHEN DATA_IN - MOVE FROM dsa_datain+0x0220, WHEN DATA_IN - MOVE FROM dsa_datain+0x0228, WHEN DATA_IN - MOVE FROM dsa_datain+0x0230, WHEN DATA_IN - MOVE FROM dsa_datain+0x0238, WHEN DATA_IN - MOVE FROM dsa_datain+0x0240, WHEN DATA_IN - MOVE FROM dsa_datain+0x0248, WHEN DATA_IN - MOVE FROM dsa_datain+0x0250, WHEN DATA_IN - MOVE FROM dsa_datain+0x0258, WHEN DATA_IN - MOVE FROM dsa_datain+0x0260, WHEN DATA_IN - MOVE FROM dsa_datain+0x0268, WHEN DATA_IN - MOVE FROM dsa_datain+0x0270, WHEN DATA_IN - MOVE FROM dsa_datain+0x0278, WHEN DATA_IN - MOVE FROM dsa_datain+0x0280, WHEN DATA_IN - MOVE FROM dsa_datain+0x0288, WHEN DATA_IN - MOVE FROM dsa_datain+0x0290, WHEN DATA_IN - MOVE FROM dsa_datain+0x0298, WHEN DATA_IN - MOVE FROM dsa_datain+0x02a0, WHEN DATA_IN - MOVE FROM dsa_datain+0x02a8, WHEN DATA_IN - MOVE FROM dsa_datain+0x02b0, WHEN DATA_IN - MOVE FROM dsa_datain+0x02b8, WHEN DATA_IN - MOVE FROM dsa_datain+0x02c0, WHEN DATA_IN - MOVE FROM dsa_datain+0x02c8, WHEN DATA_IN - MOVE FROM dsa_datain+0x02d0, WHEN DATA_IN - MOVE FROM dsa_datain+0x02d8, WHEN DATA_IN - MOVE FROM dsa_datain+0x02e0, WHEN DATA_IN - MOVE FROM dsa_datain+0x02e8, WHEN DATA_IN - MOVE FROM dsa_datain+0x02f0, WHEN DATA_IN - MOVE FROM dsa_datain+0x02f8, WHEN DATA_IN - MOVE FROM dsa_datain+0x0300, WHEN DATA_IN - MOVE FROM dsa_datain+0x0308, WHEN DATA_IN - MOVE FROM dsa_datain+0x0310, WHEN DATA_IN - MOVE FROM dsa_datain+0x0318, WHEN DATA_IN - MOVE FROM dsa_datain+0x0320, WHEN DATA_IN - MOVE FROM dsa_datain+0x0328, WHEN DATA_IN - MOVE FROM dsa_datain+0x0330, WHEN DATA_IN - MOVE FROM dsa_datain+0x0338, WHEN DATA_IN - MOVE FROM dsa_datain+0x0340, WHEN DATA_IN - MOVE FROM dsa_datain+0x0348, WHEN DATA_IN - MOVE FROM dsa_datain+0x0350, WHEN DATA_IN - MOVE FROM dsa_datain+0x0358, WHEN DATA_IN - MOVE FROM dsa_datain+0x0360, WHEN DATA_IN - MOVE FROM dsa_datain+0x0368, WHEN DATA_IN - MOVE FROM dsa_datain+0x0370, WHEN DATA_IN - MOVE FROM dsa_datain+0x0378, WHEN DATA_IN - MOVE FROM dsa_datain+0x0380, WHEN DATA_IN - MOVE FROM dsa_datain+0x0388, WHEN DATA_IN - MOVE FROM dsa_datain+0x0390, WHEN DATA_IN - MOVE FROM dsa_datain+0x0398, WHEN DATA_IN - MOVE FROM dsa_datain+0x03a0, WHEN DATA_IN - MOVE FROM dsa_datain+0x03a8, WHEN DATA_IN - MOVE FROM dsa_datain+0x03b0, WHEN DATA_IN - MOVE FROM dsa_datain+0x03b8, WHEN DATA_IN - MOVE FROM dsa_datain+0x03c0, WHEN DATA_IN - MOVE FROM dsa_datain+0x03c8, WHEN DATA_IN - MOVE FROM dsa_datain+0x03d0, WHEN DATA_IN - MOVE FROM dsa_datain+0x03d8, WHEN DATA_IN - MOVE FROM dsa_datain+0x03e0, WHEN DATA_IN - MOVE FROM dsa_datain+0x03e8, WHEN DATA_IN - MOVE FROM dsa_datain+0x03f0, WHEN DATA_IN - MOVE FROM dsa_datain+0x03f8, WHEN DATA_IN - JUMP end_data_trans - -output_data: - MOVE SCRATCH0 | had_dataout TO SCRATCH0 -ENTRY patch_output_data -patch_output_data: - JUMP 0 - MOVE FROM dsa_dataout+0x0000, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0008, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0010, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0018, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0020, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0028, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0030, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0038, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0040, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0048, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0050, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0058, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0060, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0068, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0070, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0078, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0080, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0088, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0090, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0098, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00a0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00a8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00b0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00b8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00c0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00c8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00d0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00d8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00e0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00e8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00f0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x00f8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0100, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0108, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0110, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0118, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0120, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0128, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0130, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0138, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0140, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0148, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0150, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0158, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0160, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0168, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0170, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0178, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0180, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0188, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0190, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0198, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01a0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01a8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01b0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01b8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01c0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01c8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01d0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01d8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01e0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01e8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01f0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x01f8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0200, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0208, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0210, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0218, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0220, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0228, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0230, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0238, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0240, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0248, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0250, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0258, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0260, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0268, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0270, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0278, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0280, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0288, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0290, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0298, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02a0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02a8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02b0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02b8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02c0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02c8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02d0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02d8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02e0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02e8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02f0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x02f8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0300, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0308, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0310, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0318, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0320, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0328, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0330, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0338, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0340, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0348, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0350, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0358, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0360, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0368, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0370, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0378, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0380, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0388, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0390, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x0398, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03a0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03a8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03b0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03b8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03c0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03c8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03d0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03d8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03e0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03e8, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03f0, WHEN DATA_OUT - MOVE FROM dsa_dataout+0x03f8, WHEN DATA_OUT -ENTRY end_data_trans -end_data_trans: -redo_msgin3: - JUMP get_status, WHEN STATUS - JUMP get_msgin3, WHEN MSG_IN - INT int_data_bad_phase - -get_msgin1: - MOVE SCRATCH0 | had_msgin TO SCRATCH0 - MOVE 1, msgin_buf, WHEN MSG_IN - JUMP ext_msg1, IF 0x01 ; Extended Message - JUMP ignore_msg1, IF 0x02 ; Save Data Pointers - JUMP ignore_msg1, IF 0x03 ; Save Restore Pointers - JUMP disc1, IF 0x04 ; Disconnect - INT int_bad_msg1 -ignore_msg1: - CLEAR ACK - JUMP redo_msgin1 -ext_msg1: - MOVE SCRATCH0 | had_extmsg TO SCRATCH0 - CLEAR ACK - MOVE 1, msgin_buf + 1, WHEN MSG_IN - JUMP reject_msg1, IF NOT 0x03 ; Only handle SDTR - CLEAR ACK - MOVE 1, msgin_buf + 2, WHEN MSG_IN - JUMP reject_msg1, IF NOT 0x01 ; Only handle SDTR - CLEAR ACK - MOVE 2, msgin_buf + 3, WHEN MSG_IN - INT int_msg_sdtr1 -reject_msg1: - MOVE SCRATCH1 | did_reject TO SCRATCH1 - SET ATN - CLEAR ACK - JUMP reject_msg1a, WHEN NOT MSG_IN - MOVE 1, msgin_buf + 7, WHEN MSG_IN - JUMP reject_msg1 -reject_msg1a: - MOVE 1, msg_reject, WHEN MSG_OUT - JUMP redo_msgin1 -disc1: - CLEAR ACK -ENTRY wait_disc1 -wait_disc1: - WAIT DISCONNECT - INT int_disc1 -ENTRY resume_msgin1a -resume_msgin1a: - CLEAR ACK - JUMP redo_msgin1 -ENTRY resume_msgin1b -resume_msgin1b: - SET ATN - CLEAR ACK - INT int_no_msgout1, WHEN NOT MSG_OUT - MOVE SCRATCH0 | had_msgout TO SCRATCH0 - MOVE FROM dsa_msgout, when MSG_OUT - JUMP redo_msgin1 - -get_msgin2: - MOVE SCRATCH0 | had_msgin TO SCRATCH0 - MOVE 1, msgin_buf, WHEN MSG_IN - JUMP ext_msg2, IF 0x01 ; Extended Message - JUMP ignore_msg2, IF 0x02 ; Save Data Pointers - JUMP ignore_msg2, IF 0x03 ; Save Restore Pointers - JUMP disc2, IF 0x04 ; Disconnect - INT int_bad_msg2 -ignore_msg2: - CLEAR ACK - JUMP redo_msgin2 -ext_msg2: - MOVE SCRATCH0 | had_extmsg TO SCRATCH0 - CLEAR ACK - MOVE 1, msgin_buf + 1, WHEN MSG_IN - JUMP reject_msg2, IF NOT 0x03 ; Only handle SDTR - CLEAR ACK - MOVE 1, msgin_buf + 2, WHEN MSG_IN - JUMP reject_msg2, IF NOT 0x01 ; Only handle SDTR - CLEAR ACK - MOVE 2, msgin_buf + 3, WHEN MSG_IN - INT int_msg_sdtr2 -reject_msg2: - MOVE SCRATCH1 | did_reject TO SCRATCH1 - SET ATN - CLEAR ACK - JUMP reject_msg2a, WHEN NOT MSG_IN - MOVE 1, msgin_buf + 7, WHEN MSG_IN - JUMP reject_msg2 -reject_msg2a: - MOVE 1, msg_reject, WHEN MSG_OUT - JUMP redo_msgin2 -disc2: - CLEAR ACK -ENTRY wait_disc2 -wait_disc2: - WAIT DISCONNECT - INT int_disc2 -ENTRY resume_msgin2a -resume_msgin2a: - CLEAR ACK - JUMP redo_msgin2 -ENTRY resume_msgin2b -resume_msgin2b: - SET ATN - CLEAR ACK - INT int_no_msgout2, WHEN NOT MSG_OUT - MOVE SCRATCH0 | had_msgout TO SCRATCH0 - MOVE FROM dsa_msgout, when MSG_OUT - JUMP redo_msgin2 - -get_msgin3: - MOVE SCRATCH0 | had_msgin TO SCRATCH0 - MOVE 1, msgin_buf, WHEN MSG_IN - JUMP ext_msg3, IF 0x01 ; Extended Message - JUMP ignore_msg3, IF 0x02 ; Save Data Pointers - JUMP ignore_msg3, IF 0x03 ; Save Restore Pointers - JUMP disc3, IF 0x04 ; Disconnect - INT int_bad_msg3 -ignore_msg3: - CLEAR ACK - JUMP redo_msgin3 -ext_msg3: - MOVE SCRATCH0 | had_extmsg TO SCRATCH0 - CLEAR ACK - MOVE 1, msgin_buf + 1, WHEN MSG_IN - JUMP reject_msg3, IF NOT 0x03 ; Only handle SDTR - CLEAR ACK - MOVE 1, msgin_buf + 2, WHEN MSG_IN - JUMP reject_msg3, IF NOT 0x01 ; Only handle SDTR - CLEAR ACK - MOVE 2, msgin_buf + 3, WHEN MSG_IN - INT int_msg_sdtr3 -reject_msg3: - MOVE SCRATCH1 | did_reject TO SCRATCH1 - SET ATN - CLEAR ACK - JUMP reject_msg3a, WHEN NOT MSG_IN - MOVE 1, msgin_buf + 7, WHEN MSG_IN - JUMP reject_msg3 -reject_msg3a: - MOVE 1, msg_reject, WHEN MSG_OUT - JUMP redo_msgin3 -disc3: - CLEAR ACK -ENTRY wait_disc3 -wait_disc3: - WAIT DISCONNECT - INT int_disc3 -ENTRY resume_msgin3a -resume_msgin3a: - CLEAR ACK - JUMP redo_msgin3 -ENTRY resume_msgin3b -resume_msgin3b: - SET ATN - CLEAR ACK - INT int_no_msgout3, WHEN NOT MSG_OUT - MOVE SCRATCH0 | had_msgout TO SCRATCH0 - MOVE FROM dsa_msgout, when MSG_OUT - JUMP redo_msgin3 - -ENTRY resume_rej_ident -resume_rej_ident: - CLEAR ATN - MOVE 1, msgin_buf, WHEN MSG_IN - INT int_not_rej, IF NOT 0x07 ; Reject - CLEAR ACK - JUMP done_ident - -ENTRY reselect -reselect: - ; Disable selection timer - MOVE CTEST7 | 0x10 TO CTEST7 - WAIT RESELECT resel_err - INT int_resel_not_msgin, WHEN NOT MSG_IN - MOVE 1, reselected_identify, WHEN MSG_IN - INT int_reselected -resel_err: - MOVE CTEST2 & 0x40 TO SFBR - JUMP selected, IF 0x00 - MOVE SFBR & 0 TO SFBR -ENTRY patch_new_dsa -patch_new_dsa: - MOVE SFBR | 0x11 TO DSA0 - MOVE SFBR | 0x22 TO DSA1 - MOVE SFBR | 0x33 TO DSA2 - MOVE SFBR | 0x44 TO DSA3 - JUMP do_select - -selected: - INT int_selected - -ENTRY test1 -test1: - MOVE MEMORY 4, test1_src, test1_dst - INT int_test1 - diff -Nru a/drivers/scsi/sim710_d.h_shipped b/drivers/scsi/sim710_d.h_shipped --- a/drivers/scsi/sim710_d.h_shipped Sun Feb 9 21:13:31 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2452 +0,0 @@ -/* DO NOT EDIT - Generated automatically by script_asm.pl */ -static u32 SCRIPT[] = { -/* - - - - - - -ABSOLUTE dsa_select = 0 -ABSOLUTE dsa_msgout = 8 -ABSOLUTE dsa_cmnd = 16 -ABSOLUTE dsa_status = 24 -ABSOLUTE dsa_msgin = 32 -ABSOLUTE dsa_datain = 40 -ABSOLUTE dsa_dataout = 1064 -ABSOLUTE dsa_size = 2088 - -ABSOLUTE reselected_identify = 0 -ABSOLUTE msgin_buf = 0 -ABSOLUTE msg_reject = 0 -ABSOLUTE test1_src = 0 -ABSOLUTE test1_dst = 0 - - - -ABSOLUTE int_bad_msg1 = 0xab930006 -ABSOLUTE int_bad_msg2 = 0xab930007 -ABSOLUTE int_bad_msg3 = 0xab930008 -ABSOLUTE int_cmd_bad_phase = 0xab930009 -ABSOLUTE int_cmd_complete = 0xab93000a -ABSOLUTE int_data_bad_phase = 0xab93000b -ABSOLUTE int_msg_sdtr1 = 0xab93000c -ABSOLUTE int_msg_sdtr2 = 0xab93000d -ABSOLUTE int_msg_sdtr3 = 0xab93000e -ABSOLUTE int_no_msgout1 = 0xab93000f -ABSOLUTE int_no_msgout2 = 0xab930010 -ABSOLUTE int_no_msgout3 = 0xab930011 -ABSOLUTE int_not_cmd_complete = 0xab930012 -ABSOLUTE int_sel_no_ident = 0xab930013 -ABSOLUTE int_sel_not_cmd = 0xab930014 -ABSOLUTE int_status_not_msgin = 0xab930015 -ABSOLUTE int_resel_not_msgin = 0xab930016 -ABSOLUTE int_reselected = 0xab930017 -ABSOLUTE int_selected = 0xab930018 -ABSOLUTE int_disc1 = 0xab930019 -ABSOLUTE int_disc2 = 0xab93001a -ABSOLUTE int_disc3 = 0xab93001b -ABSOLUTE int_not_rej = 0xab93001c -ABSOLUTE int_test1 = 0xab93001d - - - -ABSOLUTE had_select = 0x01 -ABSOLUTE had_msgout = 0x02 -ABSOLUTE had_cmdout = 0x04 -ABSOLUTE had_datain = 0x08 -ABSOLUTE had_dataout = 0x10 -ABSOLUTE had_status = 0x20 -ABSOLUTE had_msgin = 0x40 -ABSOLUTE had_extmsg = 0x80 - - - -ABSOLUTE did_reject = 0x01 - - - - - -ENTRY do_select -do_select: - CLEAR TARGET - -at 0x00000000 : */ 0x60000200,0x00000000, -/* - ; Enable selection timer - MOVE CTEST7 & 0xef TO CTEST7 - -at 0x00000002 : */ 0x7c1bef00,0x00000000, -/* - SELECT ATN FROM dsa_select, reselect - -at 0x00000004 : */ 0x43000000,0x00000cd0, -/* - JUMP get_status, WHEN STATUS - -at 0x00000006 : */ 0x830b0000,0x00000098, -/* - ; Disable selection timer - MOVE CTEST7 | 0x10 TO CTEST7 - -at 0x00000008 : */ 0x7a1b1000,0x00000000, -/* - MOVE SCRATCH0 | had_select TO SCRATCH0 - -at 0x0000000a : */ 0x7a340100,0x00000000, -/* - INT int_sel_no_ident, IF NOT MSG_OUT - -at 0x0000000c : */ 0x9e020000,0xab930013, -/* - MOVE SCRATCH0 | had_msgout TO SCRATCH0 - -at 0x0000000e : */ 0x7a340200,0x00000000, -/* - MOVE FROM dsa_msgout, when MSG_OUT - -at 0x00000010 : */ 0x1e000000,0x00000008, -/* -ENTRY done_ident -done_ident: - JUMP get_status, IF STATUS - -at 0x00000012 : */ 0x830a0000,0x00000098, -/* -redo_msgin1: - JUMP get_msgin1, WHEN MSG_IN - -at 0x00000014 : */ 0x870b0000,0x00000918, -/* - INT int_sel_not_cmd, IF NOT CMD - -at 0x00000016 : */ 0x9a020000,0xab930014, -/* -ENTRY resume_cmd -resume_cmd: - MOVE SCRATCH0 | had_cmdout TO SCRATCH0 - -at 0x00000018 : */ 0x7a340400,0x00000000, -/* - MOVE FROM dsa_cmnd, WHEN CMD - -at 0x0000001a : */ 0x1a000000,0x00000010, -/* -ENTRY resume_pmm -resume_pmm: -redo_msgin2: - JUMP get_msgin2, WHEN MSG_IN - -at 0x0000001c : */ 0x870b0000,0x00000a48, -/* - JUMP get_status, IF STATUS - -at 0x0000001e : */ 0x830a0000,0x00000098, -/* - JUMP input_data, IF DATA_IN - -at 0x00000020 : */ 0x810a0000,0x000000d8, -/* - JUMP output_data, IF DATA_OUT - -at 0x00000022 : */ 0x800a0000,0x000004f0, -/* - INT int_cmd_bad_phase - -at 0x00000024 : */ 0x98080000,0xab930009, -/* - -get_status: - ; Disable selection timer - MOVE CTEST7 | 0x10 TO CTEST7 - -at 0x00000026 : */ 0x7a1b1000,0x00000000, -/* - MOVE FROM dsa_status, WHEN STATUS - -at 0x00000028 : */ 0x1b000000,0x00000018, -/* - INT int_status_not_msgin, WHEN NOT MSG_IN - -at 0x0000002a : */ 0x9f030000,0xab930015, -/* - MOVE FROM dsa_msgin, WHEN MSG_IN - -at 0x0000002c : */ 0x1f000000,0x00000020, -/* - INT int_not_cmd_complete, IF NOT 0x00 - -at 0x0000002e : */ 0x98040000,0xab930012, -/* - CLEAR ACK - -at 0x00000030 : */ 0x60000040,0x00000000, -/* -ENTRY wait_disc_complete -wait_disc_complete: - WAIT DISCONNECT - -at 0x00000032 : */ 0x48000000,0x00000000, -/* - INT int_cmd_complete - -at 0x00000034 : */ 0x98080000,0xab93000a, -/* - -input_data: - MOVE SCRATCH0 | had_datain TO SCRATCH0 - -at 0x00000036 : */ 0x7a340800,0x00000000, -/* -ENTRY patch_input_data -patch_input_data: - JUMP 0 - -at 0x00000038 : */ 0x80080000,0x00000000, -/* - MOVE FROM dsa_datain+0x0000, WHEN DATA_IN - -at 0x0000003a : */ 0x19000000,0x00000028, -/* - MOVE FROM dsa_datain+0x0008, WHEN DATA_IN - -at 0x0000003c : */ 0x19000000,0x00000030, -/* - MOVE FROM dsa_datain+0x0010, WHEN DATA_IN - -at 0x0000003e : */ 0x19000000,0x00000038, -/* - MOVE FROM dsa_datain+0x0018, WHEN DATA_IN - -at 0x00000040 : */ 0x19000000,0x00000040, -/* - MOVE FROM dsa_datain+0x0020, WHEN DATA_IN - -at 0x00000042 : */ 0x19000000,0x00000048, -/* - MOVE FROM dsa_datain+0x0028, WHEN DATA_IN - -at 0x00000044 : */ 0x19000000,0x00000050, -/* - MOVE FROM dsa_datain+0x0030, WHEN DATA_IN - -at 0x00000046 : */ 0x19000000,0x00000058, -/* - MOVE FROM dsa_datain+0x0038, WHEN DATA_IN - -at 0x00000048 : */ 0x19000000,0x00000060, -/* - MOVE FROM dsa_datain+0x0040, WHEN DATA_IN - -at 0x0000004a : */ 0x19000000,0x00000068, -/* - MOVE FROM dsa_datain+0x0048, WHEN DATA_IN - -at 0x0000004c : */ 0x19000000,0x00000070, -/* - MOVE FROM dsa_datain+0x0050, WHEN DATA_IN - -at 0x0000004e : */ 0x19000000,0x00000078, -/* - MOVE FROM dsa_datain+0x0058, WHEN DATA_IN - -at 0x00000050 : */ 0x19000000,0x00000080, -/* - MOVE FROM dsa_datain+0x0060, WHEN DATA_IN - -at 0x00000052 : */ 0x19000000,0x00000088, -/* - MOVE FROM dsa_datain+0x0068, WHEN DATA_IN - -at 0x00000054 : */ 0x19000000,0x00000090, -/* - MOVE FROM dsa_datain+0x0070, WHEN DATA_IN - -at 0x00000056 : */ 0x19000000,0x00000098, -/* - MOVE FROM dsa_datain+0x0078, WHEN DATA_IN - -at 0x00000058 : */ 0x19000000,0x000000a0, -/* - MOVE FROM dsa_datain+0x0080, WHEN DATA_IN - -at 0x0000005a : */ 0x19000000,0x000000a8, -/* - MOVE FROM dsa_datain+0x0088, WHEN DATA_IN - -at 0x0000005c : */ 0x19000000,0x000000b0, -/* - MOVE FROM dsa_datain+0x0090, WHEN DATA_IN - -at 0x0000005e : */ 0x19000000,0x000000b8, -/* - MOVE FROM dsa_datain+0x0098, WHEN DATA_IN - -at 0x00000060 : */ 0x19000000,0x000000c0, -/* - MOVE FROM dsa_datain+0x00a0, WHEN DATA_IN - -at 0x00000062 : */ 0x19000000,0x000000c8, -/* - MOVE FROM dsa_datain+0x00a8, WHEN DATA_IN - -at 0x00000064 : */ 0x19000000,0x000000d0, -/* - MOVE FROM dsa_datain+0x00b0, WHEN DATA_IN - -at 0x00000066 : */ 0x19000000,0x000000d8, -/* - MOVE FROM dsa_datain+0x00b8, WHEN DATA_IN - -at 0x00000068 : */ 0x19000000,0x000000e0, -/* - MOVE FROM dsa_datain+0x00c0, WHEN DATA_IN - -at 0x0000006a : */ 0x19000000,0x000000e8, -/* - MOVE FROM dsa_datain+0x00c8, WHEN DATA_IN - -at 0x0000006c : */ 0x19000000,0x000000f0, -/* - MOVE FROM dsa_datain+0x00d0, WHEN DATA_IN - -at 0x0000006e : */ 0x19000000,0x000000f8, -/* - MOVE FROM dsa_datain+0x00d8, WHEN DATA_IN - -at 0x00000070 : */ 0x19000000,0x00000100, -/* - MOVE FROM dsa_datain+0x00e0, WHEN DATA_IN - -at 0x00000072 : */ 0x19000000,0x00000108, -/* - MOVE FROM dsa_datain+0x00e8, WHEN DATA_IN - -at 0x00000074 : */ 0x19000000,0x00000110, -/* - MOVE FROM dsa_datain+0x00f0, WHEN DATA_IN - -at 0x00000076 : */ 0x19000000,0x00000118, -/* - MOVE FROM dsa_datain+0x00f8, WHEN DATA_IN - -at 0x00000078 : */ 0x19000000,0x00000120, -/* - MOVE FROM dsa_datain+0x0100, WHEN DATA_IN - -at 0x0000007a : */ 0x19000000,0x00000128, -/* - MOVE FROM dsa_datain+0x0108, WHEN DATA_IN - -at 0x0000007c : */ 0x19000000,0x00000130, -/* - MOVE FROM dsa_datain+0x0110, WHEN DATA_IN - -at 0x0000007e : */ 0x19000000,0x00000138, -/* - MOVE FROM dsa_datain+0x0118, WHEN DATA_IN - -at 0x00000080 : */ 0x19000000,0x00000140, -/* - MOVE FROM dsa_datain+0x0120, WHEN DATA_IN - -at 0x00000082 : */ 0x19000000,0x00000148, -/* - MOVE FROM dsa_datain+0x0128, WHEN DATA_IN - -at 0x00000084 : */ 0x19000000,0x00000150, -/* - MOVE FROM dsa_datain+0x0130, WHEN DATA_IN - -at 0x00000086 : */ 0x19000000,0x00000158, -/* - MOVE FROM dsa_datain+0x0138, WHEN DATA_IN - -at 0x00000088 : */ 0x19000000,0x00000160, -/* - MOVE FROM dsa_datain+0x0140, WHEN DATA_IN - -at 0x0000008a : */ 0x19000000,0x00000168, -/* - MOVE FROM dsa_datain+0x0148, WHEN DATA_IN - -at 0x0000008c : */ 0x19000000,0x00000170, -/* - MOVE FROM dsa_datain+0x0150, WHEN DATA_IN - -at 0x0000008e : */ 0x19000000,0x00000178, -/* - MOVE FROM dsa_datain+0x0158, WHEN DATA_IN - -at 0x00000090 : */ 0x19000000,0x00000180, -/* - MOVE FROM dsa_datain+0x0160, WHEN DATA_IN - -at 0x00000092 : */ 0x19000000,0x00000188, -/* - MOVE FROM dsa_datain+0x0168, WHEN DATA_IN - -at 0x00000094 : */ 0x19000000,0x00000190, -/* - MOVE FROM dsa_datain+0x0170, WHEN DATA_IN - -at 0x00000096 : */ 0x19000000,0x00000198, -/* - MOVE FROM dsa_datain+0x0178, WHEN DATA_IN - -at 0x00000098 : */ 0x19000000,0x000001a0, -/* - MOVE FROM dsa_datain+0x0180, WHEN DATA_IN - -at 0x0000009a : */ 0x19000000,0x000001a8, -/* - MOVE FROM dsa_datain+0x0188, WHEN DATA_IN - -at 0x0000009c : */ 0x19000000,0x000001b0, -/* - MOVE FROM dsa_datain+0x0190, WHEN DATA_IN - -at 0x0000009e : */ 0x19000000,0x000001b8, -/* - MOVE FROM dsa_datain+0x0198, WHEN DATA_IN - -at 0x000000a0 : */ 0x19000000,0x000001c0, -/* - MOVE FROM dsa_datain+0x01a0, WHEN DATA_IN - -at 0x000000a2 : */ 0x19000000,0x000001c8, -/* - MOVE FROM dsa_datain+0x01a8, WHEN DATA_IN - -at 0x000000a4 : */ 0x19000000,0x000001d0, -/* - MOVE FROM dsa_datain+0x01b0, WHEN DATA_IN - -at 0x000000a6 : */ 0x19000000,0x000001d8, -/* - MOVE FROM dsa_datain+0x01b8, WHEN DATA_IN - -at 0x000000a8 : */ 0x19000000,0x000001e0, -/* - MOVE FROM dsa_datain+0x01c0, WHEN DATA_IN - -at 0x000000aa : */ 0x19000000,0x000001e8, -/* - MOVE FROM dsa_datain+0x01c8, WHEN DATA_IN - -at 0x000000ac : */ 0x19000000,0x000001f0, -/* - MOVE FROM dsa_datain+0x01d0, WHEN DATA_IN - -at 0x000000ae : */ 0x19000000,0x000001f8, -/* - MOVE FROM dsa_datain+0x01d8, WHEN DATA_IN - -at 0x000000b0 : */ 0x19000000,0x00000200, -/* - MOVE FROM dsa_datain+0x01e0, WHEN DATA_IN - -at 0x000000b2 : */ 0x19000000,0x00000208, -/* - MOVE FROM dsa_datain+0x01e8, WHEN DATA_IN - -at 0x000000b4 : */ 0x19000000,0x00000210, -/* - MOVE FROM dsa_datain+0x01f0, WHEN DATA_IN - -at 0x000000b6 : */ 0x19000000,0x00000218, -/* - MOVE FROM dsa_datain+0x01f8, WHEN DATA_IN - -at 0x000000b8 : */ 0x19000000,0x00000220, -/* - MOVE FROM dsa_datain+0x0200, WHEN DATA_IN - -at 0x000000ba : */ 0x19000000,0x00000228, -/* - MOVE FROM dsa_datain+0x0208, WHEN DATA_IN - -at 0x000000bc : */ 0x19000000,0x00000230, -/* - MOVE FROM dsa_datain+0x0210, WHEN DATA_IN - -at 0x000000be : */ 0x19000000,0x00000238, -/* - MOVE FROM dsa_datain+0x0218, WHEN DATA_IN - -at 0x000000c0 : */ 0x19000000,0x00000240, -/* - MOVE FROM dsa_datain+0x0220, WHEN DATA_IN - -at 0x000000c2 : */ 0x19000000,0x00000248, -/* - MOVE FROM dsa_datain+0x0228, WHEN DATA_IN - -at 0x000000c4 : */ 0x19000000,0x00000250, -/* - MOVE FROM dsa_datain+0x0230, WHEN DATA_IN - -at 0x000000c6 : */ 0x19000000,0x00000258, -/* - MOVE FROM dsa_datain+0x0238, WHEN DATA_IN - -at 0x000000c8 : */ 0x19000000,0x00000260, -/* - MOVE FROM dsa_datain+0x0240, WHEN DATA_IN - -at 0x000000ca : */ 0x19000000,0x00000268, -/* - MOVE FROM dsa_datain+0x0248, WHEN DATA_IN - -at 0x000000cc : */ 0x19000000,0x00000270, -/* - MOVE FROM dsa_datain+0x0250, WHEN DATA_IN - -at 0x000000ce : */ 0x19000000,0x00000278, -/* - MOVE FROM dsa_datain+0x0258, WHEN DATA_IN - -at 0x000000d0 : */ 0x19000000,0x00000280, -/* - MOVE FROM dsa_datain+0x0260, WHEN DATA_IN - -at 0x000000d2 : */ 0x19000000,0x00000288, -/* - MOVE FROM dsa_datain+0x0268, WHEN DATA_IN - -at 0x000000d4 : */ 0x19000000,0x00000290, -/* - MOVE FROM dsa_datain+0x0270, WHEN DATA_IN - -at 0x000000d6 : */ 0x19000000,0x00000298, -/* - MOVE FROM dsa_datain+0x0278, WHEN DATA_IN - -at 0x000000d8 : */ 0x19000000,0x000002a0, -/* - MOVE FROM dsa_datain+0x0280, WHEN DATA_IN - -at 0x000000da : */ 0x19000000,0x000002a8, -/* - MOVE FROM dsa_datain+0x0288, WHEN DATA_IN - -at 0x000000dc : */ 0x19000000,0x000002b0, -/* - MOVE FROM dsa_datain+0x0290, WHEN DATA_IN - -at 0x000000de : */ 0x19000000,0x000002b8, -/* - MOVE FROM dsa_datain+0x0298, WHEN DATA_IN - -at 0x000000e0 : */ 0x19000000,0x000002c0, -/* - MOVE FROM dsa_datain+0x02a0, WHEN DATA_IN - -at 0x000000e2 : */ 0x19000000,0x000002c8, -/* - MOVE FROM dsa_datain+0x02a8, WHEN DATA_IN - -at 0x000000e4 : */ 0x19000000,0x000002d0, -/* - MOVE FROM dsa_datain+0x02b0, WHEN DATA_IN - -at 0x000000e6 : */ 0x19000000,0x000002d8, -/* - MOVE FROM dsa_datain+0x02b8, WHEN DATA_IN - -at 0x000000e8 : */ 0x19000000,0x000002e0, -/* - MOVE FROM dsa_datain+0x02c0, WHEN DATA_IN - -at 0x000000ea : */ 0x19000000,0x000002e8, -/* - MOVE FROM dsa_datain+0x02c8, WHEN DATA_IN - -at 0x000000ec : */ 0x19000000,0x000002f0, -/* - MOVE FROM dsa_datain+0x02d0, WHEN DATA_IN - -at 0x000000ee : */ 0x19000000,0x000002f8, -/* - MOVE FROM dsa_datain+0x02d8, WHEN DATA_IN - -at 0x000000f0 : */ 0x19000000,0x00000300, -/* - MOVE FROM dsa_datain+0x02e0, WHEN DATA_IN - -at 0x000000f2 : */ 0x19000000,0x00000308, -/* - MOVE FROM dsa_datain+0x02e8, WHEN DATA_IN - -at 0x000000f4 : */ 0x19000000,0x00000310, -/* - MOVE FROM dsa_datain+0x02f0, WHEN DATA_IN - -at 0x000000f6 : */ 0x19000000,0x00000318, -/* - MOVE FROM dsa_datain+0x02f8, WHEN DATA_IN - -at 0x000000f8 : */ 0x19000000,0x00000320, -/* - MOVE FROM dsa_datain+0x0300, WHEN DATA_IN - -at 0x000000fa : */ 0x19000000,0x00000328, -/* - MOVE FROM dsa_datain+0x0308, WHEN DATA_IN - -at 0x000000fc : */ 0x19000000,0x00000330, -/* - MOVE FROM dsa_datain+0x0310, WHEN DATA_IN - -at 0x000000fe : */ 0x19000000,0x00000338, -/* - MOVE FROM dsa_datain+0x0318, WHEN DATA_IN - -at 0x00000100 : */ 0x19000000,0x00000340, -/* - MOVE FROM dsa_datain+0x0320, WHEN DATA_IN - -at 0x00000102 : */ 0x19000000,0x00000348, -/* - MOVE FROM dsa_datain+0x0328, WHEN DATA_IN - -at 0x00000104 : */ 0x19000000,0x00000350, -/* - MOVE FROM dsa_datain+0x0330, WHEN DATA_IN - -at 0x00000106 : */ 0x19000000,0x00000358, -/* - MOVE FROM dsa_datain+0x0338, WHEN DATA_IN - -at 0x00000108 : */ 0x19000000,0x00000360, -/* - MOVE FROM dsa_datain+0x0340, WHEN DATA_IN - -at 0x0000010a : */ 0x19000000,0x00000368, -/* - MOVE FROM dsa_datain+0x0348, WHEN DATA_IN - -at 0x0000010c : */ 0x19000000,0x00000370, -/* - MOVE FROM dsa_datain+0x0350, WHEN DATA_IN - -at 0x0000010e : */ 0x19000000,0x00000378, -/* - MOVE FROM dsa_datain+0x0358, WHEN DATA_IN - -at 0x00000110 : */ 0x19000000,0x00000380, -/* - MOVE FROM dsa_datain+0x0360, WHEN DATA_IN - -at 0x00000112 : */ 0x19000000,0x00000388, -/* - MOVE FROM dsa_datain+0x0368, WHEN DATA_IN - -at 0x00000114 : */ 0x19000000,0x00000390, -/* - MOVE FROM dsa_datain+0x0370, WHEN DATA_IN - -at 0x00000116 : */ 0x19000000,0x00000398, -/* - MOVE FROM dsa_datain+0x0378, WHEN DATA_IN - -at 0x00000118 : */ 0x19000000,0x000003a0, -/* - MOVE FROM dsa_datain+0x0380, WHEN DATA_IN - -at 0x0000011a : */ 0x19000000,0x000003a8, -/* - MOVE FROM dsa_datain+0x0388, WHEN DATA_IN - -at 0x0000011c : */ 0x19000000,0x000003b0, -/* - MOVE FROM dsa_datain+0x0390, WHEN DATA_IN - -at 0x0000011e : */ 0x19000000,0x000003b8, -/* - MOVE FROM dsa_datain+0x0398, WHEN DATA_IN - -at 0x00000120 : */ 0x19000000,0x000003c0, -/* - MOVE FROM dsa_datain+0x03a0, WHEN DATA_IN - -at 0x00000122 : */ 0x19000000,0x000003c8, -/* - MOVE FROM dsa_datain+0x03a8, WHEN DATA_IN - -at 0x00000124 : */ 0x19000000,0x000003d0, -/* - MOVE FROM dsa_datain+0x03b0, WHEN DATA_IN - -at 0x00000126 : */ 0x19000000,0x000003d8, -/* - MOVE FROM dsa_datain+0x03b8, WHEN DATA_IN - -at 0x00000128 : */ 0x19000000,0x000003e0, -/* - MOVE FROM dsa_datain+0x03c0, WHEN DATA_IN - -at 0x0000012a : */ 0x19000000,0x000003e8, -/* - MOVE FROM dsa_datain+0x03c8, WHEN DATA_IN - -at 0x0000012c : */ 0x19000000,0x000003f0, -/* - MOVE FROM dsa_datain+0x03d0, WHEN DATA_IN - -at 0x0000012e : */ 0x19000000,0x000003f8, -/* - MOVE FROM dsa_datain+0x03d8, WHEN DATA_IN - -at 0x00000130 : */ 0x19000000,0x00000400, -/* - MOVE FROM dsa_datain+0x03e0, WHEN DATA_IN - -at 0x00000132 : */ 0x19000000,0x00000408, -/* - MOVE FROM dsa_datain+0x03e8, WHEN DATA_IN - -at 0x00000134 : */ 0x19000000,0x00000410, -/* - MOVE FROM dsa_datain+0x03f0, WHEN DATA_IN - -at 0x00000136 : */ 0x19000000,0x00000418, -/* - MOVE FROM dsa_datain+0x03f8, WHEN DATA_IN - -at 0x00000138 : */ 0x19000000,0x00000420, -/* - JUMP end_data_trans - -at 0x0000013a : */ 0x80080000,0x00000900, -/* - -output_data: - MOVE SCRATCH0 | had_dataout TO SCRATCH0 - -at 0x0000013c : */ 0x7a341000,0x00000000, -/* -ENTRY patch_output_data -patch_output_data: - JUMP 0 - -at 0x0000013e : */ 0x80080000,0x00000000, -/* - MOVE FROM dsa_dataout+0x0000, WHEN DATA_OUT - -at 0x00000140 : */ 0x18000000,0x00000428, -/* - MOVE FROM dsa_dataout+0x0008, WHEN DATA_OUT - -at 0x00000142 : */ 0x18000000,0x00000430, -/* - MOVE FROM dsa_dataout+0x0010, WHEN DATA_OUT - -at 0x00000144 : */ 0x18000000,0x00000438, -/* - MOVE FROM dsa_dataout+0x0018, WHEN DATA_OUT - -at 0x00000146 : */ 0x18000000,0x00000440, -/* - MOVE FROM dsa_dataout+0x0020, WHEN DATA_OUT - -at 0x00000148 : */ 0x18000000,0x00000448, -/* - MOVE FROM dsa_dataout+0x0028, WHEN DATA_OUT - -at 0x0000014a : */ 0x18000000,0x00000450, -/* - MOVE FROM dsa_dataout+0x0030, WHEN DATA_OUT - -at 0x0000014c : */ 0x18000000,0x00000458, -/* - MOVE FROM dsa_dataout+0x0038, WHEN DATA_OUT - -at 0x0000014e : */ 0x18000000,0x00000460, -/* - MOVE FROM dsa_dataout+0x0040, WHEN DATA_OUT - -at 0x00000150 : */ 0x18000000,0x00000468, -/* - MOVE FROM dsa_dataout+0x0048, WHEN DATA_OUT - -at 0x00000152 : */ 0x18000000,0x00000470, -/* - MOVE FROM dsa_dataout+0x0050, WHEN DATA_OUT - -at 0x00000154 : */ 0x18000000,0x00000478, -/* - MOVE FROM dsa_dataout+0x0058, WHEN DATA_OUT - -at 0x00000156 : */ 0x18000000,0x00000480, -/* - MOVE FROM dsa_dataout+0x0060, WHEN DATA_OUT - -at 0x00000158 : */ 0x18000000,0x00000488, -/* - MOVE FROM dsa_dataout+0x0068, WHEN DATA_OUT - -at 0x0000015a : */ 0x18000000,0x00000490, -/* - MOVE FROM dsa_dataout+0x0070, WHEN DATA_OUT - -at 0x0000015c : */ 0x18000000,0x00000498, -/* - MOVE FROM dsa_dataout+0x0078, WHEN DATA_OUT - -at 0x0000015e : */ 0x18000000,0x000004a0, -/* - MOVE FROM dsa_dataout+0x0080, WHEN DATA_OUT - -at 0x00000160 : */ 0x18000000,0x000004a8, -/* - MOVE FROM dsa_dataout+0x0088, WHEN DATA_OUT - -at 0x00000162 : */ 0x18000000,0x000004b0, -/* - MOVE FROM dsa_dataout+0x0090, WHEN DATA_OUT - -at 0x00000164 : */ 0x18000000,0x000004b8, -/* - MOVE FROM dsa_dataout+0x0098, WHEN DATA_OUT - -at 0x00000166 : */ 0x18000000,0x000004c0, -/* - MOVE FROM dsa_dataout+0x00a0, WHEN DATA_OUT - -at 0x00000168 : */ 0x18000000,0x000004c8, -/* - MOVE FROM dsa_dataout+0x00a8, WHEN DATA_OUT - -at 0x0000016a : */ 0x18000000,0x000004d0, -/* - MOVE FROM dsa_dataout+0x00b0, WHEN DATA_OUT - -at 0x0000016c : */ 0x18000000,0x000004d8, -/* - MOVE FROM dsa_dataout+0x00b8, WHEN DATA_OUT - -at 0x0000016e : */ 0x18000000,0x000004e0, -/* - MOVE FROM dsa_dataout+0x00c0, WHEN DATA_OUT - -at 0x00000170 : */ 0x18000000,0x000004e8, -/* - MOVE FROM dsa_dataout+0x00c8, WHEN DATA_OUT - -at 0x00000172 : */ 0x18000000,0x000004f0, -/* - MOVE FROM dsa_dataout+0x00d0, WHEN DATA_OUT - -at 0x00000174 : */ 0x18000000,0x000004f8, -/* - MOVE FROM dsa_dataout+0x00d8, WHEN DATA_OUT - -at 0x00000176 : */ 0x18000000,0x00000500, -/* - MOVE FROM dsa_dataout+0x00e0, WHEN DATA_OUT - -at 0x00000178 : */ 0x18000000,0x00000508, -/* - MOVE FROM dsa_dataout+0x00e8, WHEN DATA_OUT - -at 0x0000017a : */ 0x18000000,0x00000510, -/* - MOVE FROM dsa_dataout+0x00f0, WHEN DATA_OUT - -at 0x0000017c : */ 0x18000000,0x00000518, -/* - MOVE FROM dsa_dataout+0x00f8, WHEN DATA_OUT - -at 0x0000017e : */ 0x18000000,0x00000520, -/* - MOVE FROM dsa_dataout+0x0100, WHEN DATA_OUT - -at 0x00000180 : */ 0x18000000,0x00000528, -/* - MOVE FROM dsa_dataout+0x0108, WHEN DATA_OUT - -at 0x00000182 : */ 0x18000000,0x00000530, -/* - MOVE FROM dsa_dataout+0x0110, WHEN DATA_OUT - -at 0x00000184 : */ 0x18000000,0x00000538, -/* - MOVE FROM dsa_dataout+0x0118, WHEN DATA_OUT - -at 0x00000186 : */ 0x18000000,0x00000540, -/* - MOVE FROM dsa_dataout+0x0120, WHEN DATA_OUT - -at 0x00000188 : */ 0x18000000,0x00000548, -/* - MOVE FROM dsa_dataout+0x0128, WHEN DATA_OUT - -at 0x0000018a : */ 0x18000000,0x00000550, -/* - MOVE FROM dsa_dataout+0x0130, WHEN DATA_OUT - -at 0x0000018c : */ 0x18000000,0x00000558, -/* - MOVE FROM dsa_dataout+0x0138, WHEN DATA_OUT - -at 0x0000018e : */ 0x18000000,0x00000560, -/* - MOVE FROM dsa_dataout+0x0140, WHEN DATA_OUT - -at 0x00000190 : */ 0x18000000,0x00000568, -/* - MOVE FROM dsa_dataout+0x0148, WHEN DATA_OUT - -at 0x00000192 : */ 0x18000000,0x00000570, -/* - MOVE FROM dsa_dataout+0x0150, WHEN DATA_OUT - -at 0x00000194 : */ 0x18000000,0x00000578, -/* - MOVE FROM dsa_dataout+0x0158, WHEN DATA_OUT - -at 0x00000196 : */ 0x18000000,0x00000580, -/* - MOVE FROM dsa_dataout+0x0160, WHEN DATA_OUT - -at 0x00000198 : */ 0x18000000,0x00000588, -/* - MOVE FROM dsa_dataout+0x0168, WHEN DATA_OUT - -at 0x0000019a : */ 0x18000000,0x00000590, -/* - MOVE FROM dsa_dataout+0x0170, WHEN DATA_OUT - -at 0x0000019c : */ 0x18000000,0x00000598, -/* - MOVE FROM dsa_dataout+0x0178, WHEN DATA_OUT - -at 0x0000019e : */ 0x18000000,0x000005a0, -/* - MOVE FROM dsa_dataout+0x0180, WHEN DATA_OUT - -at 0x000001a0 : */ 0x18000000,0x000005a8, -/* - MOVE FROM dsa_dataout+0x0188, WHEN DATA_OUT - -at 0x000001a2 : */ 0x18000000,0x000005b0, -/* - MOVE FROM dsa_dataout+0x0190, WHEN DATA_OUT - -at 0x000001a4 : */ 0x18000000,0x000005b8, -/* - MOVE FROM dsa_dataout+0x0198, WHEN DATA_OUT - -at 0x000001a6 : */ 0x18000000,0x000005c0, -/* - MOVE FROM dsa_dataout+0x01a0, WHEN DATA_OUT - -at 0x000001a8 : */ 0x18000000,0x000005c8, -/* - MOVE FROM dsa_dataout+0x01a8, WHEN DATA_OUT - -at 0x000001aa : */ 0x18000000,0x000005d0, -/* - MOVE FROM dsa_dataout+0x01b0, WHEN DATA_OUT - -at 0x000001ac : */ 0x18000000,0x000005d8, -/* - MOVE FROM dsa_dataout+0x01b8, WHEN DATA_OUT - -at 0x000001ae : */ 0x18000000,0x000005e0, -/* - MOVE FROM dsa_dataout+0x01c0, WHEN DATA_OUT - -at 0x000001b0 : */ 0x18000000,0x000005e8, -/* - MOVE FROM dsa_dataout+0x01c8, WHEN DATA_OUT - -at 0x000001b2 : */ 0x18000000,0x000005f0, -/* - MOVE FROM dsa_dataout+0x01d0, WHEN DATA_OUT - -at 0x000001b4 : */ 0x18000000,0x000005f8, -/* - MOVE FROM dsa_dataout+0x01d8, WHEN DATA_OUT - -at 0x000001b6 : */ 0x18000000,0x00000600, -/* - MOVE FROM dsa_dataout+0x01e0, WHEN DATA_OUT - -at 0x000001b8 : */ 0x18000000,0x00000608, -/* - MOVE FROM dsa_dataout+0x01e8, WHEN DATA_OUT - -at 0x000001ba : */ 0x18000000,0x00000610, -/* - MOVE FROM dsa_dataout+0x01f0, WHEN DATA_OUT - -at 0x000001bc : */ 0x18000000,0x00000618, -/* - MOVE FROM dsa_dataout+0x01f8, WHEN DATA_OUT - -at 0x000001be : */ 0x18000000,0x00000620, -/* - MOVE FROM dsa_dataout+0x0200, WHEN DATA_OUT - -at 0x000001c0 : */ 0x18000000,0x00000628, -/* - MOVE FROM dsa_dataout+0x0208, WHEN DATA_OUT - -at 0x000001c2 : */ 0x18000000,0x00000630, -/* - MOVE FROM dsa_dataout+0x0210, WHEN DATA_OUT - -at 0x000001c4 : */ 0x18000000,0x00000638, -/* - MOVE FROM dsa_dataout+0x0218, WHEN DATA_OUT - -at 0x000001c6 : */ 0x18000000,0x00000640, -/* - MOVE FROM dsa_dataout+0x0220, WHEN DATA_OUT - -at 0x000001c8 : */ 0x18000000,0x00000648, -/* - MOVE FROM dsa_dataout+0x0228, WHEN DATA_OUT - -at 0x000001ca : */ 0x18000000,0x00000650, -/* - MOVE FROM dsa_dataout+0x0230, WHEN DATA_OUT - -at 0x000001cc : */ 0x18000000,0x00000658, -/* - MOVE FROM dsa_dataout+0x0238, WHEN DATA_OUT - -at 0x000001ce : */ 0x18000000,0x00000660, -/* - MOVE FROM dsa_dataout+0x0240, WHEN DATA_OUT - -at 0x000001d0 : */ 0x18000000,0x00000668, -/* - MOVE FROM dsa_dataout+0x0248, WHEN DATA_OUT - -at 0x000001d2 : */ 0x18000000,0x00000670, -/* - MOVE FROM dsa_dataout+0x0250, WHEN DATA_OUT - -at 0x000001d4 : */ 0x18000000,0x00000678, -/* - MOVE FROM dsa_dataout+0x0258, WHEN DATA_OUT - -at 0x000001d6 : */ 0x18000000,0x00000680, -/* - MOVE FROM dsa_dataout+0x0260, WHEN DATA_OUT - -at 0x000001d8 : */ 0x18000000,0x00000688, -/* - MOVE FROM dsa_dataout+0x0268, WHEN DATA_OUT - -at 0x000001da : */ 0x18000000,0x00000690, -/* - MOVE FROM dsa_dataout+0x0270, WHEN DATA_OUT - -at 0x000001dc : */ 0x18000000,0x00000698, -/* - MOVE FROM dsa_dataout+0x0278, WHEN DATA_OUT - -at 0x000001de : */ 0x18000000,0x000006a0, -/* - MOVE FROM dsa_dataout+0x0280, WHEN DATA_OUT - -at 0x000001e0 : */ 0x18000000,0x000006a8, -/* - MOVE FROM dsa_dataout+0x0288, WHEN DATA_OUT - -at 0x000001e2 : */ 0x18000000,0x000006b0, -/* - MOVE FROM dsa_dataout+0x0290, WHEN DATA_OUT - -at 0x000001e4 : */ 0x18000000,0x000006b8, -/* - MOVE FROM dsa_dataout+0x0298, WHEN DATA_OUT - -at 0x000001e6 : */ 0x18000000,0x000006c0, -/* - MOVE FROM dsa_dataout+0x02a0, WHEN DATA_OUT - -at 0x000001e8 : */ 0x18000000,0x000006c8, -/* - MOVE FROM dsa_dataout+0x02a8, WHEN DATA_OUT - -at 0x000001ea : */ 0x18000000,0x000006d0, -/* - MOVE FROM dsa_dataout+0x02b0, WHEN DATA_OUT - -at 0x000001ec : */ 0x18000000,0x000006d8, -/* - MOVE FROM dsa_dataout+0x02b8, WHEN DATA_OUT - -at 0x000001ee : */ 0x18000000,0x000006e0, -/* - MOVE FROM dsa_dataout+0x02c0, WHEN DATA_OUT - -at 0x000001f0 : */ 0x18000000,0x000006e8, -/* - MOVE FROM dsa_dataout+0x02c8, WHEN DATA_OUT - -at 0x000001f2 : */ 0x18000000,0x000006f0, -/* - MOVE FROM dsa_dataout+0x02d0, WHEN DATA_OUT - -at 0x000001f4 : */ 0x18000000,0x000006f8, -/* - MOVE FROM dsa_dataout+0x02d8, WHEN DATA_OUT - -at 0x000001f6 : */ 0x18000000,0x00000700, -/* - MOVE FROM dsa_dataout+0x02e0, WHEN DATA_OUT - -at 0x000001f8 : */ 0x18000000,0x00000708, -/* - MOVE FROM dsa_dataout+0x02e8, WHEN DATA_OUT - -at 0x000001fa : */ 0x18000000,0x00000710, -/* - MOVE FROM dsa_dataout+0x02f0, WHEN DATA_OUT - -at 0x000001fc : */ 0x18000000,0x00000718, -/* - MOVE FROM dsa_dataout+0x02f8, WHEN DATA_OUT - -at 0x000001fe : */ 0x18000000,0x00000720, -/* - MOVE FROM dsa_dataout+0x0300, WHEN DATA_OUT - -at 0x00000200 : */ 0x18000000,0x00000728, -/* - MOVE FROM dsa_dataout+0x0308, WHEN DATA_OUT - -at 0x00000202 : */ 0x18000000,0x00000730, -/* - MOVE FROM dsa_dataout+0x0310, WHEN DATA_OUT - -at 0x00000204 : */ 0x18000000,0x00000738, -/* - MOVE FROM dsa_dataout+0x0318, WHEN DATA_OUT - -at 0x00000206 : */ 0x18000000,0x00000740, -/* - MOVE FROM dsa_dataout+0x0320, WHEN DATA_OUT - -at 0x00000208 : */ 0x18000000,0x00000748, -/* - MOVE FROM dsa_dataout+0x0328, WHEN DATA_OUT - -at 0x0000020a : */ 0x18000000,0x00000750, -/* - MOVE FROM dsa_dataout+0x0330, WHEN DATA_OUT - -at 0x0000020c : */ 0x18000000,0x00000758, -/* - MOVE FROM dsa_dataout+0x0338, WHEN DATA_OUT - -at 0x0000020e : */ 0x18000000,0x00000760, -/* - MOVE FROM dsa_dataout+0x0340, WHEN DATA_OUT - -at 0x00000210 : */ 0x18000000,0x00000768, -/* - MOVE FROM dsa_dataout+0x0348, WHEN DATA_OUT - -at 0x00000212 : */ 0x18000000,0x00000770, -/* - MOVE FROM dsa_dataout+0x0350, WHEN DATA_OUT - -at 0x00000214 : */ 0x18000000,0x00000778, -/* - MOVE FROM dsa_dataout+0x0358, WHEN DATA_OUT - -at 0x00000216 : */ 0x18000000,0x00000780, -/* - MOVE FROM dsa_dataout+0x0360, WHEN DATA_OUT - -at 0x00000218 : */ 0x18000000,0x00000788, -/* - MOVE FROM dsa_dataout+0x0368, WHEN DATA_OUT - -at 0x0000021a : */ 0x18000000,0x00000790, -/* - MOVE FROM dsa_dataout+0x0370, WHEN DATA_OUT - -at 0x0000021c : */ 0x18000000,0x00000798, -/* - MOVE FROM dsa_dataout+0x0378, WHEN DATA_OUT - -at 0x0000021e : */ 0x18000000,0x000007a0, -/* - MOVE FROM dsa_dataout+0x0380, WHEN DATA_OUT - -at 0x00000220 : */ 0x18000000,0x000007a8, -/* - MOVE FROM dsa_dataout+0x0388, WHEN DATA_OUT - -at 0x00000222 : */ 0x18000000,0x000007b0, -/* - MOVE FROM dsa_dataout+0x0390, WHEN DATA_OUT - -at 0x00000224 : */ 0x18000000,0x000007b8, -/* - MOVE FROM dsa_dataout+0x0398, WHEN DATA_OUT - -at 0x00000226 : */ 0x18000000,0x000007c0, -/* - MOVE FROM dsa_dataout+0x03a0, WHEN DATA_OUT - -at 0x00000228 : */ 0x18000000,0x000007c8, -/* - MOVE FROM dsa_dataout+0x03a8, WHEN DATA_OUT - -at 0x0000022a : */ 0x18000000,0x000007d0, -/* - MOVE FROM dsa_dataout+0x03b0, WHEN DATA_OUT - -at 0x0000022c : */ 0x18000000,0x000007d8, -/* - MOVE FROM dsa_dataout+0x03b8, WHEN DATA_OUT - -at 0x0000022e : */ 0x18000000,0x000007e0, -/* - MOVE FROM dsa_dataout+0x03c0, WHEN DATA_OUT - -at 0x00000230 : */ 0x18000000,0x000007e8, -/* - MOVE FROM dsa_dataout+0x03c8, WHEN DATA_OUT - -at 0x00000232 : */ 0x18000000,0x000007f0, -/* - MOVE FROM dsa_dataout+0x03d0, WHEN DATA_OUT - -at 0x00000234 : */ 0x18000000,0x000007f8, -/* - MOVE FROM dsa_dataout+0x03d8, WHEN DATA_OUT - -at 0x00000236 : */ 0x18000000,0x00000800, -/* - MOVE FROM dsa_dataout+0x03e0, WHEN DATA_OUT - -at 0x00000238 : */ 0x18000000,0x00000808, -/* - MOVE FROM dsa_dataout+0x03e8, WHEN DATA_OUT - -at 0x0000023a : */ 0x18000000,0x00000810, -/* - MOVE FROM dsa_dataout+0x03f0, WHEN DATA_OUT - -at 0x0000023c : */ 0x18000000,0x00000818, -/* - MOVE FROM dsa_dataout+0x03f8, WHEN DATA_OUT - -at 0x0000023e : */ 0x18000000,0x00000820, -/* -ENTRY end_data_trans -end_data_trans: -redo_msgin3: - JUMP get_status, WHEN STATUS - -at 0x00000240 : */ 0x830b0000,0x00000098, -/* - JUMP get_msgin3, WHEN MSG_IN - -at 0x00000242 : */ 0x870b0000,0x00000b78, -/* - INT int_data_bad_phase - -at 0x00000244 : */ 0x98080000,0xab93000b, -/* - -get_msgin1: - MOVE SCRATCH0 | had_msgin TO SCRATCH0 - -at 0x00000246 : */ 0x7a344000,0x00000000, -/* - MOVE 1, msgin_buf, WHEN MSG_IN - -at 0x00000248 : */ 0x0f000001,0x00000000, -/* - JUMP ext_msg1, IF 0x01 ; Extended Message - -at 0x0000024a : */ 0x800c0001,0x00000960, -/* - JUMP ignore_msg1, IF 0x02 ; Save Data Pointers - -at 0x0000024c : */ 0x800c0002,0x00000950, -/* - JUMP ignore_msg1, IF 0x03 ; Save Restore Pointers - -at 0x0000024e : */ 0x800c0003,0x00000950, -/* - JUMP disc1, IF 0x04 ; Disconnect - -at 0x00000250 : */ 0x800c0004,0x000009f0, -/* - INT int_bad_msg1 - -at 0x00000252 : */ 0x98080000,0xab930006, -/* -ignore_msg1: - CLEAR ACK - -at 0x00000254 : */ 0x60000040,0x00000000, -/* - JUMP redo_msgin1 - -at 0x00000256 : */ 0x80080000,0x00000050, -/* -ext_msg1: - MOVE SCRATCH0 | had_extmsg TO SCRATCH0 - -at 0x00000258 : */ 0x7a348000,0x00000000, -/* - CLEAR ACK - -at 0x0000025a : */ 0x60000040,0x00000000, -/* - MOVE 1, msgin_buf + 1, WHEN MSG_IN - -at 0x0000025c : */ 0x0f000001,0x00000001, -/* - JUMP reject_msg1, IF NOT 0x03 ; Only handle SDTR - -at 0x0000025e : */ 0x80040003,0x000009b0, -/* - CLEAR ACK - -at 0x00000260 : */ 0x60000040,0x00000000, -/* - MOVE 1, msgin_buf + 2, WHEN MSG_IN - -at 0x00000262 : */ 0x0f000001,0x00000002, -/* - JUMP reject_msg1, IF NOT 0x01 ; Only handle SDTR - -at 0x00000264 : */ 0x80040001,0x000009b0, -/* - CLEAR ACK - -at 0x00000266 : */ 0x60000040,0x00000000, -/* - MOVE 2, msgin_buf + 3, WHEN MSG_IN - -at 0x00000268 : */ 0x0f000002,0x00000003, -/* - INT int_msg_sdtr1 - -at 0x0000026a : */ 0x98080000,0xab93000c, -/* -reject_msg1: - MOVE SCRATCH1 | did_reject TO SCRATCH1 - -at 0x0000026c : */ 0x7a350100,0x00000000, -/* - SET ATN - -at 0x0000026e : */ 0x58000008,0x00000000, -/* - CLEAR ACK - -at 0x00000270 : */ 0x60000040,0x00000000, -/* - JUMP reject_msg1a, WHEN NOT MSG_IN - -at 0x00000272 : */ 0x87030000,0x000009e0, -/* - MOVE 1, msgin_buf + 7, WHEN MSG_IN - -at 0x00000274 : */ 0x0f000001,0x00000007, -/* - JUMP reject_msg1 - -at 0x00000276 : */ 0x80080000,0x000009b0, -/* -reject_msg1a: - MOVE 1, msg_reject, WHEN MSG_OUT - -at 0x00000278 : */ 0x0e000001,0x00000000, -/* - JUMP redo_msgin1 - -at 0x0000027a : */ 0x80080000,0x00000050, -/* -disc1: - CLEAR ACK - -at 0x0000027c : */ 0x60000040,0x00000000, -/* -ENTRY wait_disc1 -wait_disc1: - WAIT DISCONNECT - -at 0x0000027e : */ 0x48000000,0x00000000, -/* - INT int_disc1 - -at 0x00000280 : */ 0x98080000,0xab930019, -/* -ENTRY resume_msgin1a -resume_msgin1a: - CLEAR ACK - -at 0x00000282 : */ 0x60000040,0x00000000, -/* - JUMP redo_msgin1 - -at 0x00000284 : */ 0x80080000,0x00000050, -/* -ENTRY resume_msgin1b -resume_msgin1b: - SET ATN - -at 0x00000286 : */ 0x58000008,0x00000000, -/* - CLEAR ACK - -at 0x00000288 : */ 0x60000040,0x00000000, -/* - INT int_no_msgout1, WHEN NOT MSG_OUT - -at 0x0000028a : */ 0x9e030000,0xab93000f, -/* - MOVE SCRATCH0 | had_msgout TO SCRATCH0 - -at 0x0000028c : */ 0x7a340200,0x00000000, -/* - MOVE FROM dsa_msgout, when MSG_OUT - -at 0x0000028e : */ 0x1e000000,0x00000008, -/* - JUMP redo_msgin1 - -at 0x00000290 : */ 0x80080000,0x00000050, -/* - -get_msgin2: - MOVE SCRATCH0 | had_msgin TO SCRATCH0 - -at 0x00000292 : */ 0x7a344000,0x00000000, -/* - MOVE 1, msgin_buf, WHEN MSG_IN - -at 0x00000294 : */ 0x0f000001,0x00000000, -/* - JUMP ext_msg2, IF 0x01 ; Extended Message - -at 0x00000296 : */ 0x800c0001,0x00000a90, -/* - JUMP ignore_msg2, IF 0x02 ; Save Data Pointers - -at 0x00000298 : */ 0x800c0002,0x00000a80, -/* - JUMP ignore_msg2, IF 0x03 ; Save Restore Pointers - -at 0x0000029a : */ 0x800c0003,0x00000a80, -/* - JUMP disc2, IF 0x04 ; Disconnect - -at 0x0000029c : */ 0x800c0004,0x00000b20, -/* - INT int_bad_msg2 - -at 0x0000029e : */ 0x98080000,0xab930007, -/* -ignore_msg2: - CLEAR ACK - -at 0x000002a0 : */ 0x60000040,0x00000000, -/* - JUMP redo_msgin2 - -at 0x000002a2 : */ 0x80080000,0x00000070, -/* -ext_msg2: - MOVE SCRATCH0 | had_extmsg TO SCRATCH0 - -at 0x000002a4 : */ 0x7a348000,0x00000000, -/* - CLEAR ACK - -at 0x000002a6 : */ 0x60000040,0x00000000, -/* - MOVE 1, msgin_buf + 1, WHEN MSG_IN - -at 0x000002a8 : */ 0x0f000001,0x00000001, -/* - JUMP reject_msg2, IF NOT 0x03 ; Only handle SDTR - -at 0x000002aa : */ 0x80040003,0x00000ae0, -/* - CLEAR ACK - -at 0x000002ac : */ 0x60000040,0x00000000, -/* - MOVE 1, msgin_buf + 2, WHEN MSG_IN - -at 0x000002ae : */ 0x0f000001,0x00000002, -/* - JUMP reject_msg2, IF NOT 0x01 ; Only handle SDTR - -at 0x000002b0 : */ 0x80040001,0x00000ae0, -/* - CLEAR ACK - -at 0x000002b2 : */ 0x60000040,0x00000000, -/* - MOVE 2, msgin_buf + 3, WHEN MSG_IN - -at 0x000002b4 : */ 0x0f000002,0x00000003, -/* - INT int_msg_sdtr2 - -at 0x000002b6 : */ 0x98080000,0xab93000d, -/* -reject_msg2: - MOVE SCRATCH1 | did_reject TO SCRATCH1 - -at 0x000002b8 : */ 0x7a350100,0x00000000, -/* - SET ATN - -at 0x000002ba : */ 0x58000008,0x00000000, -/* - CLEAR ACK - -at 0x000002bc : */ 0x60000040,0x00000000, -/* - JUMP reject_msg2a, WHEN NOT MSG_IN - -at 0x000002be : */ 0x87030000,0x00000b10, -/* - MOVE 1, msgin_buf + 7, WHEN MSG_IN - -at 0x000002c0 : */ 0x0f000001,0x00000007, -/* - JUMP reject_msg2 - -at 0x000002c2 : */ 0x80080000,0x00000ae0, -/* -reject_msg2a: - MOVE 1, msg_reject, WHEN MSG_OUT - -at 0x000002c4 : */ 0x0e000001,0x00000000, -/* - JUMP redo_msgin2 - -at 0x000002c6 : */ 0x80080000,0x00000070, -/* -disc2: - CLEAR ACK - -at 0x000002c8 : */ 0x60000040,0x00000000, -/* -ENTRY wait_disc2 -wait_disc2: - WAIT DISCONNECT - -at 0x000002ca : */ 0x48000000,0x00000000, -/* - INT int_disc2 - -at 0x000002cc : */ 0x98080000,0xab93001a, -/* -ENTRY resume_msgin2a -resume_msgin2a: - CLEAR ACK - -at 0x000002ce : */ 0x60000040,0x00000000, -/* - JUMP redo_msgin2 - -at 0x000002d0 : */ 0x80080000,0x00000070, -/* -ENTRY resume_msgin2b -resume_msgin2b: - SET ATN - -at 0x000002d2 : */ 0x58000008,0x00000000, -/* - CLEAR ACK - -at 0x000002d4 : */ 0x60000040,0x00000000, -/* - INT int_no_msgout2, WHEN NOT MSG_OUT - -at 0x000002d6 : */ 0x9e030000,0xab930010, -/* - MOVE SCRATCH0 | had_msgout TO SCRATCH0 - -at 0x000002d8 : */ 0x7a340200,0x00000000, -/* - MOVE FROM dsa_msgout, when MSG_OUT - -at 0x000002da : */ 0x1e000000,0x00000008, -/* - JUMP redo_msgin2 - -at 0x000002dc : */ 0x80080000,0x00000070, -/* - -get_msgin3: - MOVE SCRATCH0 | had_msgin TO SCRATCH0 - -at 0x000002de : */ 0x7a344000,0x00000000, -/* - MOVE 1, msgin_buf, WHEN MSG_IN - -at 0x000002e0 : */ 0x0f000001,0x00000000, -/* - JUMP ext_msg3, IF 0x01 ; Extended Message - -at 0x000002e2 : */ 0x800c0001,0x00000bc0, -/* - JUMP ignore_msg3, IF 0x02 ; Save Data Pointers - -at 0x000002e4 : */ 0x800c0002,0x00000bb0, -/* - JUMP ignore_msg3, IF 0x03 ; Save Restore Pointers - -at 0x000002e6 : */ 0x800c0003,0x00000bb0, -/* - JUMP disc3, IF 0x04 ; Disconnect - -at 0x000002e8 : */ 0x800c0004,0x00000c50, -/* - INT int_bad_msg3 - -at 0x000002ea : */ 0x98080000,0xab930008, -/* -ignore_msg3: - CLEAR ACK - -at 0x000002ec : */ 0x60000040,0x00000000, -/* - JUMP redo_msgin3 - -at 0x000002ee : */ 0x80080000,0x00000900, -/* -ext_msg3: - MOVE SCRATCH0 | had_extmsg TO SCRATCH0 - -at 0x000002f0 : */ 0x7a348000,0x00000000, -/* - CLEAR ACK - -at 0x000002f2 : */ 0x60000040,0x00000000, -/* - MOVE 1, msgin_buf + 1, WHEN MSG_IN - -at 0x000002f4 : */ 0x0f000001,0x00000001, -/* - JUMP reject_msg3, IF NOT 0x03 ; Only handle SDTR - -at 0x000002f6 : */ 0x80040003,0x00000c10, -/* - CLEAR ACK - -at 0x000002f8 : */ 0x60000040,0x00000000, -/* - MOVE 1, msgin_buf + 2, WHEN MSG_IN - -at 0x000002fa : */ 0x0f000001,0x00000002, -/* - JUMP reject_msg3, IF NOT 0x01 ; Only handle SDTR - -at 0x000002fc : */ 0x80040001,0x00000c10, -/* - CLEAR ACK - -at 0x000002fe : */ 0x60000040,0x00000000, -/* - MOVE 2, msgin_buf + 3, WHEN MSG_IN - -at 0x00000300 : */ 0x0f000002,0x00000003, -/* - INT int_msg_sdtr3 - -at 0x00000302 : */ 0x98080000,0xab93000e, -/* -reject_msg3: - MOVE SCRATCH1 | did_reject TO SCRATCH1 - -at 0x00000304 : */ 0x7a350100,0x00000000, -/* - SET ATN - -at 0x00000306 : */ 0x58000008,0x00000000, -/* - CLEAR ACK - -at 0x00000308 : */ 0x60000040,0x00000000, -/* - JUMP reject_msg3a, WHEN NOT MSG_IN - -at 0x0000030a : */ 0x87030000,0x00000c40, -/* - MOVE 1, msgin_buf + 7, WHEN MSG_IN - -at 0x0000030c : */ 0x0f000001,0x00000007, -/* - JUMP reject_msg3 - -at 0x0000030e : */ 0x80080000,0x00000c10, -/* -reject_msg3a: - MOVE 1, msg_reject, WHEN MSG_OUT - -at 0x00000310 : */ 0x0e000001,0x00000000, -/* - JUMP redo_msgin3 - -at 0x00000312 : */ 0x80080000,0x00000900, -/* -disc3: - CLEAR ACK - -at 0x00000314 : */ 0x60000040,0x00000000, -/* -ENTRY wait_disc3 -wait_disc3: - WAIT DISCONNECT - -at 0x00000316 : */ 0x48000000,0x00000000, -/* - INT int_disc3 - -at 0x00000318 : */ 0x98080000,0xab93001b, -/* -ENTRY resume_msgin3a -resume_msgin3a: - CLEAR ACK - -at 0x0000031a : */ 0x60000040,0x00000000, -/* - JUMP redo_msgin3 - -at 0x0000031c : */ 0x80080000,0x00000900, -/* -ENTRY resume_msgin3b -resume_msgin3b: - SET ATN - -at 0x0000031e : */ 0x58000008,0x00000000, -/* - CLEAR ACK - -at 0x00000320 : */ 0x60000040,0x00000000, -/* - INT int_no_msgout3, WHEN NOT MSG_OUT - -at 0x00000322 : */ 0x9e030000,0xab930011, -/* - MOVE SCRATCH0 | had_msgout TO SCRATCH0 - -at 0x00000324 : */ 0x7a340200,0x00000000, -/* - MOVE FROM dsa_msgout, when MSG_OUT - -at 0x00000326 : */ 0x1e000000,0x00000008, -/* - JUMP redo_msgin3 - -at 0x00000328 : */ 0x80080000,0x00000900, -/* - -ENTRY resume_rej_ident -resume_rej_ident: - CLEAR ATN - -at 0x0000032a : */ 0x60000008,0x00000000, -/* - MOVE 1, msgin_buf, WHEN MSG_IN - -at 0x0000032c : */ 0x0f000001,0x00000000, -/* - INT int_not_rej, IF NOT 0x07 ; Reject - -at 0x0000032e : */ 0x98040007,0xab93001c, -/* - CLEAR ACK - -at 0x00000330 : */ 0x60000040,0x00000000, -/* - JUMP done_ident - -at 0x00000332 : */ 0x80080000,0x00000048, -/* - -ENTRY reselect -reselect: - ; Disable selection timer - MOVE CTEST7 | 0x10 TO CTEST7 - -at 0x00000334 : */ 0x7a1b1000,0x00000000, -/* - WAIT RESELECT resel_err - -at 0x00000336 : */ 0x50000000,0x00000cf8, -/* - INT int_resel_not_msgin, WHEN NOT MSG_IN - -at 0x00000338 : */ 0x9f030000,0xab930016, -/* - MOVE 1, reselected_identify, WHEN MSG_IN - -at 0x0000033a : */ 0x0f000001,0x00000000, -/* - INT int_reselected - -at 0x0000033c : */ 0x98080000,0xab930017, -/* -resel_err: - MOVE CTEST2 & 0x40 TO SFBR - -at 0x0000033e : */ 0x74164000,0x00000000, -/* - JUMP selected, IF 0x00 - -at 0x00000340 : */ 0x800c0000,0x00000d38, -/* - MOVE SFBR & 0 TO SFBR - -at 0x00000342 : */ 0x7c080000,0x00000000, -/* -ENTRY patch_new_dsa -patch_new_dsa: - MOVE SFBR | 0x11 TO DSA0 - -at 0x00000344 : */ 0x6a101100,0x00000000, -/* - MOVE SFBR | 0x22 TO DSA1 - -at 0x00000346 : */ 0x6a112200,0x00000000, -/* - MOVE SFBR | 0x33 TO DSA2 - -at 0x00000348 : */ 0x6a123300,0x00000000, -/* - MOVE SFBR | 0x44 TO DSA3 - -at 0x0000034a : */ 0x6a134400,0x00000000, -/* - JUMP do_select - -at 0x0000034c : */ 0x80080000,0x00000000, -/* - -selected: - INT int_selected - -at 0x0000034e : */ 0x98080000,0xab930018, -/* - -ENTRY test1 -test1: - MOVE MEMORY 4, test1_src, test1_dst - -at 0x00000350 : */ 0xc0000004,0x00000000,0x00000000, -/* - INT int_test1 - -at 0x00000353 : */ 0x98080000,0xab93001d, -}; - -#define A_did_reject 0x00000001 -static u32 A_did_reject_used[] __attribute((unused)) = { - 0x0000026c, - 0x000002b8, - 0x00000304, -}; - -#define A_dsa_cmnd 0x00000010 -static u32 A_dsa_cmnd_used[] __attribute((unused)) = { - 0x0000001b, -}; - -#define A_dsa_datain 0x00000028 -static u32 A_dsa_datain_used[] __attribute((unused)) = { - 0x0000003b, - 0x0000003d, - 0x0000003f, - 0x00000041, - 0x00000043, - 0x00000045, - 0x00000047, - 0x00000049, - 0x0000004b, - 0x0000004d, - 0x0000004f, - 0x00000051, - 0x00000053, - 0x00000055, - 0x00000057, - 0x00000059, - 0x0000005b, - 0x0000005d, - 0x0000005f, - 0x00000061, - 0x00000063, - 0x00000065, - 0x00000067, - 0x00000069, - 0x0000006b, - 0x0000006d, - 0x0000006f, - 0x00000071, - 0x00000073, - 0x00000075, - 0x00000077, - 0x00000079, - 0x0000007b, - 0x0000007d, - 0x0000007f, - 0x00000081, - 0x00000083, - 0x00000085, - 0x00000087, - 0x00000089, - 0x0000008b, - 0x0000008d, - 0x0000008f, - 0x00000091, - 0x00000093, - 0x00000095, - 0x00000097, - 0x00000099, - 0x0000009b, - 0x0000009d, - 0x0000009f, - 0x000000a1, - 0x000000a3, - 0x000000a5, - 0x000000a7, - 0x000000a9, - 0x000000ab, - 0x000000ad, - 0x000000af, - 0x000000b1, - 0x000000b3, - 0x000000b5, - 0x000000b7, - 0x000000b9, - 0x000000bb, - 0x000000bd, - 0x000000bf, - 0x000000c1, - 0x000000c3, - 0x000000c5, - 0x000000c7, - 0x000000c9, - 0x000000cb, - 0x000000cd, - 0x000000cf, - 0x000000d1, - 0x000000d3, - 0x000000d5, - 0x000000d7, - 0x000000d9, - 0x000000db, - 0x000000dd, - 0x000000df, - 0x000000e1, - 0x000000e3, - 0x000000e5, - 0x000000e7, - 0x000000e9, - 0x000000eb, - 0x000000ed, - 0x000000ef, - 0x000000f1, - 0x000000f3, - 0x000000f5, - 0x000000f7, - 0x000000f9, - 0x000000fb, - 0x000000fd, - 0x000000ff, - 0x00000101, - 0x00000103, - 0x00000105, - 0x00000107, - 0x00000109, - 0x0000010b, - 0x0000010d, - 0x0000010f, - 0x00000111, - 0x00000113, - 0x00000115, - 0x00000117, - 0x00000119, - 0x0000011b, - 0x0000011d, - 0x0000011f, - 0x00000121, - 0x00000123, - 0x00000125, - 0x00000127, - 0x00000129, - 0x0000012b, - 0x0000012d, - 0x0000012f, - 0x00000131, - 0x00000133, - 0x00000135, - 0x00000137, - 0x00000139, -}; - -#define A_dsa_dataout 0x00000428 -static u32 A_dsa_dataout_used[] __attribute((unused)) = { - 0x00000141, - 0x00000143, - 0x00000145, - 0x00000147, - 0x00000149, - 0x0000014b, - 0x0000014d, - 0x0000014f, - 0x00000151, - 0x00000153, - 0x00000155, - 0x00000157, - 0x00000159, - 0x0000015b, - 0x0000015d, - 0x0000015f, - 0x00000161, - 0x00000163, - 0x00000165, - 0x00000167, - 0x00000169, - 0x0000016b, - 0x0000016d, - 0x0000016f, - 0x00000171, - 0x00000173, - 0x00000175, - 0x00000177, - 0x00000179, - 0x0000017b, - 0x0000017d, - 0x0000017f, - 0x00000181, - 0x00000183, - 0x00000185, - 0x00000187, - 0x00000189, - 0x0000018b, - 0x0000018d, - 0x0000018f, - 0x00000191, - 0x00000193, - 0x00000195, - 0x00000197, - 0x00000199, - 0x0000019b, - 0x0000019d, - 0x0000019f, - 0x000001a1, - 0x000001a3, - 0x000001a5, - 0x000001a7, - 0x000001a9, - 0x000001ab, - 0x000001ad, - 0x000001af, - 0x000001b1, - 0x000001b3, - 0x000001b5, - 0x000001b7, - 0x000001b9, - 0x000001bb, - 0x000001bd, - 0x000001bf, - 0x000001c1, - 0x000001c3, - 0x000001c5, - 0x000001c7, - 0x000001c9, - 0x000001cb, - 0x000001cd, - 0x000001cf, - 0x000001d1, - 0x000001d3, - 0x000001d5, - 0x000001d7, - 0x000001d9, - 0x000001db, - 0x000001dd, - 0x000001df, - 0x000001e1, - 0x000001e3, - 0x000001e5, - 0x000001e7, - 0x000001e9, - 0x000001eb, - 0x000001ed, - 0x000001ef, - 0x000001f1, - 0x000001f3, - 0x000001f5, - 0x000001f7, - 0x000001f9, - 0x000001fb, - 0x000001fd, - 0x000001ff, - 0x00000201, - 0x00000203, - 0x00000205, - 0x00000207, - 0x00000209, - 0x0000020b, - 0x0000020d, - 0x0000020f, - 0x00000211, - 0x00000213, - 0x00000215, - 0x00000217, - 0x00000219, - 0x0000021b, - 0x0000021d, - 0x0000021f, - 0x00000221, - 0x00000223, - 0x00000225, - 0x00000227, - 0x00000229, - 0x0000022b, - 0x0000022d, - 0x0000022f, - 0x00000231, - 0x00000233, - 0x00000235, - 0x00000237, - 0x00000239, - 0x0000023b, - 0x0000023d, - 0x0000023f, -}; - -#define A_dsa_msgin 0x00000020 -static u32 A_dsa_msgin_used[] __attribute((unused)) = { - 0x0000002d, -}; - -#define A_dsa_msgout 0x00000008 -static u32 A_dsa_msgout_used[] __attribute((unused)) = { - 0x00000011, - 0x0000028f, - 0x000002db, - 0x00000327, -}; - -#define A_dsa_select 0x00000000 -static u32 A_dsa_select_used[] __attribute((unused)) = { - 0x00000004, -}; - -#define A_dsa_size 0x00000828 -static u32 A_dsa_size_used[] __attribute((unused)) = { -}; - -#define A_dsa_status 0x00000018 -static u32 A_dsa_status_used[] __attribute((unused)) = { - 0x00000029, -}; - -#define A_had_cmdout 0x00000004 -static u32 A_had_cmdout_used[] __attribute((unused)) = { - 0x00000018, -}; - -#define A_had_datain 0x00000008 -static u32 A_had_datain_used[] __attribute((unused)) = { - 0x00000036, -}; - -#define A_had_dataout 0x00000010 -static u32 A_had_dataout_used[] __attribute((unused)) = { - 0x0000013c, -}; - -#define A_had_extmsg 0x00000080 -static u32 A_had_extmsg_used[] __attribute((unused)) = { - 0x00000258, - 0x000002a4, - 0x000002f0, -}; - -#define A_had_msgin 0x00000040 -static u32 A_had_msgin_used[] __attribute((unused)) = { - 0x00000246, - 0x00000292, - 0x000002de, -}; - -#define A_had_msgout 0x00000002 -static u32 A_had_msgout_used[] __attribute((unused)) = { - 0x0000000e, - 0x0000028c, - 0x000002d8, - 0x00000324, -}; - -#define A_had_select 0x00000001 -static u32 A_had_select_used[] __attribute((unused)) = { - 0x0000000a, -}; - -#define A_had_status 0x00000020 -static u32 A_had_status_used[] __attribute((unused)) = { -}; - -#define A_int_bad_msg1 0xab930006 -static u32 A_int_bad_msg1_used[] __attribute((unused)) = { - 0x00000253, -}; - -#define A_int_bad_msg2 0xab930007 -static u32 A_int_bad_msg2_used[] __attribute((unused)) = { - 0x0000029f, -}; - -#define A_int_bad_msg3 0xab930008 -static u32 A_int_bad_msg3_used[] __attribute((unused)) = { - 0x000002eb, -}; - -#define A_int_cmd_bad_phase 0xab930009 -static u32 A_int_cmd_bad_phase_used[] __attribute((unused)) = { - 0x00000025, -}; - -#define A_int_cmd_complete 0xab93000a -static u32 A_int_cmd_complete_used[] __attribute((unused)) = { - 0x00000035, -}; - -#define A_int_data_bad_phase 0xab93000b -static u32 A_int_data_bad_phase_used[] __attribute((unused)) = { - 0x00000245, -}; - -#define A_int_disc1 0xab930019 -static u32 A_int_disc1_used[] __attribute((unused)) = { - 0x00000281, -}; - -#define A_int_disc2 0xab93001a -static u32 A_int_disc2_used[] __attribute((unused)) = { - 0x000002cd, -}; - -#define A_int_disc3 0xab93001b -static u32 A_int_disc3_used[] __attribute((unused)) = { - 0x00000319, -}; - -#define A_int_msg_sdtr1 0xab93000c -static u32 A_int_msg_sdtr1_used[] __attribute((unused)) = { - 0x0000026b, -}; - -#define A_int_msg_sdtr2 0xab93000d -static u32 A_int_msg_sdtr2_used[] __attribute((unused)) = { - 0x000002b7, -}; - -#define A_int_msg_sdtr3 0xab93000e -static u32 A_int_msg_sdtr3_used[] __attribute((unused)) = { - 0x00000303, -}; - -#define A_int_no_msgout1 0xab93000f -static u32 A_int_no_msgout1_used[] __attribute((unused)) = { - 0x0000028b, -}; - -#define A_int_no_msgout2 0xab930010 -static u32 A_int_no_msgout2_used[] __attribute((unused)) = { - 0x000002d7, -}; - -#define A_int_no_msgout3 0xab930011 -static u32 A_int_no_msgout3_used[] __attribute((unused)) = { - 0x00000323, -}; - -#define A_int_not_cmd_complete 0xab930012 -static u32 A_int_not_cmd_complete_used[] __attribute((unused)) = { - 0x0000002f, -}; - -#define A_int_not_rej 0xab93001c -static u32 A_int_not_rej_used[] __attribute((unused)) = { - 0x0000032f, -}; - -#define A_int_resel_not_msgin 0xab930016 -static u32 A_int_resel_not_msgin_used[] __attribute((unused)) = { - 0x00000339, -}; - -#define A_int_reselected 0xab930017 -static u32 A_int_reselected_used[] __attribute((unused)) = { - 0x0000033d, -}; - -#define A_int_sel_no_ident 0xab930013 -static u32 A_int_sel_no_ident_used[] __attribute((unused)) = { - 0x0000000d, -}; - -#define A_int_sel_not_cmd 0xab930014 -static u32 A_int_sel_not_cmd_used[] __attribute((unused)) = { - 0x00000017, -}; - -#define A_int_selected 0xab930018 -static u32 A_int_selected_used[] __attribute((unused)) = { - 0x0000034f, -}; - -#define A_int_status_not_msgin 0xab930015 -static u32 A_int_status_not_msgin_used[] __attribute((unused)) = { - 0x0000002b, -}; - -#define A_int_test1 0xab93001d -static u32 A_int_test1_used[] __attribute((unused)) = { - 0x00000354, -}; - -#define A_msg_reject 0x00000000 -static u32 A_msg_reject_used[] __attribute((unused)) = { - 0x00000279, - 0x000002c5, - 0x00000311, -}; - -#define A_msgin_buf 0x00000000 -static u32 A_msgin_buf_used[] __attribute((unused)) = { - 0x00000249, - 0x0000025d, - 0x00000263, - 0x00000269, - 0x00000275, - 0x00000295, - 0x000002a9, - 0x000002af, - 0x000002b5, - 0x000002c1, - 0x000002e1, - 0x000002f5, - 0x000002fb, - 0x00000301, - 0x0000030d, - 0x0000032d, -}; - -#define A_reselected_identify 0x00000000 -static u32 A_reselected_identify_used[] __attribute((unused)) = { - 0x0000033b, -}; - -#define A_test1_dst 0x00000000 -static u32 A_test1_dst_used[] __attribute((unused)) = { - 0x00000352, -}; - -#define A_test1_src 0x00000000 -static u32 A_test1_src_used[] __attribute((unused)) = { - 0x00000351, -}; - -#define Ent_do_select 0x00000000 -#define Ent_done_ident 0x00000048 -#define Ent_end_data_trans 0x00000900 -#define Ent_patch_input_data 0x000000e0 -#define Ent_patch_new_dsa 0x00000d10 -#define Ent_patch_output_data 0x000004f8 -#define Ent_reselect 0x00000cd0 -#define Ent_resume_cmd 0x00000060 -#define Ent_resume_msgin1a 0x00000a08 -#define Ent_resume_msgin1b 0x00000a18 -#define Ent_resume_msgin2a 0x00000b38 -#define Ent_resume_msgin2b 0x00000b48 -#define Ent_resume_msgin3a 0x00000c68 -#define Ent_resume_msgin3b 0x00000c78 -#define Ent_resume_pmm 0x00000070 -#define Ent_resume_rej_ident 0x00000ca8 -#define Ent_test1 0x00000d40 -#define Ent_wait_disc1 0x000009f8 -#define Ent_wait_disc2 0x00000b28 -#define Ent_wait_disc3 0x00000c58 -#define Ent_wait_disc_complete 0x000000c8 -static u32 LABELPATCHES[] __attribute((unused)) = { - 0x00000005, - 0x00000007, - 0x00000013, - 0x00000015, - 0x0000001d, - 0x0000001f, - 0x00000021, - 0x00000023, - 0x0000013b, - 0x00000241, - 0x00000243, - 0x0000024b, - 0x0000024d, - 0x0000024f, - 0x00000251, - 0x00000257, - 0x0000025f, - 0x00000265, - 0x00000273, - 0x00000277, - 0x0000027b, - 0x00000285, - 0x00000291, - 0x00000297, - 0x00000299, - 0x0000029b, - 0x0000029d, - 0x000002a3, - 0x000002ab, - 0x000002b1, - 0x000002bf, - 0x000002c3, - 0x000002c7, - 0x000002d1, - 0x000002dd, - 0x000002e3, - 0x000002e5, - 0x000002e7, - 0x000002e9, - 0x000002ef, - 0x000002f7, - 0x000002fd, - 0x0000030b, - 0x0000030f, - 0x00000313, - 0x0000031d, - 0x00000329, - 0x00000333, - 0x00000337, - 0x00000341, - 0x0000034d, -}; - -static struct { - u32 offset; - void *address; -} EXTERNAL_PATCHES[] __attribute((unused)) = { -}; - -static u32 INSTRUCTIONS __attribute((unused)) = 426; -static u32 PATCHES __attribute((unused)) = 51; -static u32 EXTERNAL_PATCHES_LEN __attribute((unused)) = 0; diff -Nru a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c --- a/drivers/scsi/sr_ioctl.c Sun Feb 9 21:13:33 2003 +++ b/drivers/scsi/sr_ioctl.c Sun Feb 9 21:13:33 2003 @@ -80,34 +80,20 @@ struct scsi_device *SDev; struct request *req; int result, err = 0, retries = 0; - char *bounce_buffer; SDev = cd->device; SRpnt = scsi_allocate_request(SDev); if (!SRpnt) { - printk("Unable to allocate SCSI request in sr_do_ioctl"); + printk(KERN_ERR "Unable to allocate SCSI request in sr_do_ioctl"); err = -ENOMEM; goto out; } SRpnt->sr_data_direction = cgc->data_direction; - /* use ISA DMA buffer if necessary */ - SRpnt->sr_request->buffer = cgc->buffer; - if (cgc->buffer && SRpnt->sr_host->unchecked_isa_dma && - (virt_to_phys(cgc->buffer) + cgc->buflen - 1 > ISA_DMA_THRESHOLD)) { - bounce_buffer = (char *) kmalloc(cgc->buflen, GFP_DMA); - if (bounce_buffer == NULL) { - printk("SCSI DMA pool exhausted."); - err = -ENOMEM; - goto out; - } - memcpy(bounce_buffer, cgc->buffer, cgc->buflen); - cgc->buffer = bounce_buffer; - } retry: if (!scsi_block_when_processing_errors(SDev)) { err = -ENODEV; - goto out; + goto out_free; } scsi_wait_req(SRpnt, cgc->cmd, cgc->buffer, cgc->buflen, @@ -179,6 +165,7 @@ memcpy(cgc->sense, SRpnt->sr_sense_buffer, sizeof(*cgc->sense)); /* Wake up a process waiting for device */ + out_free: scsi_release_request(SRpnt); SRpnt = NULL; out: @@ -275,11 +262,15 @@ return 0; } +/* primitive to determine whether we need to have GFP_DMA set based on + * the status of the unchecked_isa_dma flag in the host structure */ +#define SR_GFP_DMA(cd) (((cd)->device->host->unchecked_isa_dma) ? GFP_DMA : 0) + int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) { Scsi_CD *cd = cdi->handle; struct cdrom_generic_command cgc; - char buffer[32]; + char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd)); int result; memset(&cgc, 0, sizeof(struct cdrom_generic_command)); @@ -296,6 +287,7 @@ memcpy(mcn->medium_catalog_number, buffer + 9, 13); mcn->medium_catalog_number[13] = 0; + kfree(buffer); return result; } @@ -337,7 +329,7 @@ Scsi_CD *cd = cdi->handle; struct cdrom_generic_command cgc; int result; - unsigned char buffer[32]; + unsigned char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd)); memset(&cgc, 0, sizeof(struct cdrom_generic_command)); cgc.timeout = IOCTL_TIMEOUT; @@ -408,7 +400,7 @@ } default: - return -EINVAL; + result = -EINVAL; } #if 0 @@ -416,6 +408,7 @@ printk("DEBUG: sr_audio: result for ioctl %x: %x\n", cmd, result); #endif + kfree(buffer); return result; } @@ -527,7 +520,7 @@ if (!xa_test) return 0; - raw_sector = (unsigned char *) kmalloc(2048, GFP_DMA | GFP_KERNEL); + raw_sector = (unsigned char *) kmalloc(2048, GFP_KERNEL | SR_GFP_DMA(cd)); if (!raw_sector) return -ENOMEM; if (0 == sr_read_sector(cd, cd->ms_offset + 16, diff -Nru a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c --- a/drivers/scsi/sym53c8xx.c Sun Feb 9 21:13:34 2003 +++ b/drivers/scsi/sym53c8xx.c Sun Feb 9 21:13:34 2003 @@ -4735,8 +4735,8 @@ static void PRINT_ADDR(Scsi_Cmnd *cmd) { - struct host_data *host_data = (struct host_data *) cmd->host->hostdata; - PRINT_LUN(host_data->ncb, cmd->target, cmd->lun); + struct host_data *host_data = (struct host_data *) cmd->device->host->hostdata; + PRINT_LUN(host_data->ncb, cmd->device->id, cmd->device->lun); } /*========================================================== @@ -6505,8 +6505,8 @@ static int ncr_queue_command (ncb_p np, Scsi_Cmnd *cmd) { /* Scsi_Device *device = cmd->device; */ - tcb_p tp = &np->target[cmd->target]; - lcb_p lp = ncr_lp(np, tp, cmd->lun); + tcb_p tp = &np->target[cmd->device->id]; + lcb_p lp = ncr_lp(np, tp, cmd->device->lun); ccb_p cp; u_char idmsg, *msgptr; @@ -6520,9 +6520,9 @@ ** **--------------------------------------------- */ - if ((cmd->target == np->myaddr ) || - (cmd->target >= MAX_TARGET) || - (cmd->lun >= MAX_LUN )) { + if ((cmd->device->id == np->myaddr ) || + (cmd->device->id >= MAX_TARGET) || + (cmd->device->lun >= MAX_LUN )) { return(DID_BAD_TARGET); } @@ -6562,7 +6562,7 @@ np->settle_time = tlimit; } - if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->target, cmd->lun))) { + if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->device->id, cmd->device->lun))) { insert_into_waiting_list(np, cmd); return(DID_OK); } @@ -13592,7 +13592,7 @@ int sym53c8xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) { - ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb; + ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb; unsigned long flags; int sts; @@ -13661,9 +13661,9 @@ if (DEBUG_FLAGS & DEBUG_TINY) printk ("]\n"); if (done_list) { - NCR_LOCK_SCSI_DONE(done_list->host, flags); + NCR_LOCK_SCSI_DONE(done_list->device->host, flags); ncr_flush_done_cmds(done_list); - NCR_UNLOCK_SCSI_DONE(done_list->host, flags); + NCR_UNLOCK_SCSI_DONE(done_list->device->host, flags); } } @@ -13684,9 +13684,9 @@ NCR_UNLOCK_NCB(np, flags); if (done_list) { - NCR_LOCK_SCSI_DONE(done_list->host, flags); + NCR_LOCK_SCSI_DONE(done_list->device->host, flags); ncr_flush_done_cmds(done_list); - NCR_UNLOCK_SCSI_DONE(done_list->host, flags); + NCR_UNLOCK_SCSI_DONE(done_list->device->host, flags); } } @@ -13700,7 +13700,7 @@ int sym53c8xx_reset(Scsi_Cmnd *cmd) #endif { - ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb; + ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb; int sts; unsigned long flags; Scsi_Cmnd *done_list; @@ -13762,7 +13762,7 @@ int sym53c8xx_abort(Scsi_Cmnd *cmd) { - ncb_p np = ((struct host_data *) cmd->host->hostdata)->ncb; + ncb_p np = ((struct host_data *) cmd->device->host->hostdata)->ncb; int sts; unsigned long flags; Scsi_Cmnd *done_list; diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c --- a/drivers/scsi/sym53c8xx_2/sym_glue.c Sun Feb 9 21:13:37 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c Sun Feb 9 21:13:37 2003 @@ -330,7 +330,7 @@ #define SYM_UCMD_PTR(cmd) ((ucmd_p)(&(cmd)->SCp)) #define SYM_SCMD_PTR(ucmd) sym_que_entry(ucmd, Scsi_Cmnd, SCp) -#define SYM_SOFTC_PTR(cmd) (((struct host_data *)cmd->host->hostdata)->ncb) +#define SYM_SOFTC_PTR(cmd) (((struct host_data *)cmd->device->host->hostdata)->ncb) /* * Deal with DMA mapping/unmapping. @@ -467,7 +467,7 @@ Scsi_Cmnd *cmd = cp->cam_ccb; if (cmd) printf("%s:%d:%d:", sym_name(SYM_SOFTC_PTR(cmd)), - cmd->target,cmd->lun); + cmd->device->id,cmd->device->lun); } /* @@ -603,13 +603,13 @@ return; sync_scsi_data(np, cmd); - retv = __sym_sniff_inquiry(np, cmd->target, cmd->lun, + retv = __sym_sniff_inquiry(np, cmd->device->id, cmd->device->lun, (u_char *) cmd->request_buffer, cmd->request_bufflen - resid); if (retv < 0) return; else if (retv) - sym_update_trans_settings(np, &np->target[cmd->target]); + sym_update_trans_settings(np, &np->target[cmd->device->id]); } /* @@ -687,9 +687,9 @@ * Minimal checkings, so that we will not * go outside our tables. */ - if (ccb->target == np->myaddr || - ccb->target >= SYM_CONF_MAX_TARGET || - ccb->lun >= SYM_CONF_MAX_LUN) { + if (ccb->device->id == np->myaddr || + ccb->device->id >= SYM_CONF_MAX_TARGET || + ccb->device->lun >= SYM_CONF_MAX_LUN) { sym_xpt_done2(np, ccb, CAM_DEV_NOT_THERE); return 0; } @@ -697,7 +697,7 @@ /* * Retreive the target descriptor. */ - tp = &np->target[ccb->target]; + tp = &np->target[ccb->device->id]; /* * Complete the 1st INQUIRY command with error @@ -714,7 +714,7 @@ if (ccb->cmnd[0] == 0x12 || ccb->cmnd[0] == 0x0) { if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) || ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && - ccb->lun != 0)) { + ccb->device->lun != 0)) { tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED; sym_xpt_done2(np, ccb, CAM_DEV_NOT_THERE); return 0; @@ -724,13 +724,13 @@ /* * Select tagged/untagged. */ - lp = sym_lp(np, tp, ccb->lun); + lp = sym_lp(np, tp, ccb->device->lun); order = (lp && lp->s.reqtags) ? M_SIMPLE_TAG : 0; /* * Queue the SCSI IO. */ - cp = sym_get_ccb(np, ccb->target, ccb->lun, order); + cp = sym_get_ccb(np, ccb->device->id, ccb->device->lun, order); if (!cp) return 1; /* Means resource shortage */ (void) sym_queue_scsiio(np, ccb, cp); @@ -1113,7 +1113,7 @@ struct sym_eh_wait eh, *ep = &eh; char devname[20]; - sprintf(devname, "%s:%d:%d", sym_name(np), cmd->target, cmd->lun); + sprintf(devname, "%s:%d:%d", sym_name(np), cmd->device->id, cmd->device->lun); printf_warning("%s: %s operation started.\n", devname, opname); @@ -1167,7 +1167,7 @@ sts = sym_abort_scsiio(np, cmd, 1); break; case SYM_EH_DEVICE_RESET: - sts = sym_reset_scsi_target(np, cmd->target); + sts = sym_reset_scsi_target(np, cmd->device->id); break; case SYM_EH_BUS_RESET: sym_reset_scsi_bus(np, 1); @@ -1843,7 +1843,7 @@ pci_unmap_mem(np->s.ram_va, np->ram_ws); #endif /* - * Free O/S independant resources. + * Free O/S independent resources. */ sym_hcb_free(np); @@ -2043,7 +2043,7 @@ } /* - * Perform O/S independant stuff. + * Perform O/S independent stuff. */ if (sym_hcb_attach(np, fw, nvram)) goto attach_failed; diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h --- a/drivers/scsi/sym53c8xx_2/sym_glue.h Sun Feb 9 21:13:37 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.h Sun Feb 9 21:13:37 2003 @@ -188,7 +188,7 @@ typedef struct sym_shcb *shcb_p; /* - * Define a reference to the O/S dependant IO request. + * Define a reference to the O/S dependent IO request. */ typedef Scsi_Cmnd *cam_ccb_p; /* Generic */ typedef Scsi_Cmnd *cam_scsiio_p;/* SCSI I/O */ diff -Nru a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c --- a/drivers/scsi/tmscsim.c Sun Feb 9 21:13:37 2003 +++ b/drivers/scsi/tmscsim.c Sun Feb 9 21:13:37 2003 @@ -1184,7 +1184,7 @@ if (!pSRB) return; pcmd = dc390_Query_get ( pACB ); if (!pcmd) { dc390_Free_insert (pACB, pSRB); return; }; /* should not happen */ - pDCB = dc390_findDCB (pACB, pcmd->target, pcmd->lun); + pDCB = dc390_findDCB (pACB, pcmd->device->id, pcmd->device->lun); if (!pDCB) { dc390_Free_insert (pACB, pSRB); @@ -1223,12 +1223,12 @@ PDCB pDCB; PSRB pSRB; DC390_AFLAGS - PACB pACB = (PACB) cmd->host->hostdata; + PACB pACB = (PACB) cmd->device->host->hostdata; DEBUG0(/* if(pACB->scan_devices) */ \ printk(KERN_INFO "DC390: Queue Cmd=%02x,Tgt=%d,LUN=%d (pid=%li)\n",\ - cmd->cmnd[0],cmd->target,cmd->lun,cmd->pid);) + cmd->cmnd[0],cmd->device->id,cmd->device->lun,cmd->pid);) DC390_LOCK_ACB; @@ -1245,11 +1245,11 @@ else if( (pACB->scan_devices) && (cmd->cmnd[0] == READ_6) ) pACB->scan_devices = 0; - if ( ( cmd->target >= pACB->pScsiHost->max_id ) || - (cmd->lun >= pACB->pScsiHost->max_lun) ) + if ( ( cmd->device->id >= pACB->pScsiHost->max_id ) || + (cmd->device->lun >= pACB->pScsiHost->max_lun) ) { /* printk ("DC390: Ignore target %d lun %d\n", - cmd->target, cmd->lun); */ + cmd->device->id, cmd->device->lun); */ DC390_UNLOCK_ACB; //return (1); done (cmd); @@ -1257,15 +1257,15 @@ } if( (pACB->scan_devices || cmd->cmnd[0] == TEST_UNIT_READY || cmd->cmnd[0] == INQUIRY) && - !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) ) + !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) ) { pACB->scan_devices = 1; - dc390_initDCB( pACB, &pDCB, cmd->target, cmd->lun ); + dc390_initDCB( pACB, &pDCB, cmd->device->id, cmd->device->lun ); if (!pDCB) { printk (KERN_ERR "DC390: kmalloc for DCB failed, target %02x lun %02x\n", - cmd->target, cmd->lun); + cmd->device->id, cmd->device->lun); DC390_UNLOCK_ACB; printk ("DC390: No DCB in queue_command!\n"); #ifdef USE_NEW_EH @@ -1277,10 +1277,10 @@ }; } - else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) ) + else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) ) { printk(KERN_INFO "DC390: Ignore target %02x lun %02x\n", - cmd->target, cmd->lun); + cmd->device->id, cmd->device->lun); DC390_UNLOCK_ACB; //return (1); done (cmd); @@ -1288,11 +1288,11 @@ } else { - pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun); + pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun); if (!pDCB) { /* should never happen */ printk (KERN_ERR "DC390: no DCB failed, target %02x lun %02x\n", - cmd->target, cmd->lun); + cmd->device->id, cmd->device->lun); DC390_UNLOCK_ACB; printk ("DC390: No DCB in queuecommand (2)!\n"); #ifdef USE_NEW_EH @@ -1547,12 +1547,12 @@ int status; //ULONG sbac; DC390_AFLAGS - PACB pACB = (PACB) cmd->host->hostdata; + PACB pACB = (PACB) cmd->device->host->hostdata; DC390_LOCK_ACB; printk ("DC390: Abort command (pid %li, Device %02i-%02i)\n", - cmd->pid, cmd->target, cmd->lun); + cmd->pid, cmd->device->id, cmd->device->lun); /* First scan Query list */ if( pACB->QueryCnt ) @@ -1586,7 +1586,7 @@ } } - pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun); + pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun); if( !pDCB ) goto NOT_RUN; /* Added 98/07/02 KG */ @@ -1785,7 +1785,7 @@ { UCHAR bval; DC390_AFLAGS - PACB pACB = (PACB) cmd->host->hostdata; + PACB pACB = (PACB) cmd->device->host->hostdata; printk(KERN_INFO "DC390: RESET ... "); @@ -2358,11 +2358,11 @@ static void dc390_inquiry_done (Scsi_Cmnd* cmd) { printk (KERN_INFO "DC390: INQUIRY (ID %02x LUN %02x) returned %08x\n", - cmd->target, cmd->lun, cmd->result); + cmd->device->id, cmd->device->lun, cmd->result); if (cmd->result) { - PACB pACB = (PACB)cmd->host->hostdata; - PDCB pDCB = dc390_findDCB (pACB, cmd->target, cmd->lun); + PACB pACB = (PACB)cmd->device->host->hostdata; + PDCB pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun); printk ("DC390: Unsetting DsCn, Sync and TagQ!\n"); if (pDCB) { @@ -2387,9 +2387,10 @@ cmd->cmnd[4] = 0xff; cmd->cmd_len = 6; cmd->old_cmd_len = 6; - cmd->host = pACB->pScsiHost; - cmd->target = pDCB->TargetID; - cmd->lun = pDCB->TargetLUN; +/* TODO FIXME */ +/* cmd->host = pACB->pScsiHost; */ + cmd->device->id = pDCB->TargetID; + cmd->device->lun = pDCB->TargetLUN; cmd->serial_number = 1; cmd->pid = 390; cmd->bufflen = 128; @@ -2419,7 +2420,7 @@ static void dc390_sendstart_done (Scsi_Cmnd* cmd) { printk (KERN_INFO "DC390: SENDSTART (ID %02x LUN %02x) returned %08x\n", - cmd->target, cmd->lun, cmd->result); + cmd->device->id, cmd->device->lun, cmd->result); kfree (cmd); }; @@ -2437,9 +2438,10 @@ cmd->cmnd[4] = 0x01; /* START */ cmd->cmd_len = 6; cmd->old_cmd_len = 6; - cmd->host = pACB->pScsiHost; - cmd->target = pDCB->TargetID; - cmd->lun = pDCB->TargetLUN; +/* TODO FIXME */ +/* cmd->host = pACB->pScsiHost; */ + cmd->device->id = pDCB->TargetID; + cmd->device->lun = pDCB->TargetLUN; cmd->serial_number = 1; cmd->pid = 310; cmd->bufflen = 128; @@ -2734,7 +2736,9 @@ reset: { - Scsi_Cmnd cmd; cmd.host = pACB->pScsiHost; + Scsi_Cmnd cmd; + /* TODO FIXME */ + /* cmd.host = pACB->pScsiHost; */ printk (KERN_WARNING "DC390: Driver reset requested!\n"); DC390_UNLOCK_ACB; DC390_reset (&cmd, 0); diff -Nru a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c --- a/drivers/scsi/u14-34f.c Sun Feb 9 21:13:30 2003 +++ b/drivers/scsi/u14-34f.c Sun Feb 9 21:13:30 2003 @@ -671,7 +671,7 @@ tag_suffix = ""; } - if (TLDEV(dev->type) && linked_comm && dev->new_queue_depth > 2) + if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2) link_suffix = ", sorted"; else if (TLDEV(dev->type)) link_suffix = ", unsorted"; @@ -680,7 +680,7 @@ printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n", BN(j), host->host_no, dev->channel, dev->id, dev->lun, - dev->new_queue_depth, link_suffix, tag_suffix); + dev->queue_depth, link_suffix, tag_suffix); return FALSE; } @@ -1213,7 +1213,7 @@ struct mscp *cpp; /* j is the board number */ - j = ((struct hostdata *) SCpnt->host->hostdata)->board_number; + j = ((struct hostdata *) SCpnt->device->host->hostdata)->board_number; if (SCpnt->host_scribble) panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", @@ -1247,13 +1247,13 @@ SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index; if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n", - BN(j), i, SCpnt->channel, SCpnt->target, - SCpnt->lun, SCpnt->pid); + BN(j), i, SCpnt->device->channel, SCpnt->device->id, + SCpnt->device->lun, SCpnt->pid); cpp->opcode = OP_SCSI; - cpp->channel = SCpnt->channel; - cpp->target = SCpnt->target; - cpp->lun = SCpnt->lun; + cpp->channel = SCpnt->device->channel; + cpp->target = SCpnt->device->id; + cpp->lun = SCpnt->device->lun; cpp->SCpnt = SCpnt; cpp->cdb_len = SCpnt->cmd_len; memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len); @@ -1264,7 +1264,7 @@ /* Map DMA buffers and SG list */ map_dma(i, j); - if (linked_comm && SCpnt->device->new_queue_depth > 2 + if (linked_comm && SCpnt->device->queue_depth > 2 && TLDEV(SCpnt->device->type)) { HD(j)->cp_stat[i] = READY; flush_dev(SCpnt->device, SCpnt->request->sector, j, FALSE); @@ -1275,7 +1275,7 @@ unmap_dma(i, j); SCpnt->host_scribble = NULL; printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n", - BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid); + BN(j), SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid); return 1; } @@ -1292,17 +1292,17 @@ static int u14_34f_eh_abort(Scsi_Cmnd *SCarg) { unsigned int i, j; - j = ((struct hostdata *) SCarg->host->hostdata)->board_number; + j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number; if (SCarg->host_scribble == NULL) { printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n", - BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); + BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); return SUCCESS; } i = *(unsigned int *)SCarg->host_scribble; printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n", - BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); + BN(j), i, SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); if (i >= sh[j]->can_queue) panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j)); @@ -1368,9 +1368,9 @@ int arg_done = FALSE; Scsi_Cmnd *SCpnt; - j = ((struct hostdata *) SCarg->host->hostdata)->board_number; + j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number; printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n", - BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid); + BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); if (SCarg->host_scribble == NULL) printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); @@ -1669,7 +1669,7 @@ if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { printk("%s: %s, target %d.%d:%d, pid %ld, mbox %d, adapter"\ " busy, will abort.\n", BN(j), (ihdlr ? "ihdlr" : "qcomm"), - SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, k); + SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, k); HD(j)->cp_stat[k] = ABORTING; continue; } @@ -1761,7 +1761,7 @@ sync_dma(i, j); - if (linked_comm && SCpnt->device->new_queue_depth > 2 + if (linked_comm && SCpnt->device->queue_depth > 2 && TLDEV(SCpnt->device->type)) flush_dev(SCpnt->device, SCpnt->request->sector, j, TRUE); @@ -1781,7 +1781,7 @@ /* If there was a bus reset, redo operation on each target */ else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK - && HD(j)->target_redo[SCpnt->target][SCpnt->channel]) + && HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel]) status = DID_BUS_BUSY << 16; /* Works around a flaw in scsi.c */ @@ -1794,29 +1794,29 @@ status = DID_OK << 16; if (tstatus == GOOD) - HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE; + HD(j)->target_redo[SCpnt->device->id][SCpnt->device->channel] = FALSE; if (spp->target_status && SCpnt->device->type == TYPE_DISK && (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 && (SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\ "target_status 0x%x, sense key 0x%x.\n", BN(j), - SCpnt->channel, SCpnt->target, SCpnt->lun, + SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, spp->target_status, SCpnt->sense_buffer[2]); - HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0; + HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] = 0; if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0; break; case ASST: /* Selection Time Out */ - if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1) + if (HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel] > 1) status = DID_ERROR << 16; else { status = DID_TIME_OUT << 16; - HD(j)->target_to[SCpnt->target][SCpnt->channel]++; + HD(j)->target_to[SCpnt->device->id][SCpnt->device->channel]++; } break; @@ -1875,7 +1875,7 @@ printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\ " target %d.%d:%d, pid %ld, reg 0x%x, count %d.\n", BN(j), i, spp->adapter_status, spp->target_status, - SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid, + SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->pid, reg, HD(j)->iocount); unmap_dma(i, j); diff -Nru a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c --- a/drivers/serial/8250_gsc.c Sun Feb 9 21:13:34 2003 +++ b/drivers/serial/8250_gsc.c Sun Feb 9 21:13:34 2003 @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -32,6 +33,7 @@ serial->type = PORT_16550A; serial->line = line; + serial->iomap_base = address; serial->iomem_base = ioremap(address, 0x8); serial->irq = irq; @@ -91,11 +93,13 @@ { 0 } }; -/* Hack. Dino's serial port will get listed first on some machines. - * So we register this driver first which knows about Lasi's serial port. - * This needs to get fixed properly somehow. +/* Hack. Some machines have SERIAL_0 attached to Lasi and SERIAL_1 + * attached to Dino. Unfortunately, Dino appears before Lasi in the device + * tree. To ensure that ttyS0 == SERIAL_0, we register two drivers; one + * which only knows about Lasi and then a second which will find all the + * other serial ports. HPUX ignores this problem. */ -static struct parisc_device_id serial1_tbl[] = { +static struct parisc_device_id lasi_tbl[] = { { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */ { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */ { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */ @@ -111,9 +115,9 @@ MODULE_DEVICE_TABLE(parisc, serial_tbl); -static struct parisc_driver serial1_driver = { - .name = "Serial RS232", - .id_table = serial1_tbl, +static struct parisc_driver lasi_driver = { + .name = "Lasi RS232", + .id_table = lasi_tbl, .probe = serial_init_chip, }; @@ -125,7 +129,7 @@ int __init probe_serial_gsc(void) { - register_parisc_driver(&serial1_driver); + register_parisc_driver(&lasi_driver); register_parisc_driver(&serial_driver); return 0; } diff -Nru a/drivers/serial/Kconfig b/drivers/serial/Kconfig --- a/drivers/serial/Kconfig Sun Feb 9 21:13:36 2003 +++ b/drivers/serial/Kconfig Sun Feb 9 21:13:36 2003 @@ -23,7 +23,7 @@ If you want to compile this driver as a module, say M here and read . The module will be called - serial.o. + serial. [WARNING: Do not compile this driver as a module if you are using non-standard serial ports, since the configuration information will be lost when the driver is unloaded. This limitation may be lifted @@ -73,7 +73,7 @@ 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 will be called serial_cs.o. If you want to compile it as + The module will be called serial_cs. If you want to compile it as a module, say M here and read . If unsure, say N. diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile --- a/drivers/serial/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/serial/Makefile Sun Feb 9 21:13:32 2003 @@ -4,8 +4,6 @@ # $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $ # -export-objs := core.o 8250.o 8250_pci.o suncore.o - serial-8250-y := serial-8250-$(CONFIG_GSC) += 8250_gsc.o serial-8250-$(CONFIG_PCI) += 8250_pci.o diff -Nru a/drivers/serial/mux.c b/drivers/serial/mux.c --- a/drivers/serial/mux.c Sun Feb 9 21:13:34 2003 +++ b/drivers/serial/mux.c Sun Feb 9 21:13:34 2003 @@ -23,7 +23,9 @@ #include #include #include +#include #include +#include #ifdef CONFIG_MAGIC_SYSRQ #include @@ -32,34 +34,35 @@ #include -#define MUX_NR 1 - #define MUX_OFFSET 0x800 #define MUX_LINE_OFFSET 0x80 #define MUX_FIFO_SIZE 255 -#define MUX_MIN_FREE_SIZE 32 - -#define MUX_FIFO_DRAIN_DELAY 1 -#define MUX_POLL_DELAY (30 * HZ / 1000) +#define MUX_POLL_DELAY (30 * HZ / 1000) -#define IO_COMMAND_REG_OFFSET 0x30 -#define IO_STATUS_REG_OFFSET 0x34 #define IO_DATA_REG_OFFSET 0x3c #define IO_DCOUNT_REG_OFFSET 0x40 -#define IO_UCOUNT_REG_OFFSET 0x44 -#define IO_FIFOS_REG_OFFSET 0x48 #define MUX_EOFIFO(status) ((status & 0xF000) == 0xF000) #define MUX_STATUS(status) ((status & 0xF000) == 0x8000) #define MUX_BREAK(status) ((status & 0xF000) == 0x2000) +#define UART_NR 8 +struct mux_card { + struct uart_port ports[UART_NR]; + struct uart_driver drv; + struct mux_card *next; +}; + +static struct mux_card mux_card_head = { + .next = NULL, +}; -static struct uart_port mux_ports[MUX_NR]; static struct timer_list mux_timer; #define UART_PUT_CHAR(p, c) __raw_writel((c), (unsigned long)(p)->membase + IO_DATA_REG_OFFSET) #define UART_GET_FIFO_CNT(p) __raw_readl((unsigned long)(p)->membase + IO_DCOUNT_REG_OFFSET) +#define GET_MUX_PORTS(iodc_data) ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8 /** * mux_tx_empty - Check if the transmitter fifo is empty. @@ -205,8 +208,8 @@ static void mux_read(struct uart_port *port) { int data; - __u32 start_count = port->icount.rx; struct tty_struct *tty = port->info->tty; + __u32 start_count = port->icount.rx; while(1) { data = __raw_readl((unsigned long)port->membase @@ -294,7 +297,7 @@ } /** - * release_port - Release memory and IO regions. + * mux_release_port - Release memory and IO regions. * @port: Ptr to the uart_port. * * Release any memory and IO region resources currently in use by @@ -350,17 +353,26 @@ } /** - * mux_drv_poll - Mux poll function. + * mux_drv_poll - Mux poll function. * @unused: Unused variable * * This function periodically polls the Serial MUX to check for new data. */ static void mux_poll(unsigned long unused) { - struct uart_port *port = &mux_ports[0]; + int i; + struct mux_card *card = &mux_card_head; + + while(card) { + for(i = 0; i < UART_NR; ++i) { + if(!card->ports[i].info) + continue; - mux_read(port); - mux_write(port); + mux_read(&card->ports[i]); + mux_write(&card->ports[i]); + } + card = card->next; + } mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY); } @@ -395,20 +407,6 @@ .verify_port = mux_verify_port, }; -static struct uart_driver mux_reg = { - .owner = THIS_MODULE, - .driver_name = "ttyB", -#ifdef CONFIG_DEVFS_FS - .dev_name = "ttyB%d", -#else - .dev_name = "ttyB%d", -#endif - .major = MUX_MAJOR, - .minor = 0, - .nr = MUX_NR, - .cons = MUX_CONSOLE, -}; - /** * mux_probe - Determine if the Serial Mux should claim this device. * @dev: The parisc device. @@ -418,36 +416,77 @@ */ static int __init mux_probe(struct parisc_device *dev) { - int i, ret; - struct uart_port *port = &mux_ports[0]; + int i, j, ret, ports, port_cnt = 0; + u8 iodc_data[8]; + unsigned long bytecnt; + struct uart_port *port; + struct mux_card *card = &mux_card_head; + + ret = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 8); + if(ret != PDC_OK) { + printk(KERN_ERR "Serial mux: Unable to read IODC.\n"); + return 1; + } - init_timer(&mux_timer); - mux_timer.function = mux_poll; + ports = GET_MUX_PORTS(iodc_data); + printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.2\n", + ports); + + if(!card->drv.nr) { + init_timer(&mux_timer); + mux_timer.function = mux_poll; + } else { + port_cnt += UART_NR; + while(card->next) { + card = card->next; + port_cnt += UART_NR; + } + } - printk(KERN_INFO "Serial mux driver Revision: 0.1\n"); + for(i = 0; i < ports / UART_NR; ++i) { + if(card->drv.nr) { + card->next = kmalloc(sizeof(struct mux_card), GFP_KERNEL); + if(!card->next) { + printk(KERN_ERR "Serial mux: Unable to allocate memory.\n"); + return 1; + } + memset(card->next, '\0', sizeof(struct mux_card)); + card = card->next; + } - ret = uart_register_driver(&mux_reg); - if (ret) - return ret; - - for (i = 0; i < MUX_NR; i++) { - port = &mux_ports[i]; - - port->iobase = 0; - port->mapbase = dev->hpa + MUX_OFFSET + (i * MUX_LINE_OFFSET); - port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); - port->iotype = SERIAL_IO_MEM; - port->type = PORT_MUX; - port->irq = SERIAL_IRQ_NONE; - port->uartclk = 0; - port->fifosize = MUX_FIFO_SIZE; - port->ops = &mux_pops; - port->flags = UPF_BOOT_AUTOCONF; - port->line = 0; + card->drv.owner = THIS_MODULE; + card->drv.driver_name = "ttyB"; + card->drv.dev_name = "ttyB%d"; + card->drv.major = MUX_MAJOR; + card->drv.minor = port_cnt; + card->drv.nr = UART_NR; + card->drv.cons = MUX_CONSOLE; + + ret = uart_register_driver(&card->drv); + if(ret) { + printk(KERN_ERR "Serial mux: Unable to register driver.\n"); + return 1; + } - uart_add_one_port(&mux_reg, port); - } + for(j = 0; j < UART_NR; ++j) { + port = &card->ports[j]; + port->iobase = 0; + port->mapbase = dev->hpa + MUX_OFFSET + (j * MUX_LINE_OFFSET); + port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); + port->iotype = SERIAL_IO_MEM; + port->type = PORT_MUX; + port->irq = SERIAL_IRQ_NONE; + port->uartclk = 0; + port->fifosize = MUX_FIFO_SIZE; + port->ops = &mux_pops; + port->flags = UPF_BOOT_AUTOCONF; + port->line = j; + ret = uart_add_one_port(&card->drv, port); + BUG_ON(ret); + } + port_cnt += UART_NR; + } return 0; } @@ -459,9 +498,9 @@ MODULE_DEVICE_TABLE(parisc, mux_tbl); static struct parisc_driver mux_driver = { - .name = "Serial MUX driver", - .id_table = mux_tbl, - .probe = mux_probe, + .name = "Serial MUX", + .id_table = mux_tbl, + .probe = mux_probe, }; /** @@ -482,12 +521,13 @@ static void __exit mux_exit(void) { int i; + struct mux_card *card = &mux_card_head; - for (i = 0; i < MUX_NR; i++) { - uart_remove_one_port(&mux_reg, &mux_ports[i]); + for (i = 0; i < UART_NR; i++) { + uart_remove_one_port(&card->drv, &card->ports[i]); } - uart_unregister_driver(&mux_reg); + uart_unregister_driver(&card->drv); } module_init(mux_init); diff -Nru a/drivers/serial/uart00.c b/drivers/serial/uart00.c --- a/drivers/serial/uart00.c Sun Feb 9 21:13:31 2003 +++ b/drivers/serial/uart00.c Sun Feb 9 21:13:31 2003 @@ -1,5 +1,5 @@ /* - * linux/drivers/char/uart00.c + * linux/drivers/serial/uart00.c * * Driver for UART00 serial ports * @@ -149,7 +149,7 @@ goto ignore_char; } else if (rds & UART_RDS_PE_MSK) port->icount.parity++; - else if (rds & UART_RDS_PE_MSK) + else if (rds & UART_RDS_FE_MSK) port->icount.frame++; if (rds & UART_RDS_OE_MSK) port->icount.overrun++; @@ -168,7 +168,7 @@ else if (rds & UART_RDS_FE_MSK) flg = TTY_FRAME; - if (status & UART_RDS_OE_MSK) { + if (rds & UART_RDS_OE_MSK) { /* * CHECK: does overrun affect the current character? * ASSUMPTION: it does not. diff -Nru a/drivers/sgi/char/Makefile b/drivers/sgi/char/Makefile --- a/drivers/sgi/char/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/sgi/char/Makefile Sun Feb 9 21:13:28 2003 @@ -2,7 +2,6 @@ # Makefile for the linux kernel. # -export-objs := newport.o shmiq.o sgicons.o usema.o rrm.o obj-y := newport.o shmiq.o sgicons.o usema.o streamable.o obj-$(CONFIG_SGI_SERIAL) += sgiserial.o diff -Nru a/drivers/tc/Makefile b/drivers/tc/Makefile --- a/drivers/tc/Makefile Sun Feb 9 21:13:30 2003 +++ b/drivers/tc/Makefile Sun Feb 9 21:13:30 2003 @@ -2,11 +2,6 @@ # Makefile for the linux kernel. # -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := tc.o - # Object file lists. obj-$(CONFIG_TC) += tc.o diff -Nru a/drivers/telephony/Kconfig b/drivers/telephony/Kconfig --- a/drivers/telephony/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/telephony/Kconfig Sun Feb 9 21:13:29 2003 @@ -16,7 +16,7 @@ This support is also available as a module. If you want to compile it as a module, say M here and read . The module will be called - phonedev.o. + phonedev. config PHONE_IXJ tristate "QuickNet Internet LineJack/PhoneJack support" @@ -25,7 +25,7 @@ Say M if you have a telephony card manufactured by Quicknet Technologies, Inc. These include the Internet PhoneJACK and Internet LineJACK Telephony Cards. You will get a module called - ixj.o. + ixj. For the ISA versions of these products, you can configure the cards using the isapnp tools (pnpdump/isapnp) or you can use the diff -Nru a/drivers/telephony/Makefile b/drivers/telephony/Makefile --- a/drivers/telephony/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/telephony/Makefile Sun Feb 9 21:13:32 2003 @@ -2,8 +2,6 @@ # Makefile for drivers/telephony # -export-objs := phonedev.o ixj.o - obj-$(CONFIG_PHONE) += phonedev.o obj-$(CONFIG_PHONE_IXJ) += ixj.o obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o diff -Nru a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c --- a/drivers/telephony/ixj_pcmcia.c Sun Feb 9 21:13:35 2003 +++ b/drivers/telephony/ixj_pcmcia.c Sun Feb 9 21:13:35 2003 @@ -63,6 +63,7 @@ if (!link) return NULL; memset(link, 0, sizeof(struct dev_link_t)); + init_timer(&link->release); link->release.function = &ixj_cs_release; link->release.data = (u_long) link; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; diff -Nru a/drivers/usb/Kconfig b/drivers/usb/Kconfig --- a/drivers/usb/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/usb/Kconfig Sun Feb 9 21:13:29 2003 @@ -35,7 +35,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usbcore.o. If you want to compile it as a + The module will be called usbcore. If you want to compile it as a module, say M here and read . source "drivers/usb/core/Kconfig" @@ -84,7 +84,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called uss720.o. If you want to compile it as a + The module will be called uss720. If you want to compile it as a module, say M here and read . source "drivers/usb/serial/Kconfig" diff -Nru a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig --- a/drivers/usb/class/Kconfig Sun Feb 9 21:13:28 2003 +++ b/drivers/usb/class/Kconfig Sun Feb 9 21:13:28 2003 @@ -13,7 +13,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called audio.o. If you want to compile it as a + The module will be called audio. If you want to compile it as a module, say M here and read . comment "USB Bluetooth TTY can only be used with disabled Bluetooth subsystem" @@ -38,7 +38,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called bluetty.o. If you want to compile it as + The module will be called bluetty. If you want to compile it as a module, say M here and read . config USB_MIDI @@ -61,7 +61,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usb-midi.o. If you want to compile it as a + The module will be called usb-midi. If you want to compile it as a module, say M here and read . config USB_ACM @@ -78,7 +78,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called acm.o. If you want to compile it as a + The module will be called acm. If you want to compile it as a module, say M here and read . config USB_PRINTER @@ -90,6 +90,6 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called printer.o. If you want to compile it as a + The module will be called printer. If you want to compile it as a module, say M here and read . diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c --- a/drivers/usb/class/cdc-acm.c Sun Feb 9 21:13:33 2003 +++ b/drivers/usb/class/cdc-acm.c Sun Feb 9 21:13:33 2003 @@ -257,7 +257,7 @@ if (urb->status) dbg("nonzero read bulk status received: %d", urb->status); - if (!urb->status & !acm->throttle) { + if (!urb->status && !acm->throttle) { for (i = 0; i < urb->actual_length && !acm->throttle; i++) { /* if we insert more than TTY_FLIPBUF_SIZE characters, * we drop them. */ @@ -697,6 +697,7 @@ static struct usb_device_id acm_ids[] = { { USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) }, + { USB_DEVICE_INFO(USB_CLASS_COMM, 2, 0) }, { } }; diff -Nru a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile --- a/drivers/usb/core/Makefile Sun Feb 9 21:13:37 2003 +++ b/drivers/usb/core/Makefile Sun Feb 9 21:13:37 2003 @@ -2,8 +2,6 @@ # Makefile for USB Core files and filesystem # -export-objs := usb.o hcd.o hcd-pci.o urb.o message.o file.o buffer.o - usbcore-objs := usb.o usb-debug.o hub.o hcd.o urb.o message.o \ config.o file.o buffer.o driverfs.o diff -Nru a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c --- a/drivers/usb/core/devices.c Sun Feb 9 21:13:36 2003 +++ b/drivers/usb/core/devices.c Sun Feb 9 21:13:36 2003 @@ -68,7 +68,7 @@ static char *format_topo = /* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ - "T: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; +"\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; static char *format_string_manufacturer = /* S: Manufacturer=xxxx */ diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c --- a/drivers/usb/core/hcd.c Sun Feb 9 21:13:33 2003 +++ b/drivers/usb/core/hcd.c Sun Feb 9 21:13:33 2003 @@ -310,9 +310,9 @@ } else return 0; - data [0] = 2 + ascii2utf (buf, data + 2, len - 2); + data [0] = 2 * (strlen (buf) + 1); data [1] = 3; /* type == string */ - return data [0]; + return 2 + ascii2utf (buf, data + 2, len - 2); } @@ -1029,8 +1029,11 @@ return status; } - /* lower level hcd code should use *_dma exclusively */ - if (!(urb->transfer_flags & URB_NO_DMA_MAP)) { + /* lower level hcd code should use *_dma exclusively, + * unless it uses pio or talks to another transport. + */ + if (!(urb->transfer_flags & URB_NO_DMA_MAP) + && hcd->controller->dma_mask) { if (usb_pipecontrol (urb->pipe)) urb->setup_dma = dma_map_single ( hcd->controller, diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h --- a/drivers/usb/core/hcd.h Sun Feb 9 21:13:30 2003 +++ b/drivers/usb/core/hcd.h Sun Feb 9 21:13:30 2003 @@ -111,6 +111,13 @@ */ }; +/* 2.4 does this a bit differently ... */ +static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd) +{ + return &hcd->self; +} + + struct hcd_dev { /* usb_device.hcpriv points to this */ struct list_head dev_list; /* on this hcd */ struct list_head urb_list; /* pending on this dev */ @@ -342,6 +349,13 @@ extern int usb_register_root_hub (struct usb_device *usb_dev, struct device *parent_dev); + +/* for portability to 2.4, hcds should call this */ +static inline int hcd_register_root (struct usb_hcd *hcd) +{ + return usb_register_root_hub ( + hcd_to_bus (hcd)->root_hub, hcd->controller); +} /*-------------------------------------------------------------------------*/ diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c --- a/drivers/usb/core/message.c Sun Feb 9 21:13:29 2003 +++ b/drivers/usb/core/message.c Sun Feb 9 21:13:29 2003 @@ -206,7 +206,8 @@ kfree (io->urbs); io->urbs = 0; } - usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents); + if (io->dev->dev.dma_mask != 0) + usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents); io->dev = 0; } @@ -301,6 +302,7 @@ { int i; int urb_flags; + int dma; if (!io || !dev || !sg || usb_pipecontrol (pipe) @@ -314,8 +316,16 @@ io->sg = sg; io->nents = nents; + /* not all host controllers use DMA (like the mainstream pci ones); + * they can use PIO (sl811) or be software over another transport. + */ + dma = (dev->dev.dma_mask != 0); + if (dma) + io->entries = usb_buffer_map_sg (dev, pipe, sg, nents); + else + io->entries = nents; + /* initialize all the urbs we'll use */ - io->entries = usb_buffer_map_sg (dev, pipe, sg, nents); if (io->entries <= 0) return io->entries; @@ -347,8 +357,17 @@ io->urbs [i]->status = -EINPROGRESS; io->urbs [i]->actual_length = 0; - io->urbs [i]->transfer_dma = sg_dma_address (sg + i); - len = sg_dma_len (sg + i); + if (dma) { + /* hc may use _only_ transfer_dma */ + io->urbs [i]->transfer_dma = sg_dma_address (sg + i); + len = sg_dma_len (sg + i); + } else { + /* hc may use _only_ transfer_buffer */ + io->urbs [i]->transfer_buffer = + page_address (sg [i].page) + sg [i].offset; + len = sg [i].length; + } + if (length) { len = min_t (unsigned, len, length); length -= len; @@ -434,9 +453,7 @@ retval = 0; i--; // FIXME: should it usb_sg_cancel() on INTERRUPT? - // how about imposing a backoff? - set_current_state (TASK_UNINTERRUPTIBLE); - schedule (); + yield (); break; /* no error? continue immediately. diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c --- a/drivers/usb/core/usb.c Sun Feb 9 21:13:32 2003 +++ b/drivers/usb/core/usb.c Sun Feb 9 21:13:32 2003 @@ -1224,7 +1224,8 @@ * * Return value is either null (indicating no buffer could be mapped), or * the parameter. URB_NO_DMA_MAP is added to urb->transfer_flags if the - * operation succeeds. + * operation succeeds. If the device is connected to this system through + * a non-DMA controller, this operation always succeeds. * * This call would normally be used for an urb which is reused, perhaps * as the target of a large periodic transfer, with usb_buffer_dmasync() @@ -1245,12 +1246,15 @@ || !(controller = bus->controller)) return 0; - urb->transfer_dma = dma_map_single (controller, + if (controller->dma_mask) { + urb->transfer_dma = dma_map_single (controller, urb->transfer_buffer, urb->transfer_buffer_length, usb_pipein (urb->pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); // FIXME generic api broken like pci, can't report errors // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; + } else + urb->transfer_dma = ~0; urb->transfer_flags |= URB_NO_DMA_MAP; return urb; } @@ -1271,7 +1275,8 @@ || !(controller = bus->controller)) return; - dma_sync_single (controller, + if (controller->dma_mask) + dma_sync_single (controller, urb->transfer_dma, urb->transfer_buffer_length, usb_pipein (urb->pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); @@ -1295,10 +1300,12 @@ || !(controller = bus->controller)) return; - dma_unmap_single (controller, + if (controller->dma_mask) + dma_unmap_single (controller, urb->transfer_dma, urb->transfer_buffer_length, usb_pipein (urb->pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); + urb->transfer_flags &= ~URB_NO_DMA_MAP; } /** @@ -1336,7 +1343,8 @@ if (!dev || usb_pipecontrol (pipe) || !(bus = dev->bus) - || !(controller = bus->controller)) + || !(controller = bus->controller) + || !controller->dma_mask) return -1; // FIXME generic api broken like pci, can't report errors @@ -1362,7 +1370,8 @@ if (!dev || !(bus = dev->bus) - || !(controller = bus->controller)) + || !(controller = bus->controller) + || !controller->dma_mask) return; dma_sync_sg (controller, sg, n_hw_ents, @@ -1386,7 +1395,8 @@ if (!dev || !(bus = dev->bus) - || !(controller = bus->controller)) + || !(controller = bus->controller) + || !controller->dma_mask) return; dma_unmap_sg (controller, sg, n_hw_ents, diff -Nru a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig --- a/drivers/usb/host/Kconfig Sun Feb 9 21:13:36 2003 +++ b/drivers/usb/host/Kconfig Sun Feb 9 21:13:36 2003 @@ -28,7 +28,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called ehci-hcd.o. If you want to compile it as a + The module will be called ehci-hcd. If you want to compile it as a module, say M here and read . config USB_OHCI_HCD @@ -46,7 +46,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called ohci-hcd.o. If you want to compile it + The module will be called ohci-hcd. If you want to compile it as a module, say M here and read . config USB_UHCI_HCD @@ -64,7 +64,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called uhci-hcd.o. If you want to compile it as a + The module will be called uhci-hcd. If you want to compile it as a module, say M here and read . config USB_SL811HS @@ -77,6 +77,6 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called hc_sl811.o. If you want to compile it + The module will be called hc_sl811. If you want to compile it as a module, say M here and read . diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c --- a/drivers/usb/host/ehci-dbg.c Sun Feb 9 21:13:35 2003 +++ b/drivers/usb/host/ehci-dbg.c Sun Feb 9 21:13:35 2003 @@ -277,7 +277,26 @@ default: tmp = '?'; break; \ }; tmp; }) -static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep) +static inline char token_mark (u32 token) +{ + token = le32_to_cpu (token); + if (token & QTD_STS_ACTIVE) + return '*'; + if (token & QTD_STS_HALT) + return '-'; + if (QTD_PID (token) != 1 /* not IN: OUT or SETUP */ + || QTD_LENGTH (token) == 0) + return ' '; + /* tries to advance through hw_alt_next */ + return '/'; +} + +static void qh_lines ( + struct ehci_hcd *ehci, + struct ehci_qh *qh, + char **nextp, + unsigned *sizep +) { u32 scratch; u32 hw_curr; @@ -286,26 +305,49 @@ unsigned temp; unsigned size = *sizep; char *next = *nextp; + char mark; + mark = token_mark (qh->hw_token); + if (mark == '/') { /* qh_alt_next controls qh advance? */ + if ((qh->hw_alt_next & QTD_MASK) == ehci->async->hw_alt_next) + mark = '#'; /* blocked */ + else if (qh->hw_alt_next & cpu_to_le32 (0x01)) + mark = '.'; /* use hw_qtd_next */ + /* else alt_next points to some other qtd */ + } scratch = cpu_to_le32p (&qh->hw_info1); - hw_curr = cpu_to_le32p (&qh->hw_current); + hw_curr = (mark == '*') ? cpu_to_le32p (&qh->hw_current) : 0; temp = snprintf (next, size, - "qh/%p dev%d %cs ep%d %08x %08x (%08x %08x)", + "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)", qh, scratch & 0x007f, speed_char (scratch), (scratch >> 8) & 0x000f, scratch, cpu_to_le32p (&qh->hw_info2), - hw_curr, cpu_to_le32p (&qh->hw_token)); + cpu_to_le32p (&qh->hw_token), mark, + (cpu_to_le32 (0x8000000) & qh->hw_token) + ? "data0" : "data1", + (cpu_to_le32p (&qh->hw_alt_next) >> 1) & 0x0f); size -= temp; next += temp; + /* hc may be modifying the list as we read it ... */ list_for_each (entry, &qh->qtd_list) { td = list_entry (entry, struct ehci_qtd, qtd_list); scratch = cpu_to_le32p (&td->hw_token); + mark = ' '; + if (hw_curr == td->qtd_dma) + mark = '*'; + else if (qh->hw_qtd_next == td->qtd_dma) + mark = '+'; + else if (QTD_LENGTH (scratch)) { + if (td->hw_alt_next == ehci->async->hw_alt_next) + mark = '#'; + else if (td->hw_alt_next != EHCI_LIST_END) + mark = '/'; + } temp = snprintf (next, size, - "\n\t%std/%p %s len=%d %08x urb %p", - (hw_curr == td->qtd_dma) ? "*" : "", - td, ({ char *tmp; + "\n\t%p%c%s len=%d %08x urb %p", + td, mark, ({ char *tmp; switch ((scratch>>8)&0x03) { case 0: tmp = "out"; break; case 1: tmp = "in"; break; @@ -315,13 +357,27 @@ (scratch >> 16) & 0x7fff, scratch, td->urb); + if (temp < 0) + temp = 0; + else if (size < temp) + temp = size; size -= temp; next += temp; + if (temp == size) + goto done; } temp = snprintf (next, size, "\n"); - *sizep = size - temp; - *nextp = next + temp; + if (temp < 0) + temp = 0; + else if (size < temp) + temp = size; + size -= temp; + next += temp; + +done: + *sizep = size; + *nextp = next; } static ssize_t @@ -344,14 +400,15 @@ * one QH per line, and TDs we know about */ spin_lock_irqsave (&ehci->lock, flags); - for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh) - qh_lines (qh, &next, &size); - if (ehci->reclaim) { + for (qh = ehci->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh) + qh_lines (ehci, qh, &next, &size); + if (ehci->reclaim && size > 0) { temp = snprintf (next, size, "\nreclaim =\n"); size -= temp; next += temp; - qh_lines (ehci->reclaim, &next, &size); + for (qh = ehci->reclaim; size > 0 && qh; qh = qh->reclaim) + qh_lines (ehci, qh, &next, &size); } spin_unlock_irqrestore (&ehci->lock, flags); @@ -421,7 +478,7 @@ scratch & 0x007f, (scratch >> 8) & 0x000f, p.qh->usecs, p.qh->c_usecs, - scratch >> 16); + 0x7ff & (scratch >> 16)); /* FIXME TD info too */ @@ -490,7 +547,8 @@ /* Capability Registers */ i = readw (&ehci->caps->hci_version); - temp = snprintf (next, size, "EHCI %x.%02x, hcd state %d\n", + temp = snprintf (next, size, + "EHCI %x.%02x, hcd state %d (version " DRIVER_VERSION ")\n", i >> 8, i & 0x0ff, ehci->hcd.state); size -= temp; next += temp; diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c --- a/drivers/usb/host/ehci-hcd.c Sun Feb 9 21:13:33 2003 +++ b/drivers/usb/host/ehci-hcd.c Sun Feb 9 21:13:33 2003 @@ -94,7 +94,7 @@ * 2001-June Works with usb-storage and NEC EHCI on 2.4 */ -#define DRIVER_VERSION "2002-Nov-29" +#define DRIVER_VERSION "2003-Jan-22" #define DRIVER_AUTHOR "David Brownell" #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver" @@ -110,10 +110,11 @@ /* magic numbers that can affect system performance */ #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ -#define EHCI_TUNE_RL_HS 0 /* nak throttle; see 4.9 */ +#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ #define EHCI_TUNE_RL_TT 0 #define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ #define EHCI_TUNE_MULT_TT 1 +#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ #define EHCI_WATCHDOG_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ #define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ @@ -416,13 +417,26 @@ ehci_info (ehci, "enabled 64bit PCI DMA\n"); } + /* help hc dma work well with cachelines */ + pci_set_mwi (ehci->hcd.pdev); + /* clear interrupt enables, set irq latency */ temp = readl (&ehci->regs->command) & 0xff; if (log2_irq_thresh < 0 || log2_irq_thresh > 6) log2_irq_thresh = 0; temp |= 1 << (16 + log2_irq_thresh); // if hc can park (ehci >= 0.96), default is 3 packets per async QH - // keeping default periodic framelist size + if (HCC_PGM_FRAMELISTLEN (hcc_params)) { + /* periodic schedule size can be smaller than default */ + temp &= ~(3 << 2); + temp |= (EHCI_TUNE_FLS << 2); + switch (EHCI_TUNE_FLS) { + case 0: ehci->periodic_size = 1024; break; + case 1: ehci->periodic_size = 512; break; + case 2: ehci->periodic_size = 256; break; + default: BUG (); + } + } temp &= ~(CMD_IAAD | CMD_ASE | CMD_PSE), // Philips, Intel, and maybe others need CMD_RUN before the // root hub will detect new devices (why?); NEC doesn't @@ -759,7 +773,6 @@ struct ehci_hcd *ehci = hcd_to_ehci (hcd); struct ehci_qh *qh; unsigned long flags; - int maybe_irq = 1; spin_lock_irqsave (&ehci->lock, flags); switch (usb_pipetype (urb->pipe)) { @@ -769,23 +782,23 @@ qh = (struct ehci_qh *) urb->hcpriv; if (!qh) break; - while (qh->qh_state == QH_STATE_LINKED + + /* if we need to use IAA and it's busy, defer */ + if (qh->qh_state == QH_STATE_LINKED && ehci->reclaim && HCD_IS_RUNNING (ehci->hcd.state) ) { - spin_unlock_irqrestore (&ehci->lock, flags); + struct ehci_qh *last; - if (maybe_irq) { - if (in_interrupt ()) - return -EAGAIN; - maybe_irq = 0; - } - /* let pending unlinks complete, so this can start */ - wait_ms (1); + for (last = ehci->reclaim; + last->reclaim; + last = last->reclaim) + continue; + qh->qh_state = QH_STATE_UNLINK_WAIT; + last->reclaim = qh; - spin_lock_irqsave (&ehci->lock, flags); - } - if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim) + /* bypass IAA if the hc can't care */ + } else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim) end_unlink_async (ehci, NULL); /* something else might have unlinked the qh by now */ diff -Nru a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c --- a/drivers/usb/host/ehci-mem.c Sun Feb 9 21:13:36 2003 +++ b/drivers/usb/host/ehci-mem.c Sun Feb 9 21:13:36 2003 @@ -75,8 +75,6 @@ qtd = pci_pool_alloc (ehci->qtd_pool, flags, &dma); if (qtd != 0) { ehci_qtd_init (qtd, dma); - if (ehci->async) - qtd->hw_alt_next = ehci->async->hw_alt_next; } return qtd; } diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c --- a/drivers/usb/host/ehci-q.c Sun Feb 9 21:13:35 2003 +++ b/drivers/usb/host/ehci-q.c Sun Feb 9 21:13:35 2003 @@ -43,7 +43,8 @@ /* fill a qtd, returning how much of the buffer we were able to queue up */ static int -qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, int token) +qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len, + int token, int maxpacket) { int i, count; u64 addr = buf; @@ -69,6 +70,10 @@ else count = len; } + + /* short packets may only terminate transfers */ + if (count != len) + count -= (count % maxpacket); } qtd->hw_token = cpu_to_le32 ((count << 16) | token); qtd->length = count; @@ -85,7 +90,7 @@ { qh->hw_current = 0; qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma); - qh->hw_alt_next = ehci->async->hw_alt_next; + qh->hw_alt_next = EHCI_LIST_END; /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ wmb (); @@ -96,7 +101,7 @@ #define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1) -static inline void qtd_copy_status ( +static void qtd_copy_status ( struct ehci_hcd *ehci, struct urb *urb, size_t length, @@ -224,12 +229,24 @@ { struct ehci_qtd *last = 0, *end = qh->dummy; struct list_head *entry, *tmp; - int stopped = 0; + int stopped; unsigned count = 0; + int do_status = 0; + u8 state; if (unlikely (list_empty (&qh->qtd_list))) return count; + /* completions (or tasks on other cpus) must never clobber HALT + * till we've gone through and cleaned everything up, even when + * they add urbs to this qh's queue or mark them for unlinking. + * + * NOTE: unlinking expects to be done in queue order. + */ + state = qh->qh_state; + qh->qh_state = QH_STATE_COMPLETING; + stopped = (state == QH_STATE_IDLE); + /* remove de-activated QTDs from front of queue. * after faults (including short reads), cleanup this urb * then let the queue advance. @@ -261,7 +278,6 @@ rmb (); token = le32_to_cpu (qtd->hw_token); stopped = stopped - || (qh->qh_state == QH_STATE_IDLE) || (HALT_BIT & qh->hw_token) != 0 || (ehci->hcd.state == USB_STATE_HALT); @@ -271,36 +287,53 @@ /* magic dummy for short reads; won't advance */ if (IS_SHORT_READ (token) && !(token & QTD_STS_HALT) - && ehci->async->hw_alt_next - == qh->hw_alt_next) + && (qh->hw_alt_next & QTD_MASK) + == ehci->async->hw_alt_next) { + stopped = 1; goto halt; + } /* stop scanning when we reach qtds the hc is using */ } else if (likely (!stopped)) { - last = 0; break; } else { - /* ignore active qtds unless some previous qtd + /* ignore active urbs unless some previous qtd * for the urb faulted (including short read) or * its urb was canceled. we may patch qh or qtds. */ - if ((token & QTD_STS_ACTIVE) - && urb->status == -EINPROGRESS) { - last = 0; + if (likely (urb->status == -EINPROGRESS)) + continue; + + /* issue status after short control reads */ + if (unlikely (do_status != 0) + && QTD_PID (token) == 0 /* OUT */) { + do_status = 0; continue; } + + /* token in overlay may be most current */ + if (state == QH_STATE_IDLE + && cpu_to_le32 (qtd->qtd_dma) + == qh->hw_current) + token = le32_to_cpu (qh->hw_token); + + /* force halt for unlinked or blocked qh, so we'll + * patch the qh later and so that completions can't + * activate it while we "know" it's stopped. + */ if ((HALT_BIT & qh->hw_token) == 0) { halt: qh->hw_token |= HALT_BIT; wmb (); - stopped = 1; } } /* remove it from the queue */ spin_lock (&urb->lock); qtd_copy_status (ehci, urb, qtd->length, token); + do_status = (urb->status == -EREMOTEIO) + && usb_pipecontrol (urb->pipe); spin_unlock (&urb->lock); if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { @@ -319,6 +352,9 @@ ehci_qtd_free (ehci, last); } + /* restore original state; caller must unlink or relink */ + qh->qh_state = state; + /* update qh after fault cleanup */ if (unlikely ((HALT_BIT & qh->hw_token) != 0)) { qh_update (ehci, qh, @@ -367,7 +403,7 @@ struct ehci_qtd *qtd, *qtd_prev; dma_addr_t buf; int len, maxpacket; - int is_input, status_patch = 0; + int is_input; u32 token; /* @@ -388,7 +424,7 @@ if (usb_pipecontrol (urb->pipe)) { /* SETUP pid */ qtd_fill (qtd, urb->setup_dma, sizeof (struct usb_ctrlrequest), - token | (2 /* "setup" */ << 8)); + token | (2 /* "setup" */ << 8), 8); /* ... and always at least one more pid */ token ^= QTD_TOGGLE; @@ -399,10 +435,6 @@ qtd->urb = urb; qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma); list_add_tail (&qtd->qtd_list, head); - - if (len > 0 && is_input - && !(urb->transfer_flags & URB_SHORT_NOT_OK)) - status_patch = 1; } /* @@ -413,6 +445,7 @@ else buf = 0; + // FIXME this 'buf' check break some zlps... if (!buf || is_input) token |= (1 /* "in" */ << 8); /* else it's already initted to "out" pid (0 << 8) */ @@ -427,9 +460,11 @@ for (;;) { int this_qtd_len; - this_qtd_len = qtd_fill (qtd, buf, len, token); + this_qtd_len = qtd_fill (qtd, buf, len, token, maxpacket); len -= this_qtd_len; buf += this_qtd_len; + if (is_input) + qtd->hw_alt_next = ehci->async->hw_alt_next; /* qh makes control packets use qtd toggle; maybe switch it */ if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0) @@ -447,6 +482,13 @@ list_add_tail (&qtd->qtd_list, head); } + /* unless the bulk/interrupt caller wants a chance to clean + * up after short reads, hc should advance qh past this urb + */ + if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 + || usb_pipecontrol (urb->pipe))) + qtd->hw_alt_next = EHCI_LIST_END; + /* * control requests may need a terminating data "status" ack; * bulk ones may need a terminating short packet (zero length). @@ -473,23 +515,10 @@ list_add_tail (&qtd->qtd_list, head); /* never any data in such packets */ - qtd_fill (qtd, 0, 0, token); + qtd_fill (qtd, 0, 0, token, 0); } } - /* if we're permitting a short control read, we want the hardware to - * just continue after short data and send the status ack. it can do - * that on the last data packet (typically the only one). for other - * packets, software fixup is needed (in qh_completions). - */ - if (status_patch) { - struct ehci_qtd *prev; - - prev = list_entry (qtd->qtd_list.prev, - struct ehci_qtd, qtd_list); - prev->hw_alt_next = QTD_NEXT (qtd->qtd_dma); - } - /* by default, enable interrupt on urb completion */ if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT))) qtd->hw_token |= __constant_cpu_to_le32 (QTD_IOC); @@ -611,7 +640,8 @@ case USB_SPEED_FULL: /* EPS 0 means "full" */ - info1 |= (EHCI_TUNE_RL_TT << 28); + if (type != PIPE_INTERRUPT) + info1 |= (EHCI_TUNE_RL_TT << 28); if (type == PIPE_CONTROL) { info1 |= (1 << 27); /* for TT */ info1 |= 1 << 14; /* toggle from qtd */ @@ -628,12 +658,13 @@ case USB_SPEED_HIGH: /* no TT involved */ info1 |= (2 << 12); /* EPS "high" */ - info1 |= (EHCI_TUNE_RL_HS << 28); if (type == PIPE_CONTROL) { + info1 |= (EHCI_TUNE_RL_HS << 28); info1 |= 64 << 16; /* usb2 fixed maxpacket */ info1 |= 1 << 14; /* toggle from qtd */ info2 |= (EHCI_TUNE_MULT_HS << 30); } else if (type == PIPE_BULK) { + info1 |= (EHCI_TUNE_RL_HS << 28); info1 |= 512 << 16; /* usb2 fixed maxpacket */ info2 |= (EHCI_TUNE_MULT_HS << 30); } else { /* PIPE_INTERRUPT */ @@ -769,8 +800,7 @@ && !usb_pipecontrol (urb->pipe)) { /* "never happens": drivers do stall cleanup right */ if (qh->qh_state != QH_STATE_IDLE - && (cpu_to_le32 (QTD_STS_HALT) - & qh->hw_token) == 0) + && qh->qh_state != QH_STATE_COMPLETING) ehci_warn (ehci, "clear toggle dev%d " "ep%d%s: not idle\n", usb_pipedevice (urb->pipe), @@ -809,7 +839,6 @@ __list_splice (qtd_list, qh->qtd_list.prev); ehci_qtd_init (qtd, qtd->qtd_dma); - qtd->hw_alt_next = ehci->async->hw_alt_next; qh->dummy = qtd; /* hc must see the new dummy at list end */ @@ -877,9 +906,12 @@ /* the async qh for the qtds being reclaimed are now unlinked from the HC */ +static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh); + static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) { struct ehci_qh *qh = ehci->reclaim; + struct ehci_qh *next; del_timer (&ehci->watchdog); @@ -890,6 +922,10 @@ ehci->reclaim = 0; ehci->reclaim_ready = 0; + /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */ + next = qh->reclaim; + qh->reclaim = 0; + qh_completions (ehci, qh, regs); if (!list_empty (&qh->qtd_list) @@ -909,6 +945,9 @@ jiffies + EHCI_ASYNC_JIFFIES); } } + + if (next) + start_unlink_async (ehci, next); } /* makes sure the async qh will become idle */ @@ -921,7 +960,8 @@ #ifdef DEBUG if (ehci->reclaim - || qh->qh_state != QH_STATE_LINKED + || (qh->qh_state != QH_STATE_LINKED + && qh->qh_state != QH_STATE_UNLINK_WAIT) #ifdef CONFIG_SMP // this macro lies except on SMP compiles || !spin_is_locked (&ehci->lock) @@ -953,6 +993,9 @@ wmb (); if (unlikely (ehci->hcd.state == USB_STATE_HALT)) { + /* if (unlikely (qh->reclaim != 0)) + * this will recurse, probably not much + */ end_unlink_async (ehci, NULL); return; } diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h --- a/drivers/usb/host/ehci.h Sun Feb 9 21:13:35 2003 +++ b/drivers/usb/host/ehci.h Sun Feb 9 21:13:35 2003 @@ -236,12 +236,12 @@ /* the rest is HCD-private */ dma_addr_t qtd_dma; /* qtd address */ struct list_head qtd_list; /* sw qtd list */ - - /* dma same in urb's qtds, except 1st control qtd (setup buffer) */ struct urb *urb; /* qtd's urb */ size_t length; /* length of buffer */ } __attribute__ ((aligned (32))); +#define QTD_MASK cpu_to_le32 (~0x1f) /* mask NakCnt+T in qh->hw_alt_next */ + /*-------------------------------------------------------------------------*/ /* type tag from {qh,itd,sitd,fstn}->hw_next */ @@ -305,6 +305,7 @@ union ehci_shadow qh_next; /* ptr to qh; or periodic */ struct list_head qtd_list; /* sw qtd list */ struct ehci_qtd *dummy; + struct ehci_qh *reclaim; /* next to reclaim */ atomic_t refcount; unsigned stamp; @@ -313,6 +314,8 @@ #define QH_STATE_LINKED 1 /* HC sees this */ #define QH_STATE_UNLINK 2 /* HC may still see this */ #define QH_STATE_IDLE 3 /* HC doesn't see this */ +#define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */ +#define QH_STATE_COMPLETING 5 /* don't touch token.HALT */ /* periodic schedule info */ u8 usecs; /* intr bandwidth */ @@ -425,16 +428,6 @@ } #else /* LINUX_VERSION_CODE */ - -// hcd_to_bus() eventually moves to hcd.h on 2.5 too -static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd) - { return &hcd->self; } -// ... as does hcd_register_root() -static inline int hcd_register_root (struct usb_hcd *hcd) -{ - return usb_register_root_hub ( - hcd_to_bus (hcd)->root_hub, &hcd->pdev->dev); -} #define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags) diff -Nru a/drivers/usb/host/hc_simple.c b/drivers/usb/host/hc_simple.c --- a/drivers/usb/host/hc_simple.c Sun Feb 9 21:13:37 2003 +++ b/drivers/usb/host/hc_simple.c Sun Feb 9 21:13:37 2003 @@ -219,7 +219,7 @@ if (!list_empty (&urb->urb_list) && urb->status == -EINPROGRESS) { /* URB active? */ - if (urb->transfer_flags & (URB_ASYNC_UNLINK | URB_TIMEOUT_KILLED)) { + if (urb->transfer_flags & URB_ASYNC_UNLINK) { /* asynchronous with callback */ /* relink the urb to the del list */ list_move (&urb->urb_list, &hci->del_list); @@ -388,7 +388,6 @@ struct urb *urb = (struct urb *) lurb; DBGFUNC ("enter qu_urb_timeout\n"); - urb->transfer_flags |= URB_TIMEOUT_KILLED; hci_unlink_urb (urb); } #endif diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c --- a/drivers/usb/host/ohci-hcd.c Sun Feb 9 21:13:29 2003 +++ b/drivers/usb/host/ohci-hcd.c Sun Feb 9 21:13:29 2003 @@ -203,27 +203,27 @@ return -ENOMEM; memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *)); - spin_lock_irqsave (&ohci->lock, flags); - - /* don't submit to a dead HC */ - if (ohci->disabled || ohci->sleeping) { - retval = -ENODEV; - goto fail; - } - /* fill the private part of the URB */ urb_priv->length = size; urb_priv->ed = ed; - /* allocate the TDs (updating hash chains) */ + /* allocate the TDs (deferring hash chain updates) */ for (i = 0; i < size; i++) { - urb_priv->td [i] = td_alloc (ohci, SLAB_ATOMIC); + urb_priv->td [i] = td_alloc (ohci, mem_flags); if (!urb_priv->td [i]) { urb_priv->length = i; - retval = -ENOMEM; - goto fail; + urb_free_priv (ohci, urb_priv); + return -ENOMEM; } } + + spin_lock_irqsave (&ohci->lock, flags); + + /* don't submit to a dead HC */ + if (ohci->disabled || ohci->sleeping) { + retval = -ENODEV; + goto fail; + } /* schedule the ed if needed */ if (ed->state == ED_IDLE) { diff -Nru a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c --- a/drivers/usb/host/ohci-mem.c Sun Feb 9 21:13:33 2003 +++ b/drivers/usb/host/ohci-mem.c Sun Feb 9 21:13:33 2003 @@ -97,17 +97,11 @@ td = pci_pool_alloc (hc->td_cache, mem_flags, &dma); if (td) { - int hash; - /* in case hc fetches it, make it look dead */ memset (td, 0, sizeof *td); td->hwNextTD = cpu_to_le32 (dma); td->td_dma = dma; - - /* hash it for later reverse mapping */ - hash = TD_HASH_FUNC (dma); - td->td_hash = hc->td_hash [hash]; - hc->td_hash [hash] = td; + /* hashed in td_fill */ } return td; } diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c --- a/drivers/usb/host/ohci-q.c Sun Feb 9 21:13:36 2003 +++ b/drivers/usb/host/ohci-q.c Sun Feb 9 21:13:36 2003 @@ -463,13 +463,14 @@ /* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ static void -td_fill (unsigned int info, +td_fill (struct ohci_hcd *ohci, u32 info, dma_addr_t data, int len, struct urb *urb, int index) { struct td *td, *td_pt; struct urb_priv *urb_priv = urb->hcpriv; int is_iso = info & TD_ISO; + int hash; // ASSERT (index < urb_priv->length); @@ -516,11 +517,16 @@ td->hwBE = 0; td->hwNextTD = cpu_to_le32 (td_pt->td_dma); - /* HC might read the TD right after we link it ... */ - wmb (); - /* append to queue */ list_add_tail (&td->td_list, &td->ed->td_list); + + /* hash it for later reverse mapping */ + hash = TD_HASH_FUNC (td->td_dma); + td->td_hash = ohci->td_hash [hash]; + ohci->td_hash [hash] = td; + + /* HC might read the TD (or cachelines) right away ... */ + wmb (); td->ed->hwTailP = td->hwNextTD; } @@ -578,7 +584,7 @@ : TD_T_TOGGLE | TD_CC | TD_DP_IN; /* TDs _could_ transfer up to 8K each */ while (data_len > 4096) { - td_fill (info, data, 4096, urb, cnt); + td_fill (ohci, info, data, 4096, urb, cnt); data += 4096; data_len -= 4096; cnt++; @@ -586,11 +592,11 @@ /* maybe avoid ED halt on final TD short read */ if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) info |= TD_R; - td_fill (info, data, data_len, urb, cnt); + td_fill (ohci, info, data, data_len, urb, cnt); cnt++; if ((urb->transfer_flags & URB_ZERO_PACKET) && cnt < urb_priv->length) { - td_fill (info, 0, 0, urb, cnt); + td_fill (ohci, info, 0, 0, urb, cnt); cnt++; } /* maybe kickstart bulk list */ @@ -605,17 +611,17 @@ */ case PIPE_CONTROL: info = TD_CC | TD_DP_SETUP | TD_T_DATA0; - td_fill (info, urb->setup_dma, 8, urb, cnt++); + td_fill (ohci, info, urb->setup_dma, 8, urb, cnt++); if (data_len > 0) { info = TD_CC | TD_R | TD_T_DATA1; info |= is_out ? TD_DP_OUT : TD_DP_IN; /* NOTE: mishandles transfers >8K, some >4K */ - td_fill (info, data, data_len, urb, cnt++); + td_fill (ohci, info, data, data_len, urb, cnt++); } info = is_out ? TD_CC | TD_DP_IN | TD_T_DATA1 : TD_CC | TD_DP_OUT | TD_T_DATA1; - td_fill (info, data, 0, urb, cnt++); + td_fill (ohci, info, data, 0, urb, cnt++); /* maybe kickstart control list */ wmb (); writel (OHCI_CLF, &ohci->regs->cmdstatus); @@ -634,7 +640,7 @@ // a 2^16 iso range, vs other HCs max of 2^10) frame += cnt * urb->interval; frame &= 0xffff; - td_fill (TD_CC | TD_ISO | frame, + td_fill (ohci, TD_CC | TD_ISO | frame, data + urb->iso_frame_desc [cnt].offset, urb->iso_frame_desc [cnt].length, urb, cnt); } diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c --- a/drivers/usb/host/uhci-hcd.c Sun Feb 9 21:13:35 2003 +++ b/drivers/usb/host/uhci-hcd.c Sun Feb 9 21:13:35 2003 @@ -1747,7 +1747,6 @@ tmp = tmp->next; - u->transfer_flags |= URB_TIMEOUT_KILLED; uhci_urb_dequeue(hcd, u); } diff -Nru a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig --- a/drivers/usb/image/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/usb/image/Kconfig Sun Feb 9 21:13:29 2003 @@ -16,7 +16,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called mdc800.o. If you want to compile it as a + The module will be called mdc800. If you want to compile it as a module, say M here and read . config USB_SCANNER @@ -29,7 +29,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called scanner.o. If you want to compile it as + The module will be called scanner. If you want to compile it as a module, say M here and read . config USB_MICROTEK @@ -42,7 +42,7 @@ Please report failures and successes. The scanner will appear as a scsi generic device to the rest of the system. Scsi support is required. - This driver can be compiled as a module, called microtek.o. + This driver can be compiled as a module, called microtek. config USB_HPUSBSCSI tristate "HP53xx USB scanner support (EXPERIMENTAL)" @@ -51,5 +51,5 @@ Say Y here if you want support for the HP 53xx series of scanners and the Minolta Scan Dual. This driver is experimental. The scanner will be accessible as a SCSI device. - This can be compiled as a module, called hpusbscsi.o. + This can be compiled as a module, called hpusbscsi. diff -Nru a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c --- a/drivers/usb/image/hpusbscsi.c Sun Feb 9 21:13:37 2003 +++ b/drivers/usb/image/hpusbscsi.c Sun Feb 9 21:13:37 2003 @@ -274,7 +274,7 @@ static int hpusbscsi_scsi_queuecommand (Scsi_Cmnd *srb, scsi_callback callback) { - struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]); + struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]); usb_complete_t usb_callback; int res; @@ -349,7 +349,7 @@ static int hpusbscsi_scsi_host_reset (Scsi_Cmnd *srb) { - struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]); + struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]); printk(KERN_DEBUG"SCSI reset requested.\n"); //usb_reset_device(hpusbscsi->dev); @@ -361,7 +361,7 @@ static int hpusbscsi_scsi_abort (Scsi_Cmnd *srb) { - struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->host->hostdata[0]); + struct hpusbscsi* hpusbscsi = (struct hpusbscsi*)(srb->device->host->hostdata[0]); printk(KERN_DEBUG"Requested is canceled.\n"); usb_unlink_urb(hpusbscsi->dataurb); diff -Nru a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c --- a/drivers/usb/image/microtek.c Sun Feb 9 21:13:37 2003 +++ b/drivers/usb/image/microtek.c Sun Feb 9 21:13:37 2003 @@ -398,7 +398,7 @@ static int mts_scsi_abort (Scsi_Cmnd *srb) { - struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]); + struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); MTS_DEBUG_GOT_HERE(); @@ -409,7 +409,7 @@ static int mts_scsi_host_reset (Scsi_Cmnd *srb) { - struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]); + struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); MTS_DEBUG_GOT_HERE(); mts_debug_dump(desc); @@ -692,7 +692,7 @@ static int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback ) { - struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]); + struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]); int err = 0; int res; diff -Nru a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c --- a/drivers/usb/image/scanner.c Sun Feb 9 21:13:30 2003 +++ b/drivers/usb/image/scanner.c Sun Feb 9 21:13:30 2003 @@ -1,13 +1,16 @@ /* -*- linux-c -*- */ /* - * Driver for USB Scanners (linux-2.5.54) + * Driver for USB Scanners (linux-2.5.60) * * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson + * Copyright (C) 2002, 2003 Henning Meier-Geinitz * * Portions may be copyright Brad Keryan and Michael Gee. * - * Brian Beattie + * Previously maintained by Brian Beattie + * + * Current maintainer: Henning Meier-Geinitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -300,8 +303,6 @@ * Frank Zago and * Oliver Neukum <520047054719-0001@t-online.de> for reviewing/testing. * - * 05/21/02 Currently maintained by Brian Beattie - * * 0.4.8 5/30/2002 * - Added Mustek BearPaw 2400 TA. Thanks to Sergey * Vlasov . @@ -332,12 +333,18 @@ * . * * 0.4.10 01/07/2003 - * - Added vendor/product ids for Visioneer scanners. + * - Added vendor/product ids for Artec, Canon, Compaq, Epson, HP, Microtek + * and Visioneer scanners. Thanks to William Lam , + * Till Kamppeter and others for all the ids. + * - Cleaned up list of vendor/product ids. * - Print information about user-supplied ids only once at startup instead * of everytime any USB device is plugged in. * - Removed PV8630 ioctls. Use the standard ioctls instead. * - Made endpoint detection more generic. Basically, only one bulk-in * endpoint is required, everything else is optional. + * - New maintainer: Henning Meier-Geinitz. + * - Print ids and device number when a device was detected. + * - Don't print errors when the device is busy. * * TODO * - Performance @@ -360,7 +367,7 @@ * - All the developers that are working on USB SANE backends or other * applications to use USB scanners. * - Thanks to Greg KH for setting up Brian Beattie - * to be the new USB Scanner maintainer. + * and Henning Meier-Geinitz to be the new USB Scanner maintainer. * * Performance: * @@ -369,6 +376,14 @@ * 24 Bit Color ~ 70 secs - 3.6 Mbit/sec * 8 Bit Gray ~ 17 secs - 4.2 Mbit/sec */ +/* + * For documentation, see Documentation/usb/scanner.txt. + * Website: http://www.meier-geinitz.de/kernel/ + * Please contact the maintainer if your scanner is not detected by this + * driver automatically. + */ + + #include /* @@ -461,7 +476,7 @@ } if (scn->isopen) { - err("open_scanner(%d): Scanner device is already open", scn_minor); + dbg("open_scanner(%d): Scanner device is already open", scn_minor); err = -EBUSY; goto out_error; } @@ -1046,6 +1061,9 @@ S_IWGRP | S_IROTH | S_IWOTH, &usb_scanner_fops, NULL); if (scn->devfs == NULL) dbg("scanner%d: device node registration failed", scn_minor); + + info ("USB scanner device (0x%04x/0x%04x) now attached to %s", + dev->descriptor.idVendor, dev->descriptor.idProduct, name); up(&scn_mutex); diff -Nru a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h --- a/drivers/usb/image/scanner.h Sun Feb 9 21:13:31 2003 +++ b/drivers/usb/image/scanner.h Sun Feb 9 21:13:31 2003 @@ -1,9 +1,10 @@ /* - * Driver for USB Scanners (linux-2.5.54) + * Driver for USB Scanners (linux-2.5.60) * * Copyright (C) 1999, 2000, 2001, 2002 David E. Nelson + * Previously maintained by Brian Beattie * - * Brian Beattie + * Current maintainer: Henning Meier-Geinitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -19,11 +20,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * 05/21/02 Currently maintained by Brian Beattie - * - * */ +/* + * For documentation, see Documentation/usb/scanner.txt. + * Website: http://www.meier-geinitz.de/kernel/ + * Please contact the maintainer if your scanner is not detected by this + * driver automatically. + */ + + #include #include #include @@ -45,7 +51,7 @@ static __s32 vendor=-1, product=-1, read_timeout=0; -MODULE_AUTHOR("Brian Beattie, beattie@beattie-home.net"); +MODULE_AUTHOR("Henning Meier-Geinitz, henning@meier-geinitz.de"); MODULE_DESCRIPTION(DRIVER_DESC" "DRIVER_VERSION); MODULE_LICENSE("GPL"); @@ -65,79 +71,90 @@ static struct usb_device_id scanner_device_ids [] = { /* Acer (now Benq) */ - { USB_DEVICE(0x04a5, 0x2060) }, /* 620U & 640U (!)*/ - { USB_DEVICE(0x04a5, 0x2040) }, /* 620U (!) */ - { USB_DEVICE(0x04a5, 0x20c0) }, /* 1240UT, 1240U */ - { USB_DEVICE(0x04a5, 0x2022) }, /* 340U */ { USB_DEVICE(0x04a5, 0x1a20) }, /* Unknown - Oliver Schwartz */ { USB_DEVICE(0x04a5, 0x1a2a) }, /* Another 620U */ + { USB_DEVICE(0x04a5, 0x2022) }, /* 340U */ + { USB_DEVICE(0x04a5, 0x2040) }, /* 620U (!) */ + { USB_DEVICE(0x04a5, 0x2060) }, /* 620U & 640U (!)*/ { USB_DEVICE(0x04a5, 0x207e) }, /* 640BU */ + { USB_DEVICE(0x04a5, 0x20b0) }, /* Benq 4300 */ { USB_DEVICE(0x04a5, 0x20be) }, /* Unknown - Oliver Schwartz */ + { USB_DEVICE(0x04a5, 0x20c0) }, /* 1240UT, 1240U */ { USB_DEVICE(0x04a5, 0x20de) }, /* S2W 3300U */ - { USB_DEVICE(0x04a5, 0x20b0) }, /* Benq 4300 */ - { USB_DEVICE(0x04a5, 0x20fe) }, /* Benq 5300 */ { USB_DEVICE(0x04a5, 0x20fc) }, /* Benq 5000 */ + { USB_DEVICE(0x04a5, 0x20fe) }, /* Benq 5300 */ /* Agfa */ { USB_DEVICE(0x06bd, 0x0001) }, /* SnapScan 1212U */ { USB_DEVICE(0x06bd, 0x0002) }, /* SnapScan 1236U */ - { USB_DEVICE(0x06bd, 0x2061) }, /* Another SnapScan 1212U (?)*/ { USB_DEVICE(0x06bd, 0x0100) }, /* SnapScan Touch */ + { USB_DEVICE(0x06bd, 0x2061) }, /* Another SnapScan 1212U (?)*/ + { USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */ + { USB_DEVICE(0x06bd, 0x208f) }, /* SnapScan e50*/ { USB_DEVICE(0x06bd, 0x2091) }, /* SnapScan e20 */ + { USB_DEVICE(0x06bd, 0x2093) }, /* SnapScan e10*/ { USB_DEVICE(0x06bd, 0x2095) }, /* SnapScan e25 */ { USB_DEVICE(0x06bd, 0x2097) }, /* SnapScan e26 */ - { USB_DEVICE(0x06bd, 0x208d) }, /* Snapscan e40 */ - { USB_DEVICE(0x06bd, 0x2093) }, /* SnapScan e10*/ - { USB_DEVICE(0x06bd, 0x20ff) }, /* SnapScan e42*/ - { USB_DEVICE(0x06bd, 0x208f) }, /* SnapScan e50*/ { USB_DEVICE(0x06bd, 0x20fd) }, /* SnapScan e52*/ + { USB_DEVICE(0x06bd, 0x20ff) }, /* SnapScan e42*/ + /* Artec */ + { USB_DEVICE(0x05d8, 0x4001) }, /* Ultima 2000 */ + { USB_DEVICE(0x05d8, 0x4002) }, /* Ultima 2000 (GT6801 based) */ /* Benq: see Acer */ /* Canon */ - { USB_DEVICE(0x04a9, 0x2201) }, /* FB320U */ - { USB_DEVICE(0x04a9, 0x2205) }, /* FB1210U */ + { USB_DEVICE(0x04a9, 0x2201) }, /* CanoScan FB320U */ { USB_DEVICE(0x04a9, 0x2202) }, /* CanoScan FB620U */ { USB_DEVICE(0x04a9, 0x2204) }, /* CanoScan FB630U/FB636U */ + { USB_DEVICE(0x04a9, 0x2205) }, /* CanoScan FB1210U */ { USB_DEVICE(0x04a9, 0x2206) }, /* CanoScan N650U/N656U */ { USB_DEVICE(0x04a9, 0x2207) }, /* CanoScan N1220U */ { USB_DEVICE(0x04a9, 0x2208) }, /* CanoScan D660U */ - { USB_DEVICE(0x04a9, 0x220b) }, /* D646U */ + { USB_DEVICE(0x04a9, 0x220b) }, /* CanoScan D646U */ + { USB_DEVICE(0x04a9, 0x220c) }, /* CanoScan D1250U2 */ { USB_DEVICE(0x04a9, 0x220d) }, /* CanoScan N670U/N676U/LIDE 20 */ { USB_DEVICE(0x04a9, 0x220e) }, /* CanoScan N1240U/LIDE 30 */ { USB_DEVICE(0x04a9, 0x3042) }, /* FS4000US */ /* Colorado -- See Primax/Colorado below */ + /* Compaq */ + { USB_DEVICE(0x049f, 0x0021) }, /* S200 */ /* Epson -- See Seiko/Epson below */ /* Genius */ - { USB_DEVICE(0x0458, 0x2001) }, /* ColorPage-Vivid Pro */ + { USB_DEVICE(0x0458, 0x2001) }, /* ColorPage Vivid Pro */ { USB_DEVICE(0x0458, 0x2007) }, /* ColorPage HR6 V2 */ - { USB_DEVICE(0x0458, 0x2008) }, /* ColorPage-HR6 V2 */ - { USB_DEVICE(0x0458, 0x2009) }, /* ColorPage-HR6A */ - { USB_DEVICE(0x0458, 0x2011) }, /* ColorPage-Vivid3x */ - { USB_DEVICE(0x0458, 0x2013) }, /* ColorPage-HR7 */ - { USB_DEVICE(0x0458, 0x2015) }, /* ColorPage-HR7LE */ - { USB_DEVICE(0x0458, 0x2016) }, /* ColorPage-HR6X */ + { USB_DEVICE(0x0458, 0x2008) }, /* ColorPage HR6 V2 */ + { USB_DEVICE(0x0458, 0x2009) }, /* ColorPage HR6A */ + { USB_DEVICE(0x0458, 0x2011) }, /* ColorPage Vivid3x */ + { USB_DEVICE(0x0458, 0x2013) }, /* ColorPage HR7 */ + { USB_DEVICE(0x0458, 0x2015) }, /* ColorPage HR7LE */ + { USB_DEVICE(0x0458, 0x2016) }, /* ColorPage HR6X */ /* Hewlett Packard */ - { USB_DEVICE(0x03f0, 0x0505) }, /* ScanJet 2100C */ - { USB_DEVICE(0x03f0, 0x0605) }, /* 2200C */ - { USB_DEVICE(0x03f0, 0x0901) }, /* 2300C */ - { USB_DEVICE(0x03f0, 0x0205) }, /* 3300C */ - { USB_DEVICE(0x03f0, 0x0405) }, /* 3400C */ - { USB_DEVICE(0x03f0, 0x0101) }, /* 4100C */ - { USB_DEVICE(0x03f0, 0x0105) }, /* 4200C */ - { USB_DEVICE(0x03f0, 0x0305) }, /* 4300C */ - { USB_DEVICE(0x03f0, 0x0705) }, /* 4400C */ + { USB_DEVICE(0x03f0, 0x0101) }, /* ScanJet 4100C */ { USB_DEVICE(0x03f0, 0x0102) }, /* PhotoSmart S20 */ - { USB_DEVICE(0x03f0, 0x0401) }, /* 5200C */ - // { USB_DEVICE(0x03f0, 0x0701) }, /* 5300C - NOT SUPPORTED - see http://www.neatech.nl/oss/HP5300C/ */ - { USB_DEVICE(0x03f0, 0x0201) }, /* 6200C */ - { USB_DEVICE(0x03f0, 0x0601) }, /* 6300C */ + { USB_DEVICE(0x03f0, 0x0105) }, /* ScanJet 4200C */ + { USB_DEVICE(0x03f0, 0x0201) }, /* ScanJet 6200C */ + { USB_DEVICE(0x03f0, 0x0205) }, /* ScanJet 3300C */ + { USB_DEVICE(0x03f0, 0x0305) }, /* ScanJet 4300C */ + { USB_DEVICE(0x03f0, 0x0401) }, /* ScanJet 5200C */ + { USB_DEVICE(0x03f0, 0x0405) }, /* ScanJet 3400C */ + { USB_DEVICE(0x03f0, 0x0505) }, /* ScanJet 2100C */ + { USB_DEVICE(0x03f0, 0x0601) }, /* ScanJet 6300C */ + { USB_DEVICE(0x03f0, 0x0605) }, /* ScanJet 2200C */ + // { USB_DEVICE(0x03f0, 0x0701) }, /* ScanJet 5300C - NOT SUPPORTED - use hpusbscsi driver */ + { USB_DEVICE(0x03f0, 0x0705) }, /* ScanJet 4400C */ + // { USB_DEVICE(0x03f0, 0x0801) }, /* ScanJet 7400C - NOT SUPPORTED - use hpusbscsi driver */ + { USB_DEVICE(0x03f0, 0x0901) }, /* ScanJet 2300C */ + { USB_DEVICE(0x03f0, 0x1305) }, /* Scanjet 4570c */ + { USB_DEVICE(0x03f0, 0x2005) }, /* ScanJet 3570c */ + { USB_DEVICE(0x03f0, 0x2205) }, /* ScanJet 3500c */ /* iVina */ { USB_DEVICE(0x0638, 0x0268) }, /* 1200U */ /* Lexmark */ { USB_DEVICE(0x043d, 0x002d) }, /* X70/X73 */ - /* Lifetec */ - { USB_DEVICE(0x05d8, 0x4002) }, /* Lifetec LT9385 */ /* Memorex */ { USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */ - /* Microtek -- No longer supported - Enable SCSI and USB Microtek in kernel config */ + /* Microtek */ + { USB_DEVICE(0x05da, 0x30ce) }, /* ScanMaker 3800 */ + /* The following SCSI-over-USB Microtek devices are supported by the + microtek driver: Enable SCSI and USB Microtek in kernel config */ // { USB_DEVICE(0x05da, 0x0099) }, /* ScanMaker X6 - X6U */ // { USB_DEVICE(0x05da, 0x0094) }, /* Phantom 336CX - C3 */ // { USB_DEVICE(0x05da, 0x00a0) }, /* Phantom 336CX - C3 #2 */ @@ -146,58 +163,59 @@ // { USB_DEVICE(0x05da, 0x80a3) }, /* ScanMaker V6USL #2 */ // { USB_DEVICE(0x05da, 0x80ac) }, /* ScanMaker V6UL - SpicyU */ /* Minolta */ - // { USB_DEVICE(0x0638,0x026a) }, /* Minolta Dimage Scan Dual II */ - // { USB_DEVICE(0x0686, 0x4004) }, /* Scan Elite II (need interrupt ep) */ { USB_DEVICE(0x0686, 0x400d) }, /* Scan Dual III */ + /* The following SCSI-over-USB Minolta devices are supported by the + hpusbscsi driver: Enable SCSI and USB hpusbscsi in kernel config */ + // { USB_DEVICE(0x0638, 0x026a) }, /* Minolta Dimage Scan Dual II */ + // { USB_DEVICE(0x0686, 0x4004) }, /* Scan Elite II (need interrupt ep) */ /* Mustek */ + { USB_DEVICE(0x0400, 0x1000) }, /* BearPaw 1200 (National Semiconductor LM9831) */ + { USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 (National Semiconductor LM9832) */ { USB_DEVICE(0x055f, 0x0001) }, /* ScanExpress 1200 CU */ - { USB_DEVICE(0x0400, 0x1000) }, /* BearPaw 1200 */ { USB_DEVICE(0x055f, 0x0002) }, /* ScanExpress 600 CU */ - { USB_DEVICE(0x055f, 0x0873) }, /* ScanExpress 600 USB */ { USB_DEVICE(0x055f, 0x0003) }, /* ScanExpress 1200 USB */ { USB_DEVICE(0x055f, 0x0006) }, /* ScanExpress 1200 UB */ { USB_DEVICE(0x055f, 0x0007) }, /* ScanExpress 1200 USB Plus */ - { USB_DEVICE(0x055f, 0x0210) }, /* ScanExpress A3 USB */ - { USB_DEVICE(0x0400, 0x1001) }, /* BearPaw 2400 */ { USB_DEVICE(0x055f, 0x0008) }, /* ScanExpress 1200 CU Plus */ { USB_DEVICE(0x055f, 0x0010) }, /* BearPaw 1200F */ + { USB_DEVICE(0x055f, 0x0210) }, /* ScanExpress A3 USB */ { USB_DEVICE(0x055f, 0x0218) }, /* BearPaw 2400 TA */ - { USB_DEVICE(0x05d8, 0x4002) }, /* BearPaw 1200 CU and ScanExpress 1200 UB Plus */ { USB_DEVICE(0x055f, 0x0219) }, /* BearPaw 2400 TA Plus */ { USB_DEVICE(0x055f, 0x021c) }, /* BearPaw 1200 CU Plus */ { USB_DEVICE(0x055f, 0x021d) }, /* Bearpaw 2400 CU Plus */ { USB_DEVICE(0x055f, 0x021e) }, /* BearPaw 1200 TA/CS */ { USB_DEVICE(0x055f, 0x0400) }, /* BearPaw 2400 TA PRO */ + { USB_DEVICE(0x055f, 0x0873) }, /* ScanExpress 600 USB */ { USB_DEVICE(0x055f, 0x1000) }, /* BearPaw 4800 TA PRO */ + // { USB_DEVICE(0x05d8, 0x4002) }, /* BearPaw 1200 CU and ScanExpress 1200 UB Plus (see Artec) */ /* Nikon */ { USB_DEVICE(0x04b0, 0x4000) }, /* Coolscan LS 40 ED */ /* Plustek */ - { USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/UT24 */ - { USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro U24 */ - { USB_DEVICE(0x07b3, 0x0010) }, /* OpticPro U12 */ - { USB_DEVICE(0x07b3, 0x0015) }, /* OpticPro U24 */ { USB_DEVICE(0x07b3, 0x0005) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0007) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x000F) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0010) }, /* OpticPro U12 */ + { USB_DEVICE(0x07b3, 0x0011) }, /* OpticPro U24 */ { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0013) }, /* Unknown */ { USB_DEVICE(0x07b3, 0x0014) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0015) }, /* OpticPro U24 */ { USB_DEVICE(0x07b3, 0x0016) }, /* Unknown */ - { USB_DEVICE(0x07b3, 0x0012) }, /* Unknown */ + { USB_DEVICE(0x07b3, 0x0017) }, /* OpticPro UT12/UT16/UT24 */ { USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U */ /* Primax/Colorado */ { USB_DEVICE(0x0461, 0x0300) }, /* G2-300 #1 */ - { USB_DEVICE(0x0461, 0x0380) }, /* G2-600 #1 */ { USB_DEVICE(0x0461, 0x0301) }, /* G2E-300 #1 */ - { USB_DEVICE(0x0461, 0x0381) }, /* ReadyScan 636i */ { USB_DEVICE(0x0461, 0x0302) }, /* G2-300 #2 */ - { USB_DEVICE(0x0461, 0x0382) }, /* G2-600 #2 */ { USB_DEVICE(0x0461, 0x0303) }, /* G2E-300 #2 */ - { USB_DEVICE(0x0461, 0x0383) }, /* G2E-600 */ { USB_DEVICE(0x0461, 0x0340) }, /* Colorado USB 9600 */ - // { USB_DEVICE(0x0461, 0x0360) }, /* Colorado USB 19200 - undetected endpoint */ { USB_DEVICE(0x0461, 0x0341) }, /* Colorado 600u */ + { USB_DEVICE(0x0461, 0x0360) }, /* Colorado USB 19200 */ { USB_DEVICE(0x0461, 0x0361) }, /* Colorado 1200u */ + { USB_DEVICE(0x0461, 0x0380) }, /* G2-600 #1 */ + { USB_DEVICE(0x0461, 0x0381) }, /* ReadyScan 636i */ + { USB_DEVICE(0x0461, 0x0382) }, /* G2-600 #2 */ + { USB_DEVICE(0x0461, 0x0383) }, /* G2E-600 */ /* Relisis */ // { USB_DEVICE(0x0475, 0x0103) }, /* Episode - undetected endpoint */ /* Seiko/Epson Corp. */ @@ -221,17 +239,18 @@ { USB_DEVICE(0x04b8, 0x011c) }, /* Perfection 3200 */ { USB_DEVICE(0x04b8, 0x011d) }, /* Perfection 1260 */ { USB_DEVICE(0x04b8, 0x011e) }, /* Perfection 1660 Photo */ + { USB_DEVICE(0x04b8, 0x0801) }, /* Stylus CX5200 */ { USB_DEVICE(0x04b8, 0x0802) }, /* Stylus CX3200 */ /* Umax */ { USB_DEVICE(0x1606, 0x0010) }, /* Astra 1220U */ { USB_DEVICE(0x1606, 0x0030) }, /* Astra 2000U */ { USB_DEVICE(0x1606, 0x0060) }, /* Astra 3400U/3450U */ { USB_DEVICE(0x1606, 0x0130) }, /* Astra 2100U */ - { USB_DEVICE(0x1606, 0x0160) }, /* Astra 5400U */ + { USB_DEVICE(0x1606, 0x0160) }, /* Astra 5400U */ { USB_DEVICE(0x1606, 0x0230) }, /* Astra 2200U */ /* Visioneer */ - { USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */ { USB_DEVICE(0x04a7, 0x0211) }, /* OneTouch 7600 USB */ + { USB_DEVICE(0x04a7, 0x0221) }, /* OneTouch 5300 USB */ { USB_DEVICE(0x04a7, 0x0231) }, /* 6100 USB */ { USB_DEVICE(0x04a7, 0x0311) }, /* 6200 EPP/USB */ { USB_DEVICE(0x04a7, 0x0321) }, /* OneTouch 8100 EPP/USB */ diff -Nru a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig --- a/drivers/usb/input/Kconfig Sun Feb 9 21:13:34 2003 +++ b/drivers/usb/input/Kconfig Sun Feb 9 21:13:34 2003 @@ -22,7 +22,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called hid.o. If you want to compile it as a + The module will be called hid. If you want to compile it as a module, say M here and read . comment "Input core support is needed for USB HID input layer or HIDBP support" @@ -98,7 +98,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usbkbd.o. If you want to compile it as a + The module will be called usbkbd. If you want to compile it as a module, say M here and read . If even remotely unsure, say N. @@ -116,7 +116,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usbmouse.o. If you want to compile it as + The module will be called usbmouse. If you want to compile it as a module, say M here and read . If even remotely unsure, say N. @@ -134,7 +134,7 @@ 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 will be called aiptek.o. If you want to compile it as a + The module will be called aiptek. If you want to compile it as a module, say M here and read . config USB_WACOM @@ -148,7 +148,7 @@ 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 will be called wacom.o. If you want to compile it as a + The module will be called wacom. If you want to compile it as a module, say M here and read . config USB_POWERMATE @@ -165,7 +165,7 @@ 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 will be called powermate.o. If you want to compile it as a + The module will be called powermate. If you want to compile it as a module, say M here and read . config USB_XPAD @@ -181,6 +181,6 @@ 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 will be called xpad.o. If you want to compile it as a + The module will be called xpad. If you want to compile it as a module, say M here and read . diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c --- a/drivers/usb/input/hid-core.c Sun Feb 9 21:13:33 2003 +++ b/drivers/usb/input/hid-core.c Sun Feb 9 21:13:33 2003 @@ -1324,6 +1324,9 @@ #define USB_DEVICE_ID_MGE_UPS 0xffff #define USB_DEVICE_ID_MGE_UPS1 0x0001 +#define USB_VENDOR_ID_ONTRAK 0x0a07 +#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 + struct hid_blacklist { __u16 idVendor; __u16 idProduct; @@ -1359,6 +1362,12 @@ { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_HIDDEV }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_HIDDEV }, { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, + { 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 }, { 0, 0 } }; diff -Nru a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c --- a/drivers/usb/input/pid.c Sun Feb 9 21:13:35 2003 +++ b/drivers/usb/input/pid.c Sun Feb 9 21:13:35 2003 @@ -176,7 +176,7 @@ struct hid_ff_pid* pid_private = (struct hid_ff_pid*)(dev->private); int ret; int is_update; - int flags=0; + unsigned long flags = 0; dev_dbg(&pid_private->hid->dev->dev, "upload effect called: effect_type=%x\n",effect->type); /* Check this effect type is supported by this device */ @@ -192,7 +192,7 @@ int id=0; // Spinlock so we don`t get a race condition when choosing IDs - spin_lock_irqsave(&pid_private->lock,flags); + spin_lock_irqsave(&pid_private->lock, flags); while(id < FF_EFFECTS_MAX) if (!test_and_set_bit(FF_PID_FLAGS_USED, &pid_private->effects[id++].flags)) diff -Nru a/drivers/usb/media/Kconfig b/drivers/usb/media/Kconfig --- a/drivers/usb/media/Kconfig Sun Feb 9 21:13:28 2003 +++ b/drivers/usb/media/Kconfig Sun Feb 9 21:13:28 2003 @@ -16,7 +16,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called dabusb.o. If you want to compile it as a + The module will be called dabusb. If you want to compile it as a module, say M here and read . comment "Video4Linux support is needed for USB Multimedia device support" @@ -35,7 +35,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called vicam.o. If you want to compile it as a + The module will be called vicam. If you want to compile it as a module, say M here and read . config USB_DSBR @@ -55,7 +55,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called dsbr100.o. If you want to compile it as a + The module will be called dsbr100. If you want to compile it as a module, say M here and read . config USB_IBMCAM @@ -74,7 +74,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called ibmcam.o. If you want to compile it as a + The module will be called ibmcam. If you want to compile it as a module, say M here and read . This camera has several configuration options which can be specified when you load the module. Read to @@ -95,7 +95,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called konicawc.o. If you want to compile it as + The module will be called konicawc. If you want to compile it as a module, say M here and read . config USB_OV511 @@ -113,7 +113,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called ov511.o. If you want to compile it as a + The module will be called ov511. If you want to compile it as a module, say M here and read . config USB_PWC @@ -154,7 +154,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called pwc.o. If you want to compile it as a + The module will be called pwc. If you want to compile it as a module, say M here and read . config USB_SE401 @@ -172,7 +172,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called se401.o. If you want to compile it as a + The module will be called se401. If you want to compile it as a module, say M here and read . config USB_STV680 @@ -191,6 +191,6 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called stv680.o. If you want to compile it as a + The module will be called stv680. If you want to compile it as a module, say M here and read . diff -Nru a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile --- a/drivers/usb/media/Makefile Sun Feb 9 21:13:28 2003 +++ b/drivers/usb/media/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for USB Media drivers # -export-objs := ov511.o pwc-uncompress.o usbvideo.o - pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o obj-$(CONFIG_USB_DABUSB) += dabusb.o diff -Nru a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c --- a/drivers/usb/media/usbvideo.c Sun Feb 9 21:13:37 2003 +++ b/drivers/usb/media/usbvideo.c Sun Feb 9 21:13:37 2003 @@ -61,7 +61,7 @@ unsigned int cmd, unsigned long arg); static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma); static int usbvideo_v4l_open(struct inode *inode, struct file *file); -static int usbvideo_v4l_read(struct file *file, char *buf, +static ssize_t usbvideo_v4l_read(struct file *file, char *buf, size_t count, loff_t *ppos); static int usbvideo_v4l_close(struct inode *inode, struct file *file); @@ -1641,7 +1641,7 @@ * 20-Oct-2000 Created. * 01-Nov-2000 Added mutex (uvd->lock). */ -static int usbvideo_v4l_read(struct file *file, char *buf, +static ssize_t usbvideo_v4l_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct uvd *uvd = file->private_data; diff -Nru a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c --- a/drivers/usb/media/vicam.c Sun Feb 9 21:13:30 2003 +++ b/drivers/usb/media/vicam.c Sun Feb 9 21:13:30 2003 @@ -988,7 +988,7 @@ up(&cam->cam_lock); } -static int +static ssize_t vicam_read( struct file *file, char *buf, size_t count, loff_t *ppos ) { struct vicam_camera *cam = file->private_data; diff -Nru a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig --- a/drivers/usb/misc/Kconfig Sun Feb 9 21:13:36 2003 +++ b/drivers/usb/misc/Kconfig Sun Feb 9 21:13:36 2003 @@ -16,7 +16,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called audio.o. If you want to compile it as a + The module will be called audio. If you want to compile it as a module, say M here and read . config USB_TIGL @@ -32,7 +32,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called tiglusb.o. If you want to compile it as a + The module will be called tiglusb. If you want to compile it as a module, say M here and read Documentation/modules.txt. If you don't know what the SilverLink cable is or what a Texas @@ -50,7 +50,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called auerswald.o. If you want to compile it as + The module will be called auerswald. If you want to compile it as a module, say M here and read . config USB_RIO500 @@ -63,7 +63,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called rio500.o. If you want to compile it as + The module will be called rio500. If you want to compile it as a module, say M here and read . config USB_BRLVGER @@ -76,7 +76,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called brlvger.o. If you want to compile it as + The module will be called brlvger. If you want to compile it as a module, say M here and read . config USB_LCD @@ -90,7 +90,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usblcd.o. If you want to compile it as + The module will be called usblcd. If you want to compile it as a module, say M here and read . config USB_SPEEDTOUCH diff -Nru a/drivers/usb/misc/atmsar.c b/drivers/usb/misc/atmsar.c --- a/drivers/usb/misc/atmsar.c Sun Feb 9 21:13:30 2003 +++ b/drivers/usb/misc/atmsar.c Sun Feb 9 21:13:30 2003 @@ -45,7 +45,7 @@ * - No more in-buffer rewriting for cloned buffers. * - Removed the PII specific CFLAGS in the Makefile. * - * 0.2.1: - removed dependancy on alloc_tx. tis presented problems when + * 0.2.1: - removed dependency on alloc_tx. tis presented problems when * using this with the br2684 code. * * 0.2: - added AAL0 reassembly @@ -381,6 +381,83 @@ ** ***********************/ +/* encapsulate in an AAL5 frame, which is then split into ATM cells */ +unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target, unsigned int pdu_length) +{ + unsigned int num_cells = (pdu_length + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD; + unsigned int num_pdu_cells = pdu_length / ATM_CELL_PAYLOAD + 1; + unsigned int aal5_length = num_cells * ATM_CELL_PAYLOAD; + unsigned int zero_padding = aal5_length - pdu_length - ATM_AAL5_TRAILER; + unsigned int final_length = num_cells * ATM_CELL_SIZE; + unsigned char aal5_trailer [ATM_AAL5_TRAILER]; + unsigned char cell_header [ATM_CELL_HEADER]; + u32 crc; + int i; + + PDEBUG ("atmsar_encode entered\n"); + + PDEBUG ("pdu_length %d, num_cells %d, num_pdu_cells %d, aal5_length %d, zero_padding %d, final_length %d\n", pdu_length, num_cells, num_pdu_cells, aal5_length, zero_padding, final_length); + + PDEBUG ("source 0x=%p, target 0x%p\n", source, target); + + aal5_trailer [0] = 0; /* UU = 0 */ + aal5_trailer [1] = 0; /* CPI = 0 */ + aal5_trailer [2] = pdu_length >> 8; + aal5_trailer [3] = pdu_length; + + crc = crc32 (~0, source, pdu_length); + for (i = 0; i < zero_padding; i++) + crc = CRC32 (0, crc); + crc = crc32 (crc, aal5_trailer, 4); + crc = ~crc; + + aal5_trailer [4] = crc >> 24; + aal5_trailer [5] = crc >> 16; + aal5_trailer [6] = crc >> 8; + aal5_trailer [7] = crc; + + cell_header [0] = ctx->atmHeader >> 24; + cell_header [1] = ctx->atmHeader >> 16; + cell_header [2] = ctx->atmHeader >> 8; + cell_header [3] = ctx->atmHeader; + cell_header [4] = 0xec; + + for (i = 1; i < num_pdu_cells; i++) { + memcpy (target, cell_header, ATM_CELL_HEADER); + target += ATM_CELL_HEADER; + memcpy (target, source, ATM_CELL_PAYLOAD); + target += ATM_CELL_PAYLOAD; + source += ATM_CELL_PAYLOAD; + PDEBUG ("source 0x=%p, target 0x%p\n", source, target); + } + memcpy (target, cell_header, ATM_CELL_HEADER); + target += ATM_CELL_HEADER; + memcpy (target, source, pdu_length % ATM_CELL_PAYLOAD); + target += pdu_length % ATM_CELL_PAYLOAD; + if (num_pdu_cells < num_cells) { + memset (target, 0, zero_padding + ATM_AAL5_TRAILER - ATM_CELL_PAYLOAD); + target += zero_padding + ATM_AAL5_TRAILER - ATM_CELL_PAYLOAD; + memcpy (target, cell_header, ATM_CELL_HEADER); + target += ATM_CELL_HEADER; + zero_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER; + } + memset (target, 0, zero_padding); + target += zero_padding; + memcpy (target, aal5_trailer, ATM_AAL5_TRAILER); + + /* set pti bit in last cell */ + *(target + ATM_AAL5_TRAILER + 3 - ATM_CELL_SIZE) |= 0x2; + + /* update stats */ + if (ctx->stats) + atomic_inc (&ctx->stats->tx); + + if (ctx->stats && (ctx->type <= ATMSAR_TYPE_AAL1)) + atomic_add (num_cells, &(ctx->stats->tx)); + + return final_length; +} + struct sk_buff *atmsar_encode_rawcell (struct atmsar_vcc_data *ctx, struct sk_buff *skb) { int number_of_cells = (skb->len) / 48; @@ -624,9 +701,8 @@ } else { /* If data is corrupt and skb doesn't hold a whole cell, flush the lot */ if (skb_pull (skb, (list->flags & ATMSAR_USE_53BYTE_CELL ? 53 : 52)) == - NULL) { - skb_trim (skb, 0); - } + NULL) + return NULL; } } diff -Nru a/drivers/usb/misc/atmsar.h b/drivers/usb/misc/atmsar.h --- a/drivers/usb/misc/atmsar.h Sun Feb 9 21:13:31 2003 +++ b/drivers/usb/misc/atmsar.h Sun Feb 9 21:13:31 2003 @@ -33,6 +33,7 @@ #define ATMSAR_USE_53BYTE_CELL 0x1L #define ATMSAR_SET_PTI 0x2L +#define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD) /* types */ #define ATMSAR_TYPE_AAL0 ATM_AAL0 @@ -88,5 +89,7 @@ struct sk_buff *atmsar_decode_aal5 (struct atmsar_vcc_data *ctx, struct sk_buff *skb); struct sk_buff *atmsar_alloc_tx (struct atmsar_vcc_data *vcc, unsigned int size); + +unsigned int atmsar_encode (struct atmsar_vcc_data *ctx, char *source, char *target, unsigned int pdu_length); #endif /* _ATMSAR_H_ */ diff -Nru a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c --- a/drivers/usb/misc/speedtouch.c Sun Feb 9 21:13:37 2003 +++ b/drivers/usb/misc/speedtouch.c Sun Feb 9 21:13:37 2003 @@ -46,6 +46,7 @@ * */ +#include #include #include #include @@ -58,7 +59,6 @@ #include #include #include - #include #include #include "atmsar.h" @@ -106,20 +106,21 @@ #define UDSL_ENDPOINT_DATA_OUT 0x07 #define UDSL_ENDPOINT_DATA_IN 0x87 +#define hex2int(c) ( (c >= '0')&&(c <= '9') ? (c - '0') : ((c & 0xf)+9) ) + /* usb_device_id struct */ -static struct usb_device_id udsl_usb_ids[] = { - {USB_DEVICE (SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID)}, - {} /* list terminator */ +static struct usb_device_id udsl_usb_ids [] = { + { USB_DEVICE (SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID) }, + { } /* Terminating entry */ }; -/* not exporting this prevents the depmod from generating the map that causes the modules to be isnserted as driver. - * we do not want this, we want the script run. -MODULE_DEVICE_TABLE ( usb, udsl_usb_ids); -*/ +MODULE_DEVICE_TABLE (usb, udsl_usb_ids); + /* context declarations */ -struct udsl_data_ctx { +struct udsl_receiver { + struct list_head list; struct sk_buff *skb; struct urb *urb; struct udsl_instance_data *instance; @@ -137,25 +138,32 @@ */ struct udsl_instance_data { - struct tasklet_struct recvqueue_tasklet; + struct semaphore serialize; /* usb device part */ struct usb_device *usb_dev; - struct udsl_data_ctx *rcvbufs; struct sk_buff_head sndqueue; - struct udsl_usb_send_data_context send_ctx[UDSL_NUMBER_SND_URBS]; - int data_started; + struct udsl_usb_send_data_context send_ctx [UDSL_NUMBER_SND_URBS]; + int firmware_loaded; /* atm device part */ struct atm_dev *atm_dev; - struct sk_buff_head recvqueue; struct atmsar_vcc_data *atmsar_vcc_list; -}; -static const char udsl_driver_name[] = "Alcatel SpeedTouch USB"; + /* receiving */ + struct udsl_receiver all_receivers [UDSL_NUMBER_RCV_URBS]; + + spinlock_t spare_receivers_lock; + struct list_head spare_receivers; + + spinlock_t completed_receivers_lock; + struct list_head completed_receivers; + + struct tasklet_struct receive_tasklet; +}; -static DECLARE_MUTEX(udsl_usb_ioctl_lock); +static const char udsl_driver_name [] = "Alcatel SpeedTouch USB"; #ifdef DEBUG_PACKET static int udsl_print_packet (const unsigned char *data, int len); @@ -169,8 +177,7 @@ static void udsl_atm_close (struct atm_vcc *vcc); static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg); static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb); -static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page); -static void udsl_atm_processqueue (unsigned long data); +static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page); static struct atmdev_ops udsl_atm_devops = { .open = udsl_atm_open, @@ -203,6 +210,170 @@ .id_table = udsl_usb_ids, }; + +/************** +** receive ** +**************/ + +static void udsl_complete_receive (struct urb *urb, struct pt_regs *regs) +{ + struct udsl_instance_data *instance; + struct udsl_receiver *rcv; + unsigned long flags; + + PDEBUG ("udsl_complete_receive entered\n"); + + if (!urb || !(rcv = urb->context) || !(instance = rcv->instance)) { + PDEBUG ("udsl_complete_receive: bad urb!\n"); + return; + } + + /* may not be in_interrupt() */ + spin_lock_irqsave (&instance->completed_receivers_lock, flags); + list_add_tail (&rcv->list, &instance->completed_receivers); + spin_unlock_irqrestore (&instance->completed_receivers_lock, flags); + PDEBUG ("udsl_complete_receive: scheduling tasklet\n"); + tasklet_schedule (&instance->receive_tasklet); +} + +static void udsl_process_receive (unsigned long data) +{ + struct udsl_instance_data *instance = (struct udsl_instance_data *) data; + struct udsl_receiver *rcv; + unsigned long flags; + unsigned char *data_start; + struct sk_buff *skb; + struct urb *urb; + struct atmsar_vcc_data *atmsar_vcc = NULL; + struct sk_buff *new = NULL, *tmp = NULL; + + PDEBUG ("udsl_process_receive entered\n"); + + spin_lock_irqsave (&instance->completed_receivers_lock, flags); + while (!list_empty (&instance->completed_receivers)) { + rcv = list_entry (instance->completed_receivers.next, struct udsl_receiver, list); + list_del (&rcv->list); + spin_unlock_irqrestore (&instance->completed_receivers_lock, flags); + + urb = rcv->urb; + PDEBUG ("udsl_process_receive: got packet %p with length %d and status %d\n", urb, urb->actual_length, urb->status); + + switch (urb->status) { + case 0: + PDEBUG ("udsl_process_receive: processing urb with rcv %p, urb %p, skb %p\n", rcv, urb, rcv->skb); + + /* update the skb structure */ + skb = rcv->skb; + skb_trim (skb, 0); + skb_put (skb, urb->actual_length); + data_start = skb->data; + + PDEBUG ("skb->len = %d\n", skb->len); + PACKETDEBUG (skb->data, skb->len); + + while ((new = + atmsar_decode_rawcell (instance->atmsar_vcc_list, skb, + &atmsar_vcc)) != NULL) { + PDEBUG ("(after cell processing)skb->len = %d\n", new->len); + + switch (atmsar_vcc->type) { + case ATMSAR_TYPE_AAL5: + tmp = new; + new = atmsar_decode_aal5 (atmsar_vcc, new); + + /* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */ + if (new) { + PDEBUG ("(after aal5 decap) skb->len = %d\n", new->len); + if (new->len && atm_charge (atmsar_vcc->vcc, new->truesize)) { + PACKETDEBUG (new->data, new->len); + atmsar_vcc->vcc->push (atmsar_vcc->vcc, new); + } else { + PDEBUG + ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d\n", + atomic_read (&atmsar_vcc->vcc->rx_inuse), + atmsar_vcc->vcc->sk->rcvbuf, new->truesize); + dev_kfree_skb (new); + } + } else { + PDEBUG ("atmsar_decode_aal5 returned NULL!\n"); + dev_kfree_skb (tmp); + } + break; + default: + /* not supported. we delete the skb. */ + printk (KERN_INFO + "SpeedTouch USB: illegal vcc type. Dropping packet.\n"); + dev_kfree_skb (new); + break; + } + } + + /* restore skb */ + skb_push (skb, skb->data - data_start); + + usb_fill_bulk_urb (urb, + instance->usb_dev, + usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN), + (unsigned char *) rcv->skb->data, + UDSL_RECEIVE_BUFFER_SIZE, + udsl_complete_receive, + rcv); + if (!usb_submit_urb (urb, GFP_ATOMIC)) + break; + PDEBUG ("udsl_process_receive: submission failed\n"); + /* fall through */ + default: /* error or urb unlinked */ + PDEBUG ("udsl_process_receive: adding to spare_receivers\n"); + spin_lock_irqsave (&instance->spare_receivers_lock, flags); + list_add (&rcv->list, &instance->spare_receivers); + spin_unlock_irqrestore (&instance->spare_receivers_lock, flags); + break; + } /* switch */ + + spin_lock_irqsave (&instance->completed_receivers_lock, flags); + } /* while */ + spin_unlock_irqrestore (&instance->completed_receivers_lock, flags); + PDEBUG ("udsl_process_receive successful\n"); +} + +static void udsl_fire_receivers (struct udsl_instance_data *instance) +{ + struct list_head receivers, *pos, *n; + unsigned long flags; + + INIT_LIST_HEAD (&receivers); + + down (&instance->serialize); + + spin_lock_irqsave (&instance->spare_receivers_lock, flags); + list_splice_init (&instance->spare_receivers, &receivers); + spin_unlock_irqrestore (&instance->spare_receivers_lock, flags); + + list_for_each_safe (pos, n, &receivers) { + struct udsl_receiver *rcv = list_entry (pos, struct udsl_receiver, list); + + PDEBUG ("udsl_fire_receivers: firing urb %p\n", rcv->urb); + + usb_fill_bulk_urb (rcv->urb, + instance->usb_dev, + usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN), + (unsigned char *) rcv->skb->data, + UDSL_RECEIVE_BUFFER_SIZE, + udsl_complete_receive, + rcv); + + if (usb_submit_urb (rcv->urb, GFP_KERNEL) < 0) { + PDEBUG ("udsl_fire_receivers: submit failed!\n"); + spin_lock_irqsave (&instance->spare_receivers_lock, flags); + list_move (pos, &instance->spare_receivers); + spin_unlock_irqrestore (&instance->spare_receivers_lock, flags); + } + } + + up (&instance->serialize); +} + + /************ ** ATM ** ************/ @@ -213,27 +384,9 @@ * ****************************************************************************/ -static struct atm_dev *udsl_atm_startdevice (struct udsl_instance_data *instance, struct atmdev_ops *devops) -{ - MOD_INC_USE_COUNT; - instance->atm_dev = atm_dev_register (udsl_driver_name, devops, -1, 0); - instance->atm_dev->dev_data = instance; - instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX; - instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX; - instance->atm_dev->signal = ATM_PHY_SIG_LOST; - - skb_queue_head_init (&instance->recvqueue); - - /* tmp init atm device, set to 128kbit */ - instance->atm_dev->link_rate = 128 * 1000 / 424; - - return instance->atm_dev; -} - static void udsl_atm_stopdevice (struct udsl_instance_data *instance) { struct atm_vcc *walk; - struct sk_buff *skb; struct atm_dev *atm_dev; if (!instance->atm_dev) @@ -241,10 +394,6 @@ atm_dev = instance->atm_dev; - /* clean queue */ - while ((skb = skb_dequeue (&instance->recvqueue))) - dev_kfree_skb (skb); - atm_dev->signal = ATM_PHY_SIG_LOST; walk = atm_dev->vccs; shutdown_atm_dev (atm_dev); @@ -253,16 +402,8 @@ wake_up (&walk->sleep); instance->atm_dev = NULL; - MOD_DEC_USE_COUNT; } -static void udsl_atm_set_mac (struct udsl_instance_data *instance, const char mac[6]) -{ - if (!instance->atm_dev) - return; - - memcpy (instance->atm_dev->esi, mac, 6); -} /*************************************************************************** * @@ -281,11 +422,16 @@ return NULL; } -static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page) +static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t *pos, char *page) { struct udsl_instance_data *instance = atm_dev->dev_data; int left = *pos; + if (!instance) { + PDEBUG ("NULL instance!\n"); + return -ENODEV; + } + if (!left--) return sprintf (page, "SpeedTouch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)\n", instance->usb_dev->bus->bus_name, instance->usb_dev->devpath, @@ -311,6 +457,7 @@ return 0; } + /*************************************************************************** * * ATM DATA functions @@ -325,8 +472,13 @@ PDEBUG ("udsl_atm_send called\n"); - if (!dev_data) + if (!dev_data || !instance) { + PDEBUG ("NULL data!\n"); return -EINVAL; + } + + if (!instance->firmware_loaded) + return -EAGAIN; switch (vcc->qos.aal) { case ATM_AAL5: @@ -350,67 +502,13 @@ break; default: return -EINVAL; - }; + } PDEBUG ("udsl_atm_send unsuccessfull\n"); return 0; nomem: vcc->pop (vcc, skb); return -ENOMEM; -}; - - -static void udsl_atm_processqueue (unsigned long data) -{ - struct udsl_instance_data *instance = (struct udsl_instance_data *) data; - struct atmsar_vcc_data *atmsar_vcc = NULL; - struct sk_buff *new = NULL, *skb = NULL, *tmp = NULL; - - PDEBUG ("udsl_atm_processqueue entered\n"); - - while ((skb = skb_dequeue (&instance->recvqueue))) { - PDEBUG ("skb = %p, skb->len = %d\n", skb, skb->len); - PACKETDEBUG (skb->data, skb->len); - - while ((new = - atmsar_decode_rawcell (instance->atmsar_vcc_list, skb, - &atmsar_vcc)) != NULL) { - PDEBUG ("(after cell processing)skb->len = %d\n", new->len); - switch (atmsar_vcc->type) { - case ATMSAR_TYPE_AAL5: - tmp = new; - new = atmsar_decode_aal5 (atmsar_vcc, new); - - /* we can't send NULL skbs upstream, the ATM layer would try to close the vcc... */ - if (new) { - PDEBUG ("(after aal5 decap) skb->len = %d\n", new->len); - if (new->len && atm_charge (atmsar_vcc->vcc, new->truesize)) { - PACKETDEBUG (new->data, new->len); - atmsar_vcc->vcc->push (atmsar_vcc->vcc, new); - } else { - PDEBUG - ("dropping incoming packet : rx_inuse = %d, vcc->sk->rcvbuf = %d, skb->true_size = %d\n", - atomic_read (&atmsar_vcc->vcc->rx_inuse), - atmsar_vcc->vcc->sk->rcvbuf, new->truesize); - dev_kfree_skb (new); - } - } else { - PDEBUG ("atmsar_decode_aal5 returned NULL!\n"); - dev_kfree_skb (tmp); - } - break; - default: - /* not supported. we delete the skb. */ - printk (KERN_INFO - "SpeedTouch USB: illegal vcc type. Dropping packet.\n"); - dev_kfree_skb (new); - break; - } - }; - dev_kfree_skb (skb); - }; - - PDEBUG ("udsl_atm_processqueue successfull\n"); } @@ -419,6 +517,7 @@ * SAR driver entries * ****************************************************************************/ + static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) { struct udsl_atm_dev_data *dev_data; @@ -426,6 +525,11 @@ PDEBUG ("udsl_atm_open called\n"); + if (!instance) { + PDEBUG ("NULL instance!\n"); + return -ENODEV; + } + /* at the moment only AAL5 support */ if (vcc->qos.aal != ATM_AAL5) return -EINVAL; @@ -453,6 +557,9 @@ dev_data->atmsar_vcc->mtu = UDSL_MAX_AAL5_MRU; + if (instance->firmware_loaded) + udsl_fire_receivers (instance); + PDEBUG ("udsl_atm_open successfull\n"); return 0; } @@ -464,6 +571,11 @@ PDEBUG ("udsl_atm_close called\n"); + if (!dev_data || !instance) { + PDEBUG ("NULL data!\n"); + return; + } + /* freeing resources */ /* cancel all sends on this vcc */ udsl_usb_cancelsends (instance, vcc); @@ -482,7 +594,7 @@ PDEBUG ("udsl_atm_close successfull\n"); return; -}; +} static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg) { @@ -492,7 +604,7 @@ default: return -ENOIOCTLCMD; } -}; +} /************ @@ -566,9 +678,6 @@ PDEBUG ("udsl_usb_send_data entered, sending packet %p with length %d\n", skb, skb->len); - if (!instance->data_started) - return -EAGAIN; - PACKETDEBUG (skb->data, skb->len); spin_lock_irqsave (&instance->sndqueue.lock, flags); @@ -592,7 +701,7 @@ spin_unlock_irqrestore (&instance->sndqueue.lock, flags); PDEBUG ("udsl_usb_send_data: skb (0x%p) queued\n", skb); return 0; - }; + } /* init context */ urb = instance->send_ctx[i].urb; @@ -620,285 +729,264 @@ return err; } -/********* receive *******/ -static void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs) -{ - struct udsl_data_ctx *ctx; - struct udsl_instance_data *instance; - if (!urb) - return; +/*************************************************************************** +* +* usb driver entries +* +****************************************************************************/ - PDEBUG ("udsl_usb_receive_data entered, got packet %p with length %d an status %d\n", urb, - urb->actual_length, urb->status); +static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data) +{ + struct udsl_instance_data *instance = usb_get_intfdata (intf); - ctx = urb->context; - if (!ctx || !ctx->skb) - return; + PDEBUG ("udsl_usb_ioctl entered\n"); - instance = ctx->instance; + if (!instance) { + PDEBUG ("NULL instance!\n"); + return -ENODEV; + } - switch (urb->status) { - case 0: - PDEBUG ("udsl_usb_data_receive: processing urb with ctx %p, urb %p (%p), skb %p\n", - ctx, ctx ? ctx->urb : NULL, urb, ctx ? ctx->skb : NULL); - /* update the skb structure */ - skb_put (ctx->skb, urb->actual_length); - - /* queue the skb for processing and wake the SAR */ - skb_queue_tail (&instance->recvqueue, ctx->skb); - tasklet_schedule (&instance->recvqueue_tasklet); - /* get a new skb */ - ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE); - if (!ctx->skb) { - PDEBUG ("No skb, loosing urb.\n"); - usb_free_urb (ctx->urb); - ctx->urb = NULL; - return; + switch (code) { + case UDSL_IOCTL_START: + instance->atm_dev->signal = ATM_PHY_SIG_FOUND; + down (&instance->serialize); /* vs self */ + if (!instance->firmware_loaded) { + usb_set_interface (instance->usb_dev, 1, 2); + instance->firmware_loaded = 1; } - break; - case -ENOENT: /* buffer was unlinked */ - case -EILSEQ: /* unplug or timeout */ - case -ETIMEDOUT: /* unplug or timeout */ - /* - * we don't do anything here and we don't resubmit - */ - return; + up (&instance->serialize); + udsl_fire_receivers (instance); + return 0; + case UDSL_IOCTL_STOP: + instance->atm_dev->signal = ATM_PHY_SIG_LOST; + return 0; + default: + return -ENOTTY; } +} - usb_fill_bulk_urb (urb, - instance->usb_dev, - usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN), - (unsigned char *) ctx->skb->data, - UDSL_RECEIVE_BUFFER_SIZE, udsl_usb_data_receive, ctx); - usb_submit_urb (urb, GFP_ATOMIC); - return; -}; - -static int udsl_usb_data_init (struct udsl_instance_data *instance) +static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id) { - int i, succes; + struct usb_device *dev = interface_to_usbdev(intf); + int ifnum = intf->altsetting->desc.bInterfaceNumber; + struct udsl_instance_data *instance; + unsigned char mac_str [13]; + unsigned char mac [6]; + int i, err; - if (instance->data_started) - return 1; + PDEBUG ("Trying device with Vendor=0x%x, Product=0x%x, ifnum %d\n", + dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum); - /* set alternate setting 1 on interface 1 */ - usb_set_interface (instance->usb_dev, 1, 2); + if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || + (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) || + (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1)) + return -ENODEV; - PDEBUG ("max packet size on endpoint %d is %d\n", UDSL_ENDPOINT_DATA_OUT, - usb_maxpacket (instance->usb_dev, - usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), 0)); + PDEBUG ("Device Accepted\n"); - instance->rcvbufs = kmalloc (sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS, GFP_KERNEL); - if (!instance->rcvbufs) - return -ENOMEM; + /* instance init */ + if (!(instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL))) { + PDEBUG ("No memory for Instance data!\n"); + err = -ENOMEM; + goto fail_instance; + } - memset (instance->rcvbufs, 0, sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS); + memset (instance, 0, sizeof (struct udsl_instance_data)); - skb_queue_head_init (&instance->sndqueue); + init_MUTEX (&instance->serialize); - for (i = 0, succes = 0; i < UDSL_NUMBER_RCV_URBS; i++) { - struct udsl_data_ctx *ctx = &(instance->rcvbufs[i]); + instance->usb_dev = dev; - ctx->urb = NULL; - ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE); - if (!ctx->skb) - continue; + spin_lock_init (&instance->spare_receivers_lock); + INIT_LIST_HEAD (&instance->spare_receivers); - ctx->urb = usb_alloc_urb (0, GFP_KERNEL); - if (!ctx->urb) { - kfree_skb (ctx->skb); - ctx->skb = NULL; - break; - }; + spin_lock_init (&instance->completed_receivers_lock); + INIT_LIST_HEAD (&instance->completed_receivers); - usb_fill_bulk_urb (ctx->urb, - instance->usb_dev, - usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN), - (unsigned char *) ctx->skb->data, - UDSL_RECEIVE_BUFFER_SIZE, - udsl_usb_data_receive, ctx); + tasklet_init (&instance->receive_tasklet, udsl_process_receive, (unsigned long) instance); + skb_queue_head_init (&instance->sndqueue); - ctx->instance = instance; + /* receive urb init */ + for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) { + struct udsl_receiver *rcv = &(instance->all_receivers[i]); - PDEBUG ("udsl_usb_data_init: usb with skb->truesize = %d (Asked for %d)\n", - ctx->skb->truesize, UDSL_RECEIVE_BUFFER_SIZE); + if (!(rcv->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE))) { + PDEBUG ("No memory for skb %d!\n", i); + err = -ENOMEM; + goto fail_urbs; + } - if (usb_submit_urb (ctx->urb, GFP_KERNEL) < 0) - PDEBUG ("udsl_usb_data_init: Submit failed, loosing urb.\n"); - else - succes++; - } + if (!(rcv->urb = usb_alloc_urb (0, GFP_KERNEL))) { + PDEBUG ("No memory for receive urb %d!\n", i); + err = -ENOMEM; + goto fail_urbs; + } + + rcv->instance = instance; - PDEBUG ("udsl_usb_data_init %d urb%s queued for receive\n", succes, - (succes != 1) ? "s" : ""); + list_add (&rcv->list, &instance->spare_receivers); - for (i = 0, succes = 0; i < UDSL_NUMBER_SND_URBS; i++) { - instance->send_ctx[i].urb = usb_alloc_urb (0, GFP_KERNEL); - PDEBUG ("udsl_usb_data_init: send urb allocted address %p\n", - instance->send_ctx[i].urb); - if (instance->send_ctx[i].urb) - succes++; + PDEBUG ("skb->truesize = %d (asked for %d)\n", rcv->skb->truesize, UDSL_RECEIVE_BUFFER_SIZE); } - PDEBUG ("udsl_usb_data_init %d urb%s queued for send\n", succes, (succes != 1) ? "s" : ""); + for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) { + struct udsl_usb_send_data_context *snd = &(instance->send_ctx[i]); - instance->data_started = 1; - instance->atm_dev->signal = ATM_PHY_SIG_FOUND; + if (!(snd->urb = usb_alloc_urb (0, GFP_KERNEL))) { + PDEBUG ("No memory for send urb %d!\n", i); + err = -ENOMEM; + goto fail_urbs; + } - return 0; -} + snd->instance = instance; + } -static int udsl_usb_data_exit (struct udsl_instance_data *instance) -{ - int i; + /* atm init */ + if (!(instance->atm_dev = atm_dev_register (udsl_driver_name, &udsl_atm_devops, -1, 0))) { + PDEBUG ("failed to register ATM device!\n"); + err = -ENOMEM; + goto fail_atm; + } - if (!instance->data_started) - return 0; + instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX; + instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX; + instance->atm_dev->signal = ATM_PHY_SIG_LOST; - if (!instance->rcvbufs) - return 0; + /* tmp init atm device, set to 128kbit */ + instance->atm_dev->link_rate = 128 * 1000 / 424; - /* destroy urbs */ - for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) { - struct udsl_data_ctx *ctx = &(instance->rcvbufs[i]); + /* set MAC address, it is stored in the serial number */ + usb_string (instance->usb_dev, instance->usb_dev->descriptor.iSerialNumber, mac_str, 13); + for (i = 0; i < 6; i++) + mac[i] = (hex2int (mac_str[i * 2]) * 16) + (hex2int (mac_str[i * 2 + 1])); - if ((!ctx->urb) || (!ctx->skb)) - continue; + PDEBUG ("MAC is %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - usb_unlink_urb (ctx->urb); + memcpy (instance->atm_dev->esi, mac, 6); - usb_free_urb (ctx->urb); - kfree_skb (ctx->skb); - ctx->skb = NULL; - } + wmb (); - tasklet_kill (&instance->recvqueue_tasklet); + instance->atm_dev->dev_data = instance; + usb_set_intfdata (intf, instance); + + return 0; + +fail_atm: +fail_urbs: for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) { - struct udsl_usb_send_data_context *ctx = &(instance->send_ctx[i]); + struct udsl_usb_send_data_context *snd = &(instance->send_ctx[i]); - usb_unlink_urb (ctx->urb); + if (snd->urb) + usb_free_urb (snd->urb); + } - if (ctx->skb) - ctx->vcc->pop (ctx->vcc, ctx->skb); - ctx->skb = NULL; + for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) { + struct udsl_receiver *rcv = &(instance->all_receivers[i]); - usb_free_urb (ctx->urb); + if (rcv->skb) + kfree_skb (rcv->skb); + if (rcv->urb) + usb_free_urb (rcv->urb); } + kfree (instance); +fail_instance: + return err; +} - /* free receive contexts */ - kfree (instance->rcvbufs); - instance->rcvbufs = NULL; +static void udsl_usb_disconnect (struct usb_interface *intf) +{ + struct udsl_instance_data *instance = usb_get_intfdata (intf); + struct list_head *pos; + unsigned long flags; + unsigned int count = 0; + int i; - instance->data_started = 0; - instance->atm_dev->signal = ATM_PHY_SIG_LOST; + PDEBUG ("disconnecting\n"); - return 0; -}; + usb_set_intfdata (intf, NULL); + if (!instance) { + PDEBUG ("NULL instance!\n"); + return; + } -/*************************************************************************** -* -* usb driver entries -* -****************************************************************************/ -#define hex2int(c) ( (c >= '0')&&(c <= '9') ? (c - '0') : ((c & 0xf)+9) ) + tasklet_disable (&instance->receive_tasklet); + down (&instance->serialize); /* vs udsl_fire_receivers */ + /* no need to take the spinlock - receive_tasklet is not running */ + list_for_each (pos, &instance->spare_receivers) + if (++count > UDSL_NUMBER_RCV_URBS) + panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__); + INIT_LIST_HEAD (&instance->spare_receivers); + up (&instance->serialize); -static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data) -{ - struct udsl_instance_data *instance = usb_get_intfdata (intf); - int retval; + PDEBUG ("udsl_usb_disconnect: flushed %u spare receivers\n", count); - down(&udsl_usb_ioctl_lock); - switch (code) { - case UDSL_IOCTL_START: - retval = udsl_usb_data_init (instance); - break; - case UDSL_IOCTL_STOP: - retval = udsl_usb_data_exit (instance); - break; - default: - retval = -ENOTTY; - break; - } - up(&udsl_usb_ioctl_lock); - return retval; -} + count = UDSL_NUMBER_RCV_URBS - count; -static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); - int ifnum = intf->altsetting->desc.bInterfaceNumber; - int i; - unsigned char mac[6]; - unsigned char mac_str[13]; - struct udsl_instance_data *instance = NULL; + for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) + usb_unlink_urb (instance->all_receivers[i].urb); - PDEBUG ("Trying device with Vendor=0x%x, Product=0x%x, ifnum %d\n", - dev->descriptor.idVendor, dev->descriptor.idProduct, ifnum); + /* wait for completion handlers to finish */ + do { + unsigned int completed = 0; - if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || - (dev->descriptor.idVendor != SPEEDTOUCH_VENDORID) || - (dev->descriptor.idProduct != SPEEDTOUCH_PRODUCTID) || (ifnum != 1)) - return -ENODEV; + spin_lock_irqsave (&instance->completed_receivers_lock, flags); + list_for_each (pos, &instance->completed_receivers) + if (++completed > count) + panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__); + spin_unlock_irqrestore (&instance->completed_receivers_lock, flags); - MOD_INC_USE_COUNT; + PDEBUG ("udsl_usb_disconnect: found %u completed receivers\n", completed); - PDEBUG ("Device Accepted\n"); + if (completed == count) + break; - /* device init */ - instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL); - if (!instance) { - PDEBUG ("No memory for Instance data!\n"); - return -ENOMEM; - } + /* not all urbs completed */ + yield (); + } while (1); + + PDEBUG ("udsl_usb_disconnect: flushing %u completed receivers\n", count); + /* no need to take the spinlock - no completion handlers running */ + INIT_LIST_HEAD (&instance->completed_receivers); - /* initialize structure */ - memset (instance, 0, sizeof (struct udsl_instance_data)); - instance->usb_dev = dev; - instance->rcvbufs = NULL; - tasklet_init (&instance->recvqueue_tasklet, udsl_atm_processqueue, (unsigned long) instance); + tasklet_enable (&instance->receive_tasklet); + tasklet_kill (&instance->receive_tasklet); - udsl_atm_startdevice (instance, &udsl_atm_devops); + PDEBUG ("udsl_usb_disconnect: freeing receivers\n"); + for (i = 0; i < UDSL_NUMBER_RCV_URBS; i++) { + struct udsl_receiver *rcv = &(instance->all_receivers[i]); - /* set MAC address, it is stored in the serial number */ - usb_string (instance->usb_dev, instance->usb_dev->descriptor.iSerialNumber, mac_str, 13); - for (i = 0; i < 6; i++) - mac[i] = (hex2int (mac_str[i * 2]) * 16) + (hex2int (mac_str[i * 2 + 1])); + usb_free_urb (rcv->urb); + kfree_skb (rcv->skb); + } - PDEBUG ("MAC is %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], - mac[5]); - udsl_atm_set_mac (instance, mac); + for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) { + struct udsl_usb_send_data_context *ctx = &(instance->send_ctx[i]); - usb_set_intfdata (intf, instance); - return 0; -} + usb_unlink_urb (ctx->urb); -static void udsl_usb_disconnect (struct usb_interface *intf) -{ - struct udsl_instance_data *instance = usb_get_intfdata (intf); + if (ctx->skb) + ctx->vcc->pop (ctx->vcc, ctx->skb); + ctx->skb = NULL; - PDEBUG ("disconnecting\n"); + usb_free_urb (ctx->urb); - usb_set_intfdata (intf, NULL); - if (instance) { - /* unlinking receive buffers */ - udsl_usb_data_exit (instance); + } - /* removing atm device */ - if (instance->atm_dev) - udsl_atm_stopdevice (instance); - kfree (instance); + /* removing atm device */ + if (instance->atm_dev) + udsl_atm_stopdevice (instance); - MOD_DEC_USE_COUNT; - } + kfree (instance); } + /*************************************************************************** * * Driver Init @@ -907,18 +995,25 @@ static int __init udsl_usb_init (void) { - PDEBUG ("Initializing SpeedTouch Driver Version " DRIVER_VERSION "\n"); + PDEBUG ("udsl_usb_init: driver version " DRIVER_VERSION "\n"); return usb_register (&udsl_usb_driver); } static void __exit udsl_usb_cleanup (void) { + PDEBUG ("udsl_usb_cleanup\n"); + usb_deregister (&udsl_usb_driver); } -module_init(udsl_usb_init); -module_exit(udsl_usb_cleanup); +module_init (udsl_usb_init); +module_exit (udsl_usb_cleanup); + +MODULE_AUTHOR (DRIVER_AUTHOR); +MODULE_DESCRIPTION (DRIVER_DESC); +MODULE_LICENSE ("GPL"); + #ifdef DEBUG_PACKET /******************************************************************************* @@ -929,7 +1024,7 @@ static int udsl_print_packet (const unsigned char *data, int len) { - unsigned char buffer[256]; + unsigned char buffer [256]; int i = 0, j = 0; for (i = 0; i < len;) { @@ -941,10 +1036,6 @@ PDEBUG ("%s\n", buffer); } return i; -}; +} #endif /* PACKETDEBUG */ - -MODULE_AUTHOR (DRIVER_AUTHOR); -MODULE_DESCRIPTION (DRIVER_DESC); -MODULE_LICENSE ("GPL"); diff -Nru a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig --- a/drivers/usb/net/Kconfig Sun Feb 9 21:13:34 2003 +++ b/drivers/usb/net/Kconfig Sun Feb 9 21:13:34 2003 @@ -25,7 +25,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called catc.o. If you want to compile it as a + The module will be called catc. If you want to compile it as a module, say M here and read . config USB_CDCETHER @@ -49,7 +49,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called cdc-ether.o. If you want to compile it + The module will be called cdc-ether. If you want to compile it as a module, say M here and read . config USB_KAWETH @@ -91,7 +91,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called kaweth.o. If you want to compile it as a + The module will be called kaweth. If you want to compile it as a module, say M here and read . config USB_PEGASUS @@ -107,7 +107,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called pegasus.o. If you want to compile it as a + The module will be called pegasus. If you want to compile it as a module, say M here and read . config USB_RTL8150 @@ -120,7 +120,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called rtl8150.o. If you want to compile it as a + The module will be called rtl8150. If you want to compile it as a module, say M here and read . config USB_USBNET @@ -144,6 +144,6 @@ This code is also available as a kernel module (code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usbnet.o. If you want to compile it as a + The module will be called usbnet. If you want to compile it as a module, say M here and read . diff -Nru a/drivers/usb/net/Makefile.mii b/drivers/usb/net/Makefile.mii --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/usb/net/Makefile.mii Sun Feb 9 21:13:38 2003 @@ -0,0 +1,5 @@ +# +# Makefile for USB Network drivers which require generic MII code. +# + +obj-$(CONFIG_USB_PEGASUS) += mii.o diff -Nru a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig --- a/drivers/usb/serial/Kconfig Sun Feb 9 21:13:34 2003 +++ b/drivers/usb/serial/Kconfig Sun Feb 9 21:13:34 2003 @@ -19,7 +19,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usbserial.o. If you want to compile it + The module will be called usbserial. If you want to compile it as a module, say M here and read . config USB_SERIAL_DEBUG @@ -72,7 +72,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called belkin_sa.o. If you want to compile it as + The module will be called belkin_sa. If you want to compile it as a module, say M here and read . config USB_SERIAL_WHITEHEAT @@ -84,7 +84,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called whiteheat.o. If you want to compile it as + The module will be called whiteheat. If you want to compile it as a module, say M here and read . config USB_SERIAL_DIGI_ACCELEPORT @@ -101,7 +101,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called digi_acceleport.o. If you want to compile + The module will be called digi_acceleport. If you want to compile it as a module, say M here and read . @@ -116,7 +116,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called empeg.o. If you want to compile it as a + The module will be called empeg. If you want to compile it as a module, say M here and read . config USB_SERIAL_FTDI_SIO @@ -132,7 +132,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called ftdi_sio.o. If you want to compile it as + The module will be called ftdi_sio. If you want to compile it as a module, say M here and read . config USB_SERIAL_VISOR @@ -146,7 +146,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called visor.o. If you want to compile it as a + The module will be called visor. If you want to compile it as a module, say M here and read . config USB_SERIAL_IPAQ @@ -160,7 +160,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called ipaq.o. If you want to compile it as a + The module will be called ipaq. If you want to compile it as a module, say M here and read . config USB_SERIAL_IR @@ -173,7 +173,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called ir-usb.o. If you want to compile it as a + The module will be called ir-usb. If you want to compile it as a module, say M here and read . config USB_SERIAL_EDGEPORT @@ -201,7 +201,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called io_edgeport.o. If you want to compile it + The module will be called io_edgeport. If you want to compile it as a module, say M here and read . config USB_SERIAL_EDGEPORT_TI @@ -214,7 +214,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called io_ti.o. If you want to compile it + The module will be called io_ti. If you want to compile it as a module, say M here and read . config USB_SERIAL_KEYSPAN_PDA @@ -227,7 +227,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called keyspan_pda.o. If you want to compile it + The module will be called keyspan_pda. If you want to compile it as a module, say M here and read . config USB_SERIAL_KEYSPAN @@ -243,7 +243,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called keyspan.o. If you want to compile it as a + The module will be called keyspan. If you want to compile it as a module, say M here and read . config USB_SERIAL_KEYSPAN_USA28 @@ -323,7 +323,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called kl5kusb105.o. If you want to compile it as + The module will be called kl5kusb105. If you want to compile it as a module, say M here and read . config USB_SERIAL_KOBIL_SCT @@ -342,7 +342,7 @@ Note that you need a current CT-API. This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called kobil_sct.o. If you want to compile it as + The module will be called kobil_sct. If you want to compile it as a module, say M here and read . config USB_SERIAL_MCT_U232 @@ -357,7 +357,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called mct_u232.o. If you want to compile it as + The module will be called mct_u232. If you want to compile it as a module, say M here and read . config USB_SERIAL_PL2303 @@ -369,7 +369,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called pl2303.o. If you want to compile it as + The module will be called pl2303. If you want to compile it as a module, say M here and read . config USB_SERIAL_SAFE @@ -390,7 +390,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called cyberjack.o. If you want to compile it as + The module will be called cyberjack. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -405,7 +405,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called keyspan_pda.o. If you want to compile it + The module will be called keyspan_pda. If you want to compile it as a module, say M here and read . config USB_SERIAL_OMNINET @@ -416,7 +416,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called omninet.o. If you want to compile it as a + The module will be called omninet. If you want to compile it as a module, say M here and read . config USB_EZUSB diff -Nru a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile --- a/drivers/usb/serial/Makefile Sun Feb 9 21:13:29 2003 +++ b/drivers/usb/serial/Makefile Sun Feb 9 21:13:29 2003 @@ -30,7 +30,4 @@ obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o -# Objects that export symbols. -export-objs := usb-serial.o ezusb.o - usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y) diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c --- a/drivers/usb/serial/ftdi_sio.c Sun Feb 9 21:13:35 2003 +++ b/drivers/usb/serial/ftdi_sio.c Sun Feb 9 21:13:35 2003 @@ -135,6 +135,7 @@ static struct usb_device_id id_table_8U232AM [] = { { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, { } /* Terminating entry */ }; @@ -143,6 +144,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, { } /* Terminating entry */ }; diff -Nru a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h --- a/drivers/usb/serial/ftdi_sio.h Sun Feb 9 21:13:35 2003 +++ b/drivers/usb/serial/ftdi_sio.h Sun Feb 9 21:13:35 2003 @@ -17,11 +17,14 @@ * Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc.- wrote the * FTDI_SIO implementation. * + * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais + * from Rudolf Gugler */ #define FTDI_VID 0x0403 /* Vendor Id */ #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */ +#define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c --- a/drivers/usb/serial/ipaq.c Sun Feb 9 21:13:35 2003 +++ b/drivers/usb/serial/ipaq.c Sun Feb 9 21:13:35 2003 @@ -106,6 +106,7 @@ { USB_DEVICE(CASIO_VENDOR_ID, CASIO_EM500_ID) }, { USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_IPAQ_ID) }, { USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_0032_ID) }, + { USB_DEVICE(DELL_VENDOR_ID, DELL_AXIM_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_548_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_568_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_2016_ID) }, @@ -126,6 +127,7 @@ { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_WIRELESS_ID) }, { USB_DEVICE(SOCKET_VENDOR_ID, SOCKET_PRODUCT_ID) }, { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_ID) }, + { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_E740_ID) }, { USB_DEVICE(HTC_VENDOR_ID, HTC_PRODUCT_ID) }, { USB_DEVICE(NEC_VENDOR_ID, NEC_PRODUCT_ID) }, { } /* Terminating entry */ diff -Nru a/drivers/usb/serial/ipaq.h b/drivers/usb/serial/ipaq.h --- a/drivers/usb/serial/ipaq.h Sun Feb 9 21:13:28 2003 +++ b/drivers/usb/serial/ipaq.h Sun Feb 9 21:13:28 2003 @@ -30,6 +30,9 @@ #define COMPAQ_IPAQ_ID 0x0003 #define COMPAQ_0032_ID 0x0032 +#define DELL_VENDOR_ID 0x413c +#define DELL_AXIM_ID 0x4001 + #define HP_VENDOR_ID 0x03f0 #define HP_JORNADA_548_ID 0x1016 #define HP_JORNADA_568_ID 0x1116 @@ -63,6 +66,7 @@ #define TOSHIBA_VENDOR_ID 0x0930 #define TOSHIBA_PRODUCT_ID 0x0700 +#define TOSHIBA_E740_ID 0x0706 #define HTC_VENDOR_ID 0x0bb4 #define HTC_PRODUCT_ID 0x00ce diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c --- a/drivers/usb/serial/pl2303.c Sun Feb 9 21:13:31 2003 +++ b/drivers/usb/serial/pl2303.c Sun Feb 9 21:13:31 2003 @@ -74,6 +74,7 @@ { USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) }, { USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID) }, + { USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) }, { } /* Terminating entry */ }; diff -Nru a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h --- a/drivers/usb/serial/pl2303.h Sun Feb 9 21:13:32 2003 +++ b/drivers/usb/serial/pl2303.h Sun Feb 9 21:13:32 2003 @@ -28,3 +28,6 @@ #define RATOC_VENDOR_ID 0x0584 #define RATOC_PRODUCT_ID 0xb000 + +#define TRIPP_VENDOR_ID 0x2478 +#define TRIPP_PRODUCT_ID 0x2008 diff -Nru a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c --- a/drivers/usb/serial/safe_serial.c Sun Feb 9 21:13:29 2003 +++ b/drivers/usb/serial/safe_serial.c Sun Feb 9 21:13:29 2003 @@ -256,7 +256,7 @@ } tty_flip_buffer_push (port->tty); } else { - err ("%s - inconsistant lengths %d:%d", __FUNCTION__, + err ("%s - inconsistent lengths %d:%d", __FUNCTION__, actual_length, length); } } else { diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c --- a/drivers/usb/serial/usb-serial.c Sun Feb 9 21:13:31 2003 +++ b/drivers/usb/serial/usb-serial.c Sun Feb 9 21:13:31 2003 @@ -214,7 +214,7 @@ * Brian Warner has a place to put his code. * Made the ezusb specific functions generic enough that different * devices can use them (whiteheat and keyspan_pda both need them). - * Split out a whole bunch of structure and other stuff to a seperate + * Split out a whole bunch of structure and other stuff to a separate * usb-serial.h file. * Made the Visor connection messages a little more understandable, now * that Miles Lott (milos@insync.net) has gotten the Generic channel to diff -Nru a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig --- a/drivers/usb/storage/Kconfig Sun Feb 9 21:13:36 2003 +++ b/drivers/usb/storage/Kconfig Sun Feb 9 21:13:36 2003 @@ -16,7 +16,7 @@ This code is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called usb-storage.o. If you want to compile it + The module will be called usb-storage. If you want to compile it as a module, say M here and read . config USB_STORAGE_DEBUG diff -Nru a/drivers/usb/storage/datafab.h b/drivers/usb/storage/datafab.h --- a/drivers/usb/storage/datafab.h Sun Feb 9 21:13:34 2003 +++ b/drivers/usb/storage/datafab.h Sun Feb 9 21:13:34 2003 @@ -27,14 +27,14 @@ extern int datafab_transport(Scsi_Cmnd *srb, struct us_data *us); struct datafab_info { - unsigned long sectors; // total sector count - unsigned long ssize; // sector size in bytes - char lun; // used for dual-slot readers - - // the following aren't used yet + unsigned long sectors; // total sector count + unsigned long ssize; // sector size in bytes + char lun; // used for dual-slot readers + + // the following aren't used yet unsigned char sense_key; - unsigned long sense_asc; // additional sense code - unsigned long sense_ascq; // additional sense code qualifier + unsigned long sense_asc; // additional sense code + unsigned long sense_ascq; // additional sense code qualifier }; #endif diff -Nru a/drivers/usb/storage/dpcm.c b/drivers/usb/storage/dpcm.c --- a/drivers/usb/storage/dpcm.c Sun Feb 9 21:13:34 2003 +++ b/drivers/usb/storage/dpcm.c Sun Feb 9 21:13:34 2003 @@ -48,9 +48,9 @@ if(srb == NULL) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("dpcm_transport: LUN=%d\n", srb->lun); + US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun); - switch(srb->lun) { + switch(srb->device->lun) { case 0: /* @@ -68,15 +68,15 @@ /* * Set the LUN to 0 (just in case). */ - srb->lun = 0; us->srb->lun = 0; + srb->device->lun = 0; us->srb->device->lun = 0; ret = sddr09_transport(srb, us); - srb->lun = 1; us->srb->lun = 1; + srb->device->lun = 1; us->srb->device->lun = 1; return ret; #endif default: - US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->lun); + US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun); return USB_STOR_TRANSPORT_ERROR; } } diff -Nru a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c --- a/drivers/usb/storage/freecom.c Sun Feb 9 21:13:37 2003 +++ b/drivers/usb/storage/freecom.c Sun Feb 9 21:13:37 2003 @@ -45,42 +45,42 @@ #define DRQ_STAT 0x08 struct freecom_udata { - u8 buffer[64]; /* Common command block. */ + u8 buffer[64]; /* Common command block. */ }; typedef struct freecom_udata *freecom_udata_t; /* All of the outgoing packets are 64 bytes long. */ struct freecom_cb_wrap { - u8 Type; /* Command type. */ - u8 Timeout; /* Timeout in seconds. */ - u8 Atapi[12]; /* An ATAPI packet. */ - u8 Filler[50]; /* Padding Data. */ + u8 Type; /* Command type. */ + u8 Timeout; /* Timeout in seconds. */ + u8 Atapi[12]; /* An ATAPI packet. */ + u8 Filler[50]; /* Padding Data. */ }; struct freecom_xfer_wrap { - u8 Type; /* Command type. */ - u8 Timeout; /* Timeout in seconds. */ - u32 Count; /* Number of bytes to transfer. */ - u8 Pad[58]; + u8 Type; /* Command type. */ + u8 Timeout; /* Timeout in seconds. */ + u32 Count; /* Number of bytes to transfer. */ + u8 Pad[58]; } __attribute__ ((packed)); struct freecom_ide_out { - u8 Type; /* Type + IDE register. */ - u8 Pad; - u16 Value; /* Value to write. */ - u8 Pad2[60]; + u8 Type; /* Type + IDE register. */ + u8 Pad; + u16 Value; /* Value to write. */ + u8 Pad2[60]; }; struct freecom_ide_in { - u8 Type; /* Type | IDE register. */ - u8 Pad[63]; + u8 Type; /* Type | IDE register. */ + u8 Pad[63]; }; struct freecom_status { - u8 Status; - u8 Reason; - u16 Count; - u8 Pad[60]; + u8 Status; + u8 Reason; + u16 Count; + u8 Pad[60]; }; /* Freecom stuffs the interrupt status in the INDEX_STAT bit of the ide @@ -110,32 +110,32 @@ static int freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, - unsigned int ipipe, unsigned int opipe, int count) + unsigned int ipipe, unsigned int opipe, int count) { - freecom_udata_t extra = (freecom_udata_t) us->extra; - struct freecom_xfer_wrap *fxfr = - (struct freecom_xfer_wrap *) extra->buffer; - int result; - - fxfr->Type = FCM_PACKET_INPUT | 0x00; - fxfr->Timeout = 0; /* Short timeout for debugging. */ - fxfr->Count = cpu_to_le32 (count); - memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); - - US_DEBUGP("Read data Freecom! (c=%d)\n", count); - - /* Issue the transfer command. */ - result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, - FCM_PACKET_LENGTH, NULL); - if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("Freecom readdata transport error\n"); - return USB_STOR_TRANSPORT_ERROR; - } + freecom_udata_t extra = (freecom_udata_t) us->extra; + struct freecom_xfer_wrap *fxfr = + (struct freecom_xfer_wrap *) extra->buffer; + int result; + + fxfr->Type = FCM_PACKET_INPUT | 0x00; + fxfr->Timeout = 0; /* Short timeout for debugging. */ + fxfr->Count = cpu_to_le32 (count); + memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); + + US_DEBUGP("Read data Freecom! (c=%d)\n", count); + + /* Issue the transfer command. */ + result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, + FCM_PACKET_LENGTH, NULL); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP ("Freecom readdata transport error\n"); + return USB_STOR_TRANSPORT_ERROR; + } - /* Now transfer all of our blocks. */ + /* Now transfer all of our blocks. */ US_DEBUGP("Start of read\n"); result = usb_stor_bulk_transfer_srb(us, ipipe, srb, count); - US_DEBUGP("freecom_readdata done!\n"); + US_DEBUGP("freecom_readdata done!\n"); if (result > USB_STOR_XFER_SHORT) return USB_STOR_TRANSPORT_ERROR; @@ -144,33 +144,33 @@ static int freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, - int unsigned ipipe, unsigned int opipe, int count) + int unsigned ipipe, unsigned int opipe, int count) { - freecom_udata_t extra = (freecom_udata_t) us->extra; - struct freecom_xfer_wrap *fxfr = - (struct freecom_xfer_wrap *) extra->buffer; - int result; - - fxfr->Type = FCM_PACKET_OUTPUT | 0x00; - fxfr->Timeout = 0; /* Short timeout for debugging. */ - fxfr->Count = cpu_to_le32 (count); - memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); - - US_DEBUGP("Write data Freecom! (c=%d)\n", count); - - /* Issue the transfer command. */ - result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, - FCM_PACKET_LENGTH, NULL); - if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("Freecom writedata transport error\n"); - return USB_STOR_TRANSPORT_ERROR; - } + freecom_udata_t extra = (freecom_udata_t) us->extra; + struct freecom_xfer_wrap *fxfr = + (struct freecom_xfer_wrap *) extra->buffer; + int result; + + fxfr->Type = FCM_PACKET_OUTPUT | 0x00; + fxfr->Timeout = 0; /* Short timeout for debugging. */ + fxfr->Count = cpu_to_le32 (count); + memset (fxfr->Pad, 0, sizeof (fxfr->Pad)); + + US_DEBUGP("Write data Freecom! (c=%d)\n", count); + + /* Issue the transfer command. */ + result = usb_stor_bulk_transfer_buf (us, opipe, fxfr, + FCM_PACKET_LENGTH, NULL); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP ("Freecom writedata transport error\n"); + return USB_STOR_TRANSPORT_ERROR; + } - /* Now transfer all of our blocks. */ + /* Now transfer all of our blocks. */ US_DEBUGP("Start of write\n"); result = usb_stor_bulk_transfer_srb(us, opipe, srb, count); - US_DEBUGP("freecom_writedata done!\n"); + US_DEBUGP("freecom_writedata done!\n"); if (result > USB_STOR_XFER_SHORT) return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_GOOD; @@ -182,54 +182,54 @@ */ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) { - struct freecom_cb_wrap *fcb; - struct freecom_status *fst; - unsigned int ipipe, opipe; /* We need both pipes. */ - int result; + struct freecom_cb_wrap *fcb; + struct freecom_status *fst; + unsigned int ipipe, opipe; /* We need both pipes. */ + int result; unsigned int partial; - int length; - freecom_udata_t extra; + int length; + freecom_udata_t extra; + + extra = (freecom_udata_t) us->extra; - extra = (freecom_udata_t) us->extra; + fcb = (struct freecom_cb_wrap *) extra->buffer; + fst = (struct freecom_status *) extra->buffer; - fcb = (struct freecom_cb_wrap *) extra->buffer; - fst = (struct freecom_status *) extra->buffer; + US_DEBUGP("Freecom TRANSPORT STARTED\n"); - US_DEBUGP("Freecom TRANSPORT STARTED\n"); - - /* Get handles for both transports. */ - opipe = us->send_bulk_pipe; - ipipe = us->recv_bulk_pipe; - - /* The ATAPI Command always goes out first. */ - fcb->Type = FCM_PACKET_ATAPI | 0x00; - fcb->Timeout = 0; - memcpy (fcb->Atapi, srb->cmnd, 12); - memset (fcb->Filler, 0, sizeof (fcb->Filler)); - - US_DEBUG(pdump (srb->cmnd, 12)); - - /* Send it out. */ - result = usb_stor_bulk_transfer_buf (us, opipe, fcb, - FCM_PACKET_LENGTH, NULL); - - /* The Freecom device will only fail if there is something wrong in - * USB land. It returns the status in its own registers, which - * come back in the bulk pipe. */ - if (result != USB_STOR_XFER_GOOD) { - US_DEBUGP ("freecom transport error\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - /* There are times we can optimize out this status read, but it - * doesn't hurt us to always do it now. */ - result = usb_stor_bulk_transfer_buf (us, ipipe, fst, - FCM_PACKET_LENGTH, &partial); - US_DEBUGP("foo Status result %d %u\n", result, partial); + /* Get handles for both transports. */ + opipe = us->send_bulk_pipe; + ipipe = us->recv_bulk_pipe; + + /* The ATAPI Command always goes out first. */ + fcb->Type = FCM_PACKET_ATAPI | 0x00; + fcb->Timeout = 0; + memcpy (fcb->Atapi, srb->cmnd, 12); + memset (fcb->Filler, 0, sizeof (fcb->Filler)); + + US_DEBUG(pdump (srb->cmnd, 12)); + + /* Send it out. */ + result = usb_stor_bulk_transfer_buf (us, opipe, fcb, + FCM_PACKET_LENGTH, NULL); + + /* The Freecom device will only fail if there is something wrong in + * USB land. It returns the status in its own registers, which + * come back in the bulk pipe. */ + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP ("freecom transport error\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + /* There are times we can optimize out this status read, but it + * doesn't hurt us to always do it now. */ + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, + FCM_PACKET_LENGTH, &partial); + US_DEBUGP("foo Status result %d %u\n", result, partial); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUG(pdump ((void *) fst, partial)); + US_DEBUG(pdump ((void *) fst, partial)); /* The firmware will time-out commands after 20 seconds. Some commands * can legitimately take longer than this, so we use a different @@ -249,7 +249,7 @@ memset (fcb->Atapi, 0, sizeof(fcb->Atapi)); memset (fcb->Filler, 0, sizeof (fcb->Filler)); - /* Send it out. */ + /* Send it out. */ result = usb_stor_bulk_transfer_buf (us, opipe, fcb, FCM_PACKET_LENGTH, NULL); @@ -263,31 +263,31 @@ } /* get the data */ - result = usb_stor_bulk_transfer_buf (us, ipipe, fst, + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, FCM_PACKET_LENGTH, &partial); US_DEBUGP("bar Status result %d %u\n", result, partial); if (result > USB_STOR_XFER_SHORT) - return USB_STOR_TRANSPORT_ERROR; + return USB_STOR_TRANSPORT_ERROR; US_DEBUG(pdump ((void *) fst, partial)); } - if (partial != 4) - return USB_STOR_TRANSPORT_ERROR; - if ((fst->Status & 1) != 0) { - US_DEBUGP("operation failed\n"); - return USB_STOR_TRANSPORT_FAILED; - } - - /* The device might not have as much data available as we - * requested. If you ask for more than the device has, this reads - * and such will hang. */ - US_DEBUGP("Device indicates that it has %d bytes available\n", - le16_to_cpu (fst->Count)); - US_DEBUGP("SCSI requested %d\n", srb->request_bufflen); + if (partial != 4) + return USB_STOR_TRANSPORT_ERROR; + if ((fst->Status & 1) != 0) { + US_DEBUGP("operation failed\n"); + return USB_STOR_TRANSPORT_FAILED; + } - /* Find the length we desire to read. */ + /* The device might not have as much data available as we + * requested. If you ask for more than the device has, this reads + * and such will hang. */ + US_DEBUGP("Device indicates that it has %d bytes available\n", + le16_to_cpu (fst->Count)); + US_DEBUGP("SCSI requested %d\n", srb->request_bufflen); + + /* Find the length we desire to read. */ switch (srb->cmnd[0]) { case INQUIRY: case REQUEST_SENSE: /* 16 or 18 bytes? spec says 18, lots of devices only have 16 */ @@ -305,97 +305,97 @@ US_DEBUGP("Truncating request to match buffer length: %d\n", length); } - /* What we do now depends on what direction the data is supposed to - * move in. */ + /* What we do now depends on what direction the data is supposed to + * move in. */ + + switch (us->srb->sc_data_direction) { + case SCSI_DATA_READ: + /* Make sure that the status indicates that the device + * wants data as well. */ + if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) { + US_DEBUGP("SCSI wants data, drive doesn't have any\n"); + return USB_STOR_TRANSPORT_FAILED; + } + result = freecom_readdata (srb, us, ipipe, opipe, length); + if (result != USB_STOR_TRANSPORT_GOOD) + return result; - switch (us->srb->sc_data_direction) { - case SCSI_DATA_READ: - /* Make sure that the status indicates that the device - * wants data as well. */ - if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) { - US_DEBUGP("SCSI wants data, drive doesn't have any\n"); - return USB_STOR_TRANSPORT_FAILED; - } - result = freecom_readdata (srb, us, ipipe, opipe, length); - if (result != USB_STOR_TRANSPORT_GOOD) - return result; - - US_DEBUGP("FCM: Waiting for status\n"); - result = usb_stor_bulk_transfer_buf (us, ipipe, fst, - FCM_PACKET_LENGTH, &partial); + US_DEBUGP("FCM: Waiting for status\n"); + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, + FCM_PACKET_LENGTH, &partial); US_DEBUG(pdump ((void *) fst, partial)); - if (partial != 4 || result > USB_STOR_XFER_SHORT) - return USB_STOR_TRANSPORT_ERROR; - if ((fst->Status & ERR_STAT) != 0) { - US_DEBUGP("operation failed\n"); - return USB_STOR_TRANSPORT_FAILED; - } - if ((fst->Reason & 3) != 3) { - US_DEBUGP("Drive seems still hungry\n"); - return USB_STOR_TRANSPORT_FAILED; - } - US_DEBUGP("Transfer happy\n"); - break; - - case SCSI_DATA_WRITE: - /* Make sure the status indicates that the device wants to - * send us data. */ - /* !!IMPLEMENT!! */ - result = freecom_writedata (srb, us, ipipe, opipe, length); - if (result != USB_STOR_TRANSPORT_GOOD) - return result; - - US_DEBUGP("FCM: Waiting for status\n"); - result = usb_stor_bulk_transfer_buf (us, ipipe, fst, - FCM_PACKET_LENGTH, &partial); - - if (partial != 4 || result > USB_STOR_XFER_SHORT) - return USB_STOR_TRANSPORT_ERROR; - if ((fst->Status & ERR_STAT) != 0) { - US_DEBUGP("operation failed\n"); - return USB_STOR_TRANSPORT_FAILED; - } - if ((fst->Reason & 3) != 3) { - US_DEBUGP("Drive seems still hungry\n"); - return USB_STOR_TRANSPORT_FAILED; - } - - US_DEBUGP("Transfer happy\n"); - break; - - - case SCSI_DATA_NONE: - /* Easy, do nothing. */ - break; - - default: - US_DEBUGP ("freecom unimplemented direction: %d\n", - us->srb->sc_data_direction); - // Return fail, SCSI seems to handle this better. - return USB_STOR_TRANSPORT_FAILED; - break; - } + if (partial != 4 || result > USB_STOR_XFER_SHORT) + return USB_STOR_TRANSPORT_ERROR; + if ((fst->Status & ERR_STAT) != 0) { + US_DEBUGP("operation failed\n"); + return USB_STOR_TRANSPORT_FAILED; + } + if ((fst->Reason & 3) != 3) { + US_DEBUGP("Drive seems still hungry\n"); + return USB_STOR_TRANSPORT_FAILED; + } + US_DEBUGP("Transfer happy\n"); + break; + + case SCSI_DATA_WRITE: + /* Make sure the status indicates that the device wants to + * send us data. */ + /* !!IMPLEMENT!! */ + result = freecom_writedata (srb, us, ipipe, opipe, length); + if (result != USB_STOR_TRANSPORT_GOOD) + return result; + + US_DEBUGP("FCM: Waiting for status\n"); + result = usb_stor_bulk_transfer_buf (us, ipipe, fst, + FCM_PACKET_LENGTH, &partial); + + if (partial != 4 || result > USB_STOR_XFER_SHORT) + return USB_STOR_TRANSPORT_ERROR; + if ((fst->Status & ERR_STAT) != 0) { + US_DEBUGP("operation failed\n"); + return USB_STOR_TRANSPORT_FAILED; + } + if ((fst->Reason & 3) != 3) { + US_DEBUGP("Drive seems still hungry\n"); + return USB_STOR_TRANSPORT_FAILED; + } - return USB_STOR_TRANSPORT_GOOD; + US_DEBUGP("Transfer happy\n"); + break; + + + case SCSI_DATA_NONE: + /* Easy, do nothing. */ + break; + + default: + US_DEBUGP ("freecom unimplemented direction: %d\n", + us->srb->sc_data_direction); + // Return fail, SCSI seems to handle this better. + return USB_STOR_TRANSPORT_FAILED; + break; + } + + return USB_STOR_TRANSPORT_GOOD; } int freecom_init (struct us_data *us) { - int result; + int result; char buffer[33]; - /* Allocate a buffer for us. The upper usb transport code will - * free this for us when cleaning up. */ - if (us->extra == NULL) { - us->extra = kmalloc (sizeof (struct freecom_udata), - GFP_KERNEL); - if (us->extra == NULL) { - US_DEBUGP("Out of memory\n"); - return USB_STOR_TRANSPORT_ERROR; - } - } + /* Allocate a buffer for us. The upper usb transport code will + * free this for us when cleaning up. */ + if (us->extra == NULL) { + us->extra = kmalloc (sizeof (struct freecom_udata), + GFP_KERNEL); + if (us->extra == NULL) { + US_DEBUGP("Out of memory\n"); + return USB_STOR_TRANSPORT_ERROR; + } + } result = usb_control_msg(us->pusb_dev, us->recv_ctrl_pipe, 0x4c, 0xc0, 0x4346, 0x0, buffer, 0x20, 3*HZ); @@ -424,15 +424,15 @@ /* wait 3 seconds */ mdelay(3 * 1000); - return USB_STOR_TRANSPORT_GOOD; + return USB_STOR_TRANSPORT_GOOD; } int usb_stor_freecom_reset(struct us_data *us) { - printk (KERN_CRIT "freecom reset called\n"); + printk (KERN_CRIT "freecom reset called\n"); - /* We don't really have this feature. */ - return FAILED; + /* We don't really have this feature. */ + return FAILED; } #ifdef CONFIG_USB_STORAGE_DEBUG diff -Nru a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c --- a/drivers/usb/storage/isd200.c Sun Feb 9 21:13:32 2003 +++ b/drivers/usb/storage/isd200.c Sun Feb 9 21:13:32 2003 @@ -34,11 +34,11 @@ * 2002-10-19: Removed the specialized transfer routines. * (Alan Stern ) * 2001-02-24: Removed lots of duplicate code and simplified the structure. - * (bjorn@haxx.se) + * (bjorn@haxx.se) * 2002-01-16: Fixed endianness bug so it works on the ppc arch. - * (Luc Saillard ) + * (Luc Saillard ) * 2002-01-17: All bitfields removed. - * (bjorn@haxx.se) + * (bjorn@haxx.se) */ @@ -59,14 +59,14 @@ /* Timeout defines (in Seconds) */ -#define ISD200_ENUM_BSY_TIMEOUT 35 +#define ISD200_ENUM_BSY_TIMEOUT 35 #define ISD200_ENUM_DETECT_TIMEOUT 30 -#define ISD200_DEFAULT_TIMEOUT 30 +#define ISD200_DEFAULT_TIMEOUT 30 /* device flags */ -#define DF_ATA_DEVICE 0x0001 -#define DF_MEDIA_STATUS_ENABLED 0x0002 -#define DF_REMOVABLE_MEDIA 0x0004 +#define DF_ATA_DEVICE 0x0001 +#define DF_MEDIA_STATUS_ENABLED 0x0002 +#define DF_REMOVABLE_MEDIA 0x0004 /* capability bit definitions */ #define CAPABILITY_DMA 0x01 @@ -82,46 +82,46 @@ #define ATA_ADDRESS_DEVHEAD_SLAVE 0x10 /* Action Select bits */ -#define ACTION_SELECT_0 0x01 -#define ACTION_SELECT_1 0x02 -#define ACTION_SELECT_2 0x04 -#define ACTION_SELECT_3 0x08 -#define ACTION_SELECT_4 0x10 -#define ACTION_SELECT_5 0x20 -#define ACTION_SELECT_6 0x40 -#define ACTION_SELECT_7 0x80 +#define ACTION_SELECT_0 0x01 +#define ACTION_SELECT_1 0x02 +#define ACTION_SELECT_2 0x04 +#define ACTION_SELECT_3 0x08 +#define ACTION_SELECT_4 0x10 +#define ACTION_SELECT_5 0x20 +#define ACTION_SELECT_6 0x40 +#define ACTION_SELECT_7 0x80 /* Register Select bits */ -#define REG_ALTERNATE_STATUS 0x01 -#define REG_DEVICE_CONTROL 0x01 -#define REG_ERROR 0x02 -#define REG_FEATURES 0x02 -#define REG_SECTOR_COUNT 0x04 -#define REG_SECTOR_NUMBER 0x08 -#define REG_CYLINDER_LOW 0x10 -#define REG_CYLINDER_HIGH 0x20 -#define REG_DEVICE_HEAD 0x40 -#define REG_STATUS 0x80 -#define REG_COMMAND 0x80 +#define REG_ALTERNATE_STATUS 0x01 +#define REG_DEVICE_CONTROL 0x01 +#define REG_ERROR 0x02 +#define REG_FEATURES 0x02 +#define REG_SECTOR_COUNT 0x04 +#define REG_SECTOR_NUMBER 0x08 +#define REG_CYLINDER_LOW 0x10 +#define REG_CYLINDER_HIGH 0x20 +#define REG_DEVICE_HEAD 0x40 +#define REG_STATUS 0x80 +#define REG_COMMAND 0x80 /* ATA error definitions not in */ -#define ATA_ERROR_MEDIA_CHANGE 0x20 +#define ATA_ERROR_MEDIA_CHANGE 0x20 /* ATA command definitions not in */ -#define ATA_COMMAND_GET_MEDIA_STATUS 0xDA -#define ATA_COMMAND_MEDIA_EJECT 0xED +#define ATA_COMMAND_GET_MEDIA_STATUS 0xDA +#define ATA_COMMAND_MEDIA_EJECT 0xED /* ATA drive control definitions */ -#define ATA_DC_DISABLE_INTERRUPTS 0x02 -#define ATA_DC_RESET_CONTROLLER 0x04 -#define ATA_DC_REENABLE_CONTROLLER 0x00 +#define ATA_DC_DISABLE_INTERRUPTS 0x02 +#define ATA_DC_RESET_CONTROLLER 0x04 +#define ATA_DC_REENABLE_CONTROLLER 0x00 /* * General purpose return codes */ -#define ISD200_ERROR -1 -#define ISD200_GOOD 0 +#define ISD200_ERROR -1 +#define ISD200_GOOD 0 /* * Transport return codes @@ -162,7 +162,7 @@ unsigned char WriteData1F7; unsigned char Reserved[3]; } generic; - + struct { unsigned char SignatureByte0; unsigned char SignatureByte1; @@ -180,7 +180,7 @@ unsigned char Reserved[3]; } read; - struct { + struct { unsigned char SignatureByte0; unsigned char SignatureByte1; unsigned char ActionSelect; @@ -211,8 +211,8 @@ /* * DeviceType field */ -#define DIRECT_ACCESS_DEVICE 0x00 /* disks */ -#define DEVICE_REMOVABLE 0x80 +#define DIRECT_ACCESS_DEVICE 0x00 /* disks */ +#define DEVICE_REMOVABLE 0x80 struct inquiry_data { unsigned char DeviceType; @@ -240,9 +240,9 @@ * ISD200 CONFIG data struct */ -#define ATACFG_TIMING 0x0f +#define ATACFG_TIMING 0x0f #define ATACFG_ATAPI_RESET 0x10 -#define ATACFG_MASTER 0x20 +#define ATACFG_MASTER 0x20 #define ATACFG_BLOCKSIZE 0xa0 #define ATACFGE_LAST_LUN 0x07 @@ -255,12 +255,12 @@ #define CFG_CAPABILITY_SRST 0x01 struct isd200_config { - unsigned char EventNotification; - unsigned char ExternalClock; - unsigned char ATAInitTimeout; + unsigned char EventNotification; + unsigned char ExternalClock; + unsigned char ATAInitTimeout; unsigned char ATAConfig; - unsigned char ATAMajorCommand; - unsigned char ATAMinorCommand; + unsigned char ATAMajorCommand; + unsigned char ATAMinorCommand; unsigned char ATAExtraConfig; unsigned char Capability; }__attribute__ ((packed)); @@ -309,7 +309,7 @@ * Sense Data Format */ -#define SENSE_ERRCODE 0x7f +#define SENSE_ERRCODE 0x7f #define SENSE_ERRCODE_VALID 0x80 #define SENSE_FLAG_SENSE_KEY 0x0f #define SENSE_FLAG_BAD_LENGTH 0x20 @@ -319,13 +319,13 @@ unsigned char ErrorCode; unsigned char SegmentNumber; unsigned char Flags; - unsigned char Information[4]; - unsigned char AdditionalSenseLength; - unsigned char CommandSpecificInformation[4]; - unsigned char AdditionalSenseCode; - unsigned char AdditionalSenseCodeQualifier; - unsigned char FieldReplaceableUnitCode; - unsigned char SenseKeySpecific[3]; + unsigned char Information[4]; + unsigned char AdditionalSenseLength; + unsigned char CommandSpecificInformation[4]; + unsigned char AdditionalSenseCode; + unsigned char AdditionalSenseCodeQualifier; + unsigned char FieldReplaceableUnitCode; + unsigned char SenseKeySpecific[3]; } __attribute__ ((packed)); /* @@ -340,18 +340,18 @@ /************************************************************************** * isd200_build_sense - * + * * Builds an artificial sense buffer to report the results of a * failed command. - * + * * RETURNS: * void - */ + */ void isd200_build_sense(struct us_data *us, Scsi_Cmnd *srb) { - struct isd200_info *info = (struct isd200_info *)us->extra; - struct sense_data *buf = (struct sense_data *) &srb->sense_buffer[0]; - unsigned char error = info->ATARegs[IDE_ERROR_OFFSET]; + struct isd200_info *info = (struct isd200_info *)us->extra; + struct sense_data *buf = (struct sense_data *) &srb->sense_buffer[0]; + unsigned char error = info->ATARegs[IDE_ERROR_OFFSET]; if(error & ATA_ERROR_MEDIA_CHANGE) { buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID; @@ -359,31 +359,31 @@ buf->Flags = UNIT_ATTENTION; buf->AdditionalSenseCode = 0; buf->AdditionalSenseCodeQualifier = 0; - } else if(error & MCR_ERR) { + } else if(error & MCR_ERR) { buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID; buf->AdditionalSenseLength = 0xb; buf->Flags = UNIT_ATTENTION; buf->AdditionalSenseCode = 0; buf->AdditionalSenseCodeQualifier = 0; - } else if(error & TRK0_ERR) { + } else if(error & TRK0_ERR) { buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID; buf->AdditionalSenseLength = 0xb; buf->Flags = NOT_READY; buf->AdditionalSenseCode = 0; buf->AdditionalSenseCodeQualifier = 0; - } else if(error & ECC_ERR) { + } else if(error & ECC_ERR) { buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID; buf->AdditionalSenseLength = 0xb; buf->Flags = DATA_PROTECT; buf->AdditionalSenseCode = 0; buf->AdditionalSenseCodeQualifier = 0; - } else { + } else { buf->ErrorCode = 0; buf->AdditionalSenseLength = 0; buf->Flags = 0; buf->AdditionalSenseCode = 0; buf->AdditionalSenseCodeQualifier = 0; - } + } } @@ -430,8 +430,8 @@ case ACTION_ENUM: US_DEBUGP(" isd200_action(ENUM,0x%02x)\n",value); ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2| - ACTION_SELECT_3|ACTION_SELECT_4| - ACTION_SELECT_5; + ACTION_SELECT_3|ACTION_SELECT_4| + ACTION_SELECT_5; ata.generic.RegisterSelect = REG_DEVICE_HEAD; ata.write.DeviceHeadByte = value; srb.sc_data_direction = SCSI_DATA_NONE; @@ -440,7 +440,7 @@ case ACTION_RESET: US_DEBUGP(" isd200_action(RESET)\n"); ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2| - ACTION_SELECT_3|ACTION_SELECT_4; + ACTION_SELECT_3|ACTION_SELECT_4; ata.generic.RegisterSelect = REG_DEVICE_CONTROL; ata.write.DeviceControlByte = ATA_DC_RESET_CONTROLLER; srb.sc_data_direction = SCSI_DATA_NONE; @@ -449,7 +449,7 @@ case ACTION_REENABLE: US_DEBUGP(" isd200_action(REENABLE)\n"); ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_2| - ACTION_SELECT_3|ACTION_SELECT_4; + ACTION_SELECT_3|ACTION_SELECT_4; ata.generic.RegisterSelect = REG_DEVICE_CONTROL; ata.write.DeviceControlByte = ATA_DC_REENABLE_CONTROLLER; srb.sc_data_direction = SCSI_DATA_NONE; @@ -493,12 +493,12 @@ /************************************************************************** * isd200_read_regs - * + * * Read ATA Registers * * RETURNS: * ISD status code - */ + */ int isd200_read_regs( struct us_data *us ) { struct isd200_info *info = (struct isd200_info *)us->extra; @@ -512,10 +512,10 @@ if (transferStatus != ISD200_TRANSPORT_GOOD) { US_DEBUGP(" Error reading ATA registers\n"); retStatus = ISD200_ERROR; - } else { + } else { US_DEBUGP(" Got ATA Register[IDE_ERROR_OFFSET] = 0x%x\n", info->ATARegs[IDE_ERROR_OFFSET]); - } + } return retStatus; } @@ -649,12 +649,12 @@ /************************************************************************** * isd200_write_config - * + * * Write the ISD200 Configuraton data * * RETURNS: * ISD status code - */ + */ int isd200_write_config( struct us_data *us ) { struct isd200_info *info = (struct isd200_info *)us->extra; @@ -669,21 +669,21 @@ /* let's send the command via the control pipe */ result = usb_stor_ctrl_transfer( - us, - us->send_ctrl_pipe, - 0x01, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - 0x0000, - 0x0002, - (void *) &info->ConfigData, - sizeof(info->ConfigData)); + us, + us->send_ctrl_pipe, + 0x01, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, + 0x0000, + 0x0002, + (void *) &info->ConfigData, + sizeof(info->ConfigData)); if (result >= 0) { US_DEBUGP(" ISD200 Config Data was written successfully\n"); - } else { + } else { US_DEBUGP(" Request to write ISD200 Config Data failed!\n"); retStatus = ISD200_ERROR; - } + } US_DEBUGP("Leaving isd200_write_config %08X\n", retStatus); return retStatus; @@ -692,12 +692,12 @@ /************************************************************************** * isd200_read_config - * + * * Reads the ISD200 Configuraton data * * RETURNS: * ISD status code - */ + */ int isd200_read_config( struct us_data *us ) { struct isd200_info *info = (struct isd200_info *)us->extra; @@ -707,17 +707,17 @@ US_DEBUGP("Entering isd200_read_config\n"); /* read the configuration information from ISD200. Use this to */ - /* determine what the special ATA CDB bytes are. */ + /* determine what the special ATA CDB bytes are. */ result = usb_stor_ctrl_transfer( - us, - us->recv_ctrl_pipe, - 0x02, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x0000, - 0x0002, - (void *) &info->ConfigData, - sizeof(info->ConfigData)); + us, + us->recv_ctrl_pipe, + 0x02, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0x0000, + 0x0002, + (void *) &info->ConfigData, + sizeof(info->ConfigData)); if (result >= 0) { @@ -725,10 +725,10 @@ #ifdef CONFIG_USB_STORAGE_DEBUG isd200_log_config(info); #endif - } else { + } else { US_DEBUGP(" Request to get ISD200 Config Data failed!\n"); retStatus = ISD200_ERROR; - } + } US_DEBUGP("Leaving isd200_read_config %08X\n", retStatus); return retStatus; @@ -737,12 +737,12 @@ /************************************************************************** * isd200_atapi_soft_reset - * + * * Perform an Atapi Soft Reset on the device * * RETURNS: * NT status code - */ + */ int isd200_atapi_soft_reset( struct us_data *us ) { int retStatus = ISD200_GOOD; @@ -754,7 +754,7 @@ if (transferStatus != ISD200_TRANSPORT_GOOD) { US_DEBUGP(" Error issuing Atapi Soft Reset\n"); retStatus = ISD200_ERROR; - } + } US_DEBUGP("Leaving isd200_atapi_soft_reset %08X\n", retStatus); return retStatus; @@ -763,12 +763,12 @@ /************************************************************************** * isd200_srst - * + * * Perform an SRST on the device * * RETURNS: * ISD status code - */ + */ int isd200_srst( struct us_data *us ) { int retStatus = ISD200_GOOD; @@ -782,7 +782,7 @@ if (transferStatus != ISD200_TRANSPORT_GOOD) { US_DEBUGP(" Error issuing SRST\n"); retStatus = ISD200_ERROR; - } else { + } else { /* delay 10ms to give the drive a chance to see it */ wait_ms(10); @@ -794,7 +794,7 @@ /* delay 50ms to give the drive a chance to recover after SRST */ wait_ms(50); } - } + } US_DEBUGP("Leaving isd200_srst %08X\n", retStatus); return retStatus; @@ -803,13 +803,13 @@ /************************************************************************** * isd200_try_enum - * + * * Helper function for isd200_manual_enum(). Does ENUM and READ_STATUS * and tries to analyze the status registers * * RETURNS: * ISD status code - */ + */ static int isd200_try_enum(struct us_data *us, unsigned char master_slave, int detect ) { @@ -908,13 +908,13 @@ /************************************************************************** * isd200_manual_enum - * + * * Determines if the drive attached is an ATA or ATAPI and if it is a * master or slave. * * RETURNS: * ISD status code - */ + */ int isd200_manual_enum(struct us_data *us) { struct isd200_info *info = (struct isd200_info *)us->extra; @@ -1078,15 +1078,15 @@ us->proto_handler = usb_stor_transparent_scsi_command; US_DEBUGP("Protocol changed to: %s\n", us->protocol_name); - - /* Free driver structure */ + + /* Free driver structure */ if (us->extra != NULL) { kfree(us->extra); us->extra = NULL; us->extra_destructor = NULL; } } - } + } US_DEBUGP("Leaving isd200_get_inquiry_data %08X\n", retStatus); @@ -1096,12 +1096,12 @@ /************************************************************************** * isd200_data_copy - * + * * Copy data into the srb request buffer. Use scatter gather if required. * * RETURNS: * void - */ + */ void isd200_data_copy(Scsi_Cmnd *srb, char * src, int length) { unsigned int len = length; @@ -1150,13 +1150,13 @@ /************************************************************************** * isd200_scsi_to_ata - * + * * Translate SCSI commands to ATA commands. * * RETURNS: * TRUE if the command needs to be sent to the transport layer * FALSE otherwise - */ + */ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us, union ata_cdb * ataCdb) { @@ -1321,7 +1321,7 @@ if (info->DeviceFlags & DF_REMOVABLE_MEDIA) { US_DEBUGP(" srb->cmnd[4] = 0x%X\n", srb->cmnd[4]); - + ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand; ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand; ataCdb->generic.TransferBlockSize = 1; @@ -1378,12 +1378,12 @@ /************************************************************************** * isd200_init_info - * + * * Allocates (if necessary) and initializes the driver structure. * * RETURNS: * ISD status code - */ + */ int isd200_init_info(struct us_data *us) { int retStatus = ISD200_GOOD; @@ -1394,11 +1394,11 @@ US_DEBUGP("ERROR - kmalloc failure\n"); retStatus = ISD200_ERROR; } - } + } if (retStatus == ISD200_GOOD) { memset(us->extra, 0, sizeof(struct isd200_info)); - } + } return(retStatus); } @@ -1415,14 +1415,14 @@ if (isd200_init_info(us) == ISD200_ERROR) { US_DEBUGP("ERROR Initializing ISD200 Info struct\n"); - } else { + } else { /* Get device specific data */ if (isd200_get_inquiry_data(us) != ISD200_GOOD) US_DEBUGP("ISD200 Initialization Failure\n"); else US_DEBUGP("ISD200 Initialization complete\n"); - } + } return 0; } diff -Nru a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h --- a/drivers/usb/storage/protocol.h Sun Feb 9 21:13:31 2003 +++ b/drivers/usb/storage/protocol.h Sun Feb 9 21:13:31 2003 @@ -53,7 +53,7 @@ #define US_SC_UFI 0x04 /* Floppy */ #define US_SC_8070 0x05 /* Removable media */ #define US_SC_SCSI 0x06 /* Transparent */ -#define US_SC_ISD200 0x07 /* ISD200 ATA */ +#define US_SC_ISD200 0x07 /* ISD200 ATA */ #define US_SC_MIN US_SC_RBC #define US_SC_MAX US_SC_ISD200 diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c --- a/drivers/usb/storage/scsiglue.c Sun Feb 9 21:13:32 2003 +++ b/drivers/usb/storage/scsiglue.c Sun Feb 9 21:13:32 2003 @@ -50,23 +50,25 @@ #include "transport.h" #include +#include /*********************************************************************** * Host functions ***********************************************************************/ -static const char* host_info(struct Scsi_Host *host) +static const char* usb_storage_info(struct Scsi_Host *host) { return "SCSI emulation for USB Mass Storage devices"; } +#if 0 /* detect a virtual adapter (always works) * Synchronization: 2.4: with the io_request_lock * 2.5: no locks. * fortunately we don't care. * */ -static int detect(struct SHT *sht) +static int usb_storage_detect(struct SHT *sht) { struct us_data *us; char local_name[32]; @@ -109,7 +111,7 @@ * the driver and we're doing each virtual host in turn, not in parallel * Synchronization: BKL, no spinlock. */ -static int release(struct Scsi_Host *psh) +static int usb_storage_release(struct Scsi_Host *psh) { struct us_data *us = (struct us_data *)psh->hostdata[0]; @@ -132,20 +134,13 @@ /* we always have a successful release */ return 0; } - -/* run command */ -static int command( Scsi_Cmnd *srb ) -{ - US_DEBUGP("Bad use of us_command\n"); - - return DID_BAD_TARGET << 16; -} +#endif /* queue a command */ /* This is always called with scsi_lock(srb->host) held */ -static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) +static int usb_storage_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *)) { - struct us_data *us = (struct us_data *)srb->host->hostdata[0]; + struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; US_DEBUGP("queuecommand() called\n"); srb->host_scribble = (unsigned char *)us; @@ -168,9 +163,9 @@ /* Command abort */ /* This is always called with scsi_lock(srb->host) held */ -static int command_abort( Scsi_Cmnd *srb ) +static int usb_storage_command_abort( Scsi_Cmnd *srb ) { - struct us_data *us = (struct us_data *)srb->host->hostdata[0]; + struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; US_DEBUGP("command_abort() called\n"); @@ -187,9 +182,9 @@ /* This invokes the transport reset mechanism to reset the state of the * device */ /* This is always called with scsi_lock(srb->host) held */ -static int device_reset( Scsi_Cmnd *srb ) +static int usb_storage_device_reset( Scsi_Cmnd *srb ) { - struct us_data *us = (struct us_data *)srb->host->hostdata[0]; + struct us_data *us = (struct us_data *)srb->device->host->hostdata[0]; int result; US_DEBUGP("device_reset() called\n" ); @@ -197,20 +192,19 @@ /* set the state and release the lock */ atomic_set(&us->sm_state, US_STATE_RESETTING); - scsi_unlock(srb->host); + scsi_unlock(srb->device->host); /* lock the device pointers */ down(&(us->dev_semaphore)); - /* if the device was removed, then we're already reset */ - if (!(us->flags & US_FL_DEV_ATTACHED)) - result = SUCCESS; - else - result = us->transport_reset(us); + /* do the reset */ + result = us->transport_reset(us); + + /* unlock */ up(&(us->dev_semaphore)); /* lock access to the state and clear it */ - scsi_lock(srb->host); + scsi_lock(srb->device->host); atomic_set(&us->sm_state, US_STATE_IDLE); return result; } @@ -219,43 +213,38 @@ * disconnect/reconnect for all drivers which have claimed * interfaces, including ourself. */ /* This is always called with scsi_lock(srb->host) held */ -static int bus_reset( Scsi_Cmnd *srb ) + +/* FIXME: This needs to be re-examined in the face of the new + * hotplug system -- this will implicitly cause a detach/reattach of + * usb-storage, which is not what we want now. + * + * Can we just skip over usb-storage in the while loop? + */ +static int usb_storage_bus_reset( Scsi_Cmnd *srb ) { - struct us_data *us = (struct us_data *)srb->host->hostdata[0]; + struct us_data *us; int i; int result; - struct usb_device *pusb_dev_save; /* we use the usb_reset_device() function to handle this for us */ US_DEBUGP("bus_reset() called\n"); - - scsi_unlock(srb->host); - - /* if the device has been removed, this worked */ - down(&us->dev_semaphore); - if (!(us->flags & US_FL_DEV_ATTACHED)) { - US_DEBUGP("-- device removed already\n"); - up(&us->dev_semaphore); - scsi_lock(srb->host); - return SUCCESS; - } - pusb_dev_save = us->pusb_dev; - up(&us->dev_semaphore); + scsi_unlock(srb->device->host); + us = (struct us_data *)srb->device->host->hostdata[0]; /* attempt to reset the port */ - result = usb_reset_device(pusb_dev_save); + result = usb_reset_device(us->pusb_dev); US_DEBUGP("usb_reset_device returns %d\n", result); if (result < 0) { - scsi_lock(srb->host); + scsi_lock(srb->device->host); return FAILED; } /* FIXME: This needs to lock out driver probing while it's working * or we can have race conditions */ /* This functionality really should be provided by the khubd thread */ - for (i = 0; i < pusb_dev_save->actconfig->desc.bNumInterfaces; i++) { + for (i = 0; i < us->pusb_dev->actconfig->desc.bNumInterfaces; i++) { struct usb_interface *intf = - &pusb_dev_save->actconfig->interface[i]; + &us->pusb_dev->actconfig->interface[i]; /* if this is an unclaimed interface, skip it */ if (!intf->driver) { @@ -270,18 +259,10 @@ usb_device_probe (&intf->dev); } US_DEBUGP("bus_reset() complete\n"); - scsi_lock(srb->host); + scsi_lock(srb->device->host); return SUCCESS; } -/* FIXME: This doesn't do anything right now */ -static int host_reset( Scsi_Cmnd *srb ) -{ - printk(KERN_CRIT "usb-storage: host_reset() requested but not implemented\n" ); - bus_reset(srb); - return FAILED; -} - /*********************************************************************** * /proc/scsi/ functions ***********************************************************************/ @@ -291,29 +272,23 @@ #define SPRINTF(args...) \ do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) -static int proc_info (char *buffer, char **start, off_t offset, int length, - int hostno, int inout) +static int usb_storage_proc_info (char *buffer, char **start, off_t offset, + int length, int hostno, int inout) { struct us_data *us; char *pos = buffer; + struct Scsi_Host *hostptr; /* if someone is sending us data, just throw it away */ if (inout) return length; - /* lock the data structures */ - down(&us_list_semaphore); - - /* find our data from hostno */ - us = us_list; - while (us) { - if (us->host_no == hostno) - break; - us = us->next; + /* find our data from the given hostno */ + hostptr = scsi_host_hn_get(hostno); + if (!hostptr) { /* if we couldn't find it, we return an error */ + return -ESRCH; } - - /* release our lock on the data structures */ - up(&us_list_semaphore); + us = (struct us_data*)hostptr->hostdata[0]; /* if we couldn't find it, we return an error */ if (!us) { @@ -332,10 +307,8 @@ SPRINTF(" Protocol: %s\n", us->protocol_name); SPRINTF(" Transport: %s\n", us->transport_name); - /* show the GUID of the device */ - SPRINTF(" GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid)); - SPRINTF(" Attached: %s\n", (us->flags & US_FL_DEV_ATTACHED ? - "Yes" : "No")); + /* release the reference count on this host */ + scsi_host_put(hostptr); /* * Calculate start of next buffer, and return value. @@ -351,33 +324,69 @@ } /* - * this defines our 'host' + * this defines our host template, with which we'll allocate hosts */ -Scsi_Host_Template usb_stor_host_template = { - .name = "usb-storage", - .proc_info = proc_info, - .info = host_info, - - .detect = detect, - .release = release, - .command = command, - .queuecommand = queuecommand, - - .eh_abort_handler = command_abort, - .eh_device_reset_handler =device_reset, - .eh_bus_reset_handler = bus_reset, - .eh_host_reset_handler =host_reset, - - .can_queue = 1, - .this_id = -1, - - .sg_tablesize = SG_ALL, - .cmd_per_lun = 1, - .present = 0, - .unchecked_isa_dma = FALSE, - .use_clustering = TRUE, - .emulated = TRUE +struct SHT usb_stor_host_template = { + /* basic userland interface stuff */ + .name = "usb-storage", + .proc_name = "usb-storage", + .proc_info = usb_storage_proc_info, + .proc_dir = NULL, + .info = usb_storage_info, + .ioctl = NULL, + + /* old-style detect and release */ + .detect = NULL, + .release = NULL, + + /* command interface -- queued only */ + .command = NULL, + .queuecommand = usb_storage_queuecommand, + + /* error and abort handlers */ + .eh_abort_handler = usb_storage_command_abort, + .eh_device_reset_handler = usb_storage_device_reset, + .eh_bus_reset_handler = usb_storage_bus_reset, + .eh_host_reset_handler = NULL, + .eh_strategy_handler = NULL, + + /* queue commands only, only one command per LUN */ + .can_queue = 1, + .cmd_per_lun = 1, + + /* unknown initiator id */ + .this_id = -1, + + /* no limit on commands */ + .max_sectors = 0, + + /* pre- and post- device scan functions */ + .slave_alloc = NULL, + .slave_configure = NULL, + .slave_destroy = NULL, + + /* lots of sg segments can be handled */ + .sg_tablesize = SG_ALL, + + /* use 32-bit address space for DMA */ + .unchecked_isa_dma = FALSE, + .highmem_io = FALSE, + + /* merge commands... this seems to help performance, but + * periodically someone should test to see which setting is more + * optimal. + */ + .use_clustering = TRUE, + + /* emulated HBA */ + .emulated = TRUE, + + /* sorry, no BIOS to help us */ + .bios_param = NULL, + + /* module management */ + .module = THIS_MODULE }; /* For a device that is "Not Ready" */ diff -Nru a/drivers/usb/storage/scsiglue.h b/drivers/usb/storage/scsiglue.h --- a/drivers/usb/storage/scsiglue.h Sun Feb 9 21:13:32 2003 +++ b/drivers/usb/storage/scsiglue.h Sun Feb 9 21:13:32 2003 @@ -47,7 +47,7 @@ extern unsigned char usb_stor_sense_notready[18]; extern unsigned char usb_stor_sense_invalidCDB[18]; -extern Scsi_Host_Template usb_stor_host_template; +extern struct SHT usb_stor_host_template; extern int usb_stor_scsiSense10to6(Scsi_Cmnd*); extern int usb_stor_scsiSense6to10(Scsi_Cmnd*); diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c --- a/drivers/usb/storage/transport.c Sun Feb 9 21:13:31 2003 +++ b/drivers/usb/storage/transport.c Sun Feb 9 21:13:31 2003 @@ -697,7 +697,7 @@ /* set state to abort and release the lock */ atomic_set(&us->sm_state, US_STATE_ABORTING); - host = us->srb->host; + host = us->srb->device->host; scsi_unlock(host); /* If the state machine is blocked waiting for an URB, @@ -895,7 +895,7 @@ bcb.Tag = srb->serial_number; bcb.Lun = srb->cmnd[1] >> 5; if (us->flags & US_FL_SCM_MULT_TARG) - bcb.Lun |= srb->target << 4; + bcb.Lun |= srb->device->id << 4; bcb.Length = srb->cmd_len; /* copy the command payload */ diff -Nru a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h --- a/drivers/usb/storage/transport.h Sun Feb 9 21:13:31 2003 +++ b/drivers/usb/storage/transport.h Sun Feb 9 21:13:31 2003 @@ -55,8 +55,7 @@ #define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */ #endif #ifdef CONFIG_USB_STORAGE_SDDR09 -#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for - SDDR-09 */ +#define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ #endif #ifdef CONFIG_USB_STORAGE_SDDR55 #define US_PR_SDDR55 0x82 /* SDDR-55 (made up) */ @@ -64,15 +63,15 @@ #define US_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ #ifdef CONFIG_USB_STORAGE_FREECOM -#define US_PR_FREECOM 0xf1 /* Freecom */ +#define US_PR_FREECOM 0xf1 /* Freecom */ #endif #ifdef CONFIG_USB_STORAGE_DATAFAB -#define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ +#define US_PR_DATAFAB 0xf2 /* Datafab chipsets */ #endif #ifdef CONFIG_USB_STORAGE_JUMPSHOT -#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ +#define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ #endif /* @@ -118,10 +117,10 @@ * usb_stor_bulk_transfer_xxx() return codes, in order of severity */ -#define USB_STOR_XFER_GOOD 0 /* good transfer */ -#define USB_STOR_XFER_SHORT 1 /* transfered less than expected */ -#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */ -#define USB_STOR_XFER_ERROR 3 /* transfer died in the middle */ +#define USB_STOR_XFER_GOOD 0 /* good transfer */ +#define USB_STOR_XFER_SHORT 1 /* transfered less than expected */ +#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */ +#define USB_STOR_XFER_ERROR 3 /* transfer died in the middle */ /* * Transport return codes diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h --- a/drivers/usb/storage/unusual_devs.h Sun Feb 9 21:13:35 2003 +++ b/drivers/usb/storage/unusual_devs.h Sun Feb 9 21:13:35 2003 @@ -264,7 +264,7 @@ /* Submitted by Nathan Babb */ UNUSUAL_DEV( 0x054c, 0x006d, 0x0000, 0x9999, - "Sony", + "Sony", "PEG Mass Storage", US_SC_8070, US_PR_CBI, NULL, US_FL_FIX_INQUIRY ), @@ -546,10 +546,10 @@ /* aeb */ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, - "Feiya", - "5-in-1 Card Reader", - US_SC_SCSI, US_PR_BULK, NULL, - US_FL_FIX_CAPACITY ), + "Feiya", + "5-in-1 Card Reader", + US_SC_SCSI, US_PR_BULK, NULL, + US_FL_FIX_CAPACITY ), UNUSUAL_DEV( 0x097a, 0x0001, 0x0000, 0x0001, "Minds@Work", diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c --- a/drivers/usb/storage/usb.c Sun Feb 9 21:13:30 2003 +++ b/drivers/usb/storage/usb.c Sun Feb 9 21:13:30 2003 @@ -93,16 +93,6 @@ MODULE_DESCRIPTION("USB Mass Storage driver for Linux"); MODULE_LICENSE("GPL"); -/* - * Per device data - */ - -static int my_host_number; - -/* The list of structures and the protective lock for them */ -struct us_data *us_list; -struct semaphore us_list_semaphore; - static int storage_probe(struct usb_interface *iface, const struct usb_device_id *id); @@ -311,15 +301,15 @@ daemonize(); /* avoid getting signals */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); flush_signals(current); current->flags |= PF_IOTHREAD; sigfillset(¤t->blocked); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); /* set our name for identification purposes */ - sprintf(current->comm, "usb-storage-%d", us->host_number); + sprintf(current->comm, "usb-storage"); unlock_kernel(); @@ -342,7 +332,7 @@ US_DEBUGP("-- exit command received\n"); break; } - host = us->srb->host; + host = us->srb->device->host; /* lock access to the state */ scsi_lock(host); @@ -371,16 +361,16 @@ /* reject if target != 0 or if LUN is higher than * the maximum known LUN */ - else if (us->srb->target && + else if (us->srb->device->id && !(us->flags & US_FL_SCM_MULT_TARG)) { US_DEBUGP("Bad target number (%d/%d)\n", - us->srb->target, us->srb->lun); + us->srb->device->id, us->srb->device->lun); us->srb->result = DID_BAD_TARGET << 16; } - else if (us->srb->lun > us->max_lun) { + else if (us->srb->device->lun > us->max_lun) { US_DEBUGP("Bad LUN (%d/%d)\n", - us->srb->target, us->srb->lun); + us->srb->device->id, us->srb->device->lun); us->srb->result = DID_BAD_TARGET << 16; } @@ -395,35 +385,6 @@ us->srb->result = CHECK_CONDITION << 1; } - /* our device has gone - pretend not ready */ - else if (!(us->flags & US_FL_DEV_ATTACHED)) { - US_DEBUGP("Request is for removed device\n"); - /* For REQUEST_SENSE, it's the data. But - * for anything else, it should look like - * we auto-sensed for it. - */ - if (us->srb->cmnd[0] == REQUEST_SENSE) { - memcpy(us->srb->request_buffer, - usb_stor_sense_notready, - sizeof(usb_stor_sense_notready)); - us->srb->result = GOOD << 1; - } else if(us->srb->cmnd[0] == INQUIRY) { - /* INQUIRY should always work, per spec... */ - unsigned char data_ptr[36] = { - 0x20, 0x80, 0x02, 0x02, - 0x1F, 0x00, 0x00, 0x00}; - US_DEBUGP("Faking INQUIRY command for disconnected device\n"); - fill_inquiry_response(us, data_ptr, 36); - us->srb->result = GOOD << 1; - } else { - /* not ready */ - memcpy(us->srb->sense_buffer, - usb_stor_sense_notready, - sizeof(usb_stor_sense_notready)); - us->srb->result = CHECK_CONDITION << 1; - } - } /* !(us->flags & US_FL_DEV_ATTACHED) */ - /* Handle those devices which need us to fake * their inquiry data */ else if ((us->srb->cmnd[0] == INQUIRY) && @@ -547,7 +508,6 @@ } /* mark the device as gone */ - ss->flags &= ~ US_FL_DEV_ATTACHED; usb_put_dev(ss->pusb_dev); ss->pusb_dev = NULL; } @@ -563,12 +523,10 @@ char mf[USB_STOR_STRING_LEN]; /* manufacturer */ char prod[USB_STOR_STRING_LEN]; /* product */ char serial[USB_STOR_STRING_LEN]; /* serial number */ - GUID(guid); /* Global Unique Identifier */ unsigned int flags; struct us_unusual_dev *unusual_dev; struct us_data *ss = NULL; int result; - int new_device = 0; /* these are temporary copies -- we test on these, then put them * in the us-data structure @@ -676,8 +634,7 @@ /* At this point, we've decided to try to use the device */ usb_get_dev(dev); - /* clear the GUID and fetch the strings */ - GUID_CLEAR(guid); + /* fetch the strings */ if (dev->descriptor.iManufacturer) usb_string(dev, dev->descriptor.iManufacturer, mf, sizeof(mf)); @@ -688,346 +645,277 @@ usb_string(dev, dev->descriptor.iSerialNumber, serial, sizeof(serial)); - /* Create a GUID for this device */ - if (dev->descriptor.iSerialNumber && serial[0]) { - /* If we have a serial number, and it's a non-NULL string */ - make_guid(guid, dev->descriptor.idVendor, - dev->descriptor.idProduct, serial); - } else { - /* We don't have a serial number, so we use 0 */ - make_guid(guid, dev->descriptor.idVendor, - dev->descriptor.idProduct, "0"); + /* New device -- allocate memory and initialize */ + if ((ss = (struct us_data *)kmalloc(sizeof(struct us_data), + GFP_KERNEL)) == NULL) { + printk(KERN_WARNING USB_STORAGE "Out of memory\n"); + usb_put_dev(dev); + return -ENOMEM; + } + memset(ss, 0, sizeof(struct us_data)); + + /* Initialize the mutexes only when the struct is new */ + init_completion(&(ss->notify)); + init_MUTEX_LOCKED(&(ss->dev_semaphore)); + + /* copy over the subclass and protocol data */ + ss->subclass = subclass; + ss->protocol = protocol; + ss->flags = flags; + ss->unusual_dev = unusual_dev; + + /* copy over the endpoint data */ + ss->ep_in = ep_in->bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; + ss->ep_out = ep_out->bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; + if (ep_int) { + ss->ep_int = ep_int->bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; + ss->ep_bInterval = ep_int->bInterval; } + else + ss->ep_int = ss->ep_bInterval = 0; - /* - * Now check if we have seen this GUID before - * We're looking for a device with a matching GUID that isn't - * already on the system - */ - ss = us_list; - while ((ss != NULL) && - ((ss->flags & US_FL_DEV_ATTACHED) || - !GUID_EQUAL(guid, ss->guid))) - ss = ss->next; - - if (ss != NULL) { - /* Existing device -- re-connect */ - US_DEBUGP("Found existing GUID " GUID_FORMAT "\n", - GUID_ARGS(guid)); - - /* lock the device pointers */ - down(&(ss->dev_semaphore)); - - /* establish the connection to the new device upon reconnect */ - ss->ifnum = ifnum; - ss->pusb_dev = dev; - ss->flags |= US_FL_DEV_ATTACHED; - - /* copy over the endpoint data */ - ss->ep_in = ep_in->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - ss->ep_out = ep_out->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - if (ep_int) { - ss->ep_int = ep_int->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - ss->ep_bInterval = ep_int->bInterval; - } + /* establish the connection to the new device */ + ss->ifnum = ifnum; + ss->pusb_dev = dev; + + /* copy over the identifiying strings */ + strncpy(ss->vendor, mf, USB_STOR_STRING_LEN); + strncpy(ss->product, prod, USB_STOR_STRING_LEN); + strncpy(ss->serial, serial, USB_STOR_STRING_LEN); + if (strlen(ss->vendor) == 0) { + if (unusual_dev->vendorName) + strncpy(ss->vendor, unusual_dev->vendorName, + USB_STOR_STRING_LEN); else - ss->ep_int = ss->ep_bInterval = 0; - - /* allocate the URB, the usb_ctrlrequest, and the IRQ URB */ - if (usb_stor_allocate_urbs(ss)) - goto BadDevice; - - /* Re-Initialize the device if it needs it */ - if (unusual_dev && unusual_dev->initFunction) - (unusual_dev->initFunction)(ss); - - /* unlock the device pointers */ - up(&(ss->dev_semaphore)); - - } else { - /* New device -- allocate memory and initialize */ - US_DEBUGP("New GUID " GUID_FORMAT "\n", GUID_ARGS(guid)); - - if ((ss = (struct us_data *)kmalloc(sizeof(struct us_data), - GFP_KERNEL)) == NULL) { - printk(KERN_WARNING USB_STORAGE "Out of memory\n"); - usb_put_dev(dev); - return -ENOMEM; - } - memset(ss, 0, sizeof(struct us_data)); - new_device = 1; - - /* Initialize the mutexes only when the struct is new */ - init_completion(&(ss->notify)); - init_MUTEX_LOCKED(&(ss->dev_semaphore)); - - /* copy over the subclass and protocol data */ - ss->subclass = subclass; - ss->protocol = protocol; - ss->flags = flags | US_FL_DEV_ATTACHED; - ss->unusual_dev = unusual_dev; - - /* copy over the endpoint data */ - ss->ep_in = ep_in->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - ss->ep_out = ep_out->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - if (ep_int) { - ss->ep_int = ep_int->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - ss->ep_bInterval = ep_int->bInterval; - } + strncpy(ss->vendor, "Unknown", + USB_STOR_STRING_LEN); + } + if (strlen(ss->product) == 0) { + if (unusual_dev->productName) + strncpy(ss->product, unusual_dev->productName, + USB_STOR_STRING_LEN); else - ss->ep_int = ss->ep_bInterval = 0; - - /* establish the connection to the new device */ - ss->ifnum = ifnum; - ss->pusb_dev = dev; - - /* copy over the identifiying strings */ - strncpy(ss->vendor, mf, USB_STOR_STRING_LEN); - strncpy(ss->product, prod, USB_STOR_STRING_LEN); - strncpy(ss->serial, serial, USB_STOR_STRING_LEN); - if (strlen(ss->vendor) == 0) { - if (unusual_dev->vendorName) - strncpy(ss->vendor, unusual_dev->vendorName, - USB_STOR_STRING_LEN); - else - strncpy(ss->vendor, "Unknown", - USB_STOR_STRING_LEN); - } - if (strlen(ss->product) == 0) { - if (unusual_dev->productName) - strncpy(ss->product, unusual_dev->productName, - USB_STOR_STRING_LEN); - else - strncpy(ss->product, "Unknown", - USB_STOR_STRING_LEN); - } - if (strlen(ss->serial) == 0) - strncpy(ss->serial, "None", USB_STOR_STRING_LEN); - - /* copy the GUID we created before */ - memcpy(ss->guid, guid, sizeof(guid)); - - /* - * Set the handler pointers based on the protocol - * Again, this data is persistant across reattachments - */ - switch (ss->protocol) { - case US_PR_CB: - ss->transport_name = "Control/Bulk"; - ss->transport = usb_stor_CB_transport; - ss->transport_reset = usb_stor_CB_reset; - ss->max_lun = 7; - break; - - case US_PR_CBI: - ss->transport_name = "Control/Bulk/Interrupt"; - ss->transport = usb_stor_CBI_transport; - ss->transport_reset = usb_stor_CB_reset; - ss->max_lun = 7; - break; + strncpy(ss->product, "Unknown", + USB_STOR_STRING_LEN); + } + if (strlen(ss->serial) == 0) + strncpy(ss->serial, "None", USB_STOR_STRING_LEN); - case US_PR_BULK: - ss->transport_name = "Bulk"; - ss->transport = usb_stor_Bulk_transport; - ss->transport_reset = usb_stor_Bulk_reset; - ss->max_lun = usb_stor_Bulk_max_lun(ss); - break; + /* + * Set the handler pointers based on the protocol + * Again, this data is persistent across reattachments + */ + switch (ss->protocol) { + case US_PR_CB: + ss->transport_name = "Control/Bulk"; + ss->transport = usb_stor_CB_transport; + ss->transport_reset = usb_stor_CB_reset; + ss->max_lun = 7; + break; + + case US_PR_CBI: + ss->transport_name = "Control/Bulk/Interrupt"; + ss->transport = usb_stor_CBI_transport; + ss->transport_reset = usb_stor_CB_reset; + ss->max_lun = 7; + break; + + case US_PR_BULK: + ss->transport_name = "Bulk"; + ss->transport = usb_stor_Bulk_transport; + ss->transport_reset = usb_stor_Bulk_reset; + ss->max_lun = usb_stor_Bulk_max_lun(ss); + break; #ifdef CONFIG_USB_STORAGE_HP8200e - case US_PR_SCM_ATAPI: - ss->transport_name = "SCM/ATAPI"; - ss->transport = hp8200e_transport; - ss->transport_reset = usb_stor_CB_reset; - ss->max_lun = 1; - break; + case US_PR_SCM_ATAPI: + ss->transport_name = "SCM/ATAPI"; + ss->transport = hp8200e_transport; + ss->transport_reset = usb_stor_CB_reset; + ss->max_lun = 1; + break; #endif #ifdef CONFIG_USB_STORAGE_SDDR09 - case US_PR_EUSB_SDDR09: - ss->transport_name = "EUSB/SDDR09"; - ss->transport = sddr09_transport; - ss->transport_reset = usb_stor_CB_reset; - ss->max_lun = 0; - break; + case US_PR_EUSB_SDDR09: + ss->transport_name = "EUSB/SDDR09"; + ss->transport = sddr09_transport; + ss->transport_reset = usb_stor_CB_reset; + ss->max_lun = 0; + break; #endif #ifdef CONFIG_USB_STORAGE_SDDR55 - case US_PR_SDDR55: - ss->transport_name = "SDDR55"; - ss->transport = sddr55_transport; - ss->transport_reset = sddr55_reset; - ss->max_lun = 0; - break; + case US_PR_SDDR55: + ss->transport_name = "SDDR55"; + ss->transport = sddr55_transport; + ss->transport_reset = sddr55_reset; + ss->max_lun = 0; + break; #endif #ifdef CONFIG_USB_STORAGE_DPCM - case US_PR_DPCM_USB: - ss->transport_name = "Control/Bulk-EUSB/SDDR09"; - ss->transport = dpcm_transport; - ss->transport_reset = usb_stor_CB_reset; - ss->max_lun = 1; - break; + case US_PR_DPCM_USB: + ss->transport_name = "Control/Bulk-EUSB/SDDR09"; + ss->transport = dpcm_transport; + ss->transport_reset = usb_stor_CB_reset; + ss->max_lun = 1; + break; #endif #ifdef CONFIG_USB_STORAGE_FREECOM - case US_PR_FREECOM: - ss->transport_name = "Freecom"; - ss->transport = freecom_transport; - ss->transport_reset = usb_stor_freecom_reset; - ss->max_lun = 0; - break; + case US_PR_FREECOM: + ss->transport_name = "Freecom"; + ss->transport = freecom_transport; + ss->transport_reset = usb_stor_freecom_reset; + ss->max_lun = 0; + break; #endif #ifdef CONFIG_USB_STORAGE_DATAFAB - case US_PR_DATAFAB: - ss->transport_name = "Datafab Bulk-Only"; - ss->transport = datafab_transport; - ss->transport_reset = usb_stor_Bulk_reset; - ss->max_lun = 1; - break; + case US_PR_DATAFAB: + ss->transport_name = "Datafab Bulk-Only"; + ss->transport = datafab_transport; + ss->transport_reset = usb_stor_Bulk_reset; + ss->max_lun = 1; + break; #endif #ifdef CONFIG_USB_STORAGE_JUMPSHOT - case US_PR_JUMPSHOT: - ss->transport_name = "Lexar Jumpshot Control/Bulk"; - ss->transport = jumpshot_transport; - ss->transport_reset = usb_stor_Bulk_reset; - ss->max_lun = 1; - break; + case US_PR_JUMPSHOT: + ss->transport_name = "Lexar Jumpshot Control/Bulk"; + ss->transport = jumpshot_transport; + ss->transport_reset = usb_stor_Bulk_reset; + ss->max_lun = 1; + break; #endif - default: - /* ss->transport_name = "Unknown"; */ - goto BadDevice; - } - US_DEBUGP("Transport: %s\n", ss->transport_name); - - /* fix for single-lun devices */ - if (ss->flags & US_FL_SINGLE_LUN) - ss->max_lun = 0; - - switch (ss->subclass) { - case US_SC_RBC: - ss->protocol_name = "Reduced Block Commands (RBC)"; - ss->proto_handler = usb_stor_transparent_scsi_command; - break; - - case US_SC_8020: - ss->protocol_name = "8020i"; - ss->proto_handler = usb_stor_ATAPI_command; - ss->max_lun = 0; - break; - - case US_SC_QIC: - ss->protocol_name = "QIC-157"; - ss->proto_handler = usb_stor_qic157_command; - ss->max_lun = 0; - break; - - case US_SC_8070: - ss->protocol_name = "8070i"; - ss->proto_handler = usb_stor_ATAPI_command; - ss->max_lun = 0; - break; - - case US_SC_SCSI: - ss->protocol_name = "Transparent SCSI"; - ss->proto_handler = usb_stor_transparent_scsi_command; - break; - - case US_SC_UFI: - ss->protocol_name = "Uniform Floppy Interface (UFI)"; - ss->proto_handler = usb_stor_ufi_command; - break; + default: + /* ss->transport_name = "Unknown"; */ + goto BadDevice; + } + US_DEBUGP("Transport: %s\n", ss->transport_name); + + /* fix for single-lun devices */ + if (ss->flags & US_FL_SINGLE_LUN) + ss->max_lun = 0; + + switch (ss->subclass) { + case US_SC_RBC: + ss->protocol_name = "Reduced Block Commands (RBC)"; + ss->proto_handler = usb_stor_transparent_scsi_command; + break; + + case US_SC_8020: + ss->protocol_name = "8020i"; + ss->proto_handler = usb_stor_ATAPI_command; + ss->max_lun = 0; + break; + + case US_SC_QIC: + ss->protocol_name = "QIC-157"; + ss->proto_handler = usb_stor_qic157_command; + ss->max_lun = 0; + break; + + case US_SC_8070: + ss->protocol_name = "8070i"; + ss->proto_handler = usb_stor_ATAPI_command; + ss->max_lun = 0; + break; + + case US_SC_SCSI: + ss->protocol_name = "Transparent SCSI"; + ss->proto_handler = usb_stor_transparent_scsi_command; + break; + + case US_SC_UFI: + ss->protocol_name = "Uniform Floppy Interface (UFI)"; + ss->proto_handler = usb_stor_ufi_command; + break; #ifdef CONFIG_USB_STORAGE_ISD200 - case US_SC_ISD200: - ss->protocol_name = "ISD200 ATA/ATAPI"; - ss->proto_handler = isd200_ata_command; - break; + case US_SC_ISD200: + ss->protocol_name = "ISD200 ATA/ATAPI"; + ss->proto_handler = isd200_ata_command; + break; #endif - default: - /* ss->protocol_name = "Unknown"; */ - goto BadDevice; - } - US_DEBUGP("Protocol: %s\n", ss->protocol_name); - - /* allocate the URB, the usb_ctrlrequest, and the IRQ URB */ - if (usb_stor_allocate_urbs(ss)) - goto BadDevice; - - /* - * Since this is a new device, we need to generate a scsi - * host definition, and register with the higher SCSI layers - */ - - /* Initialize the host template based on the default one */ - memcpy(&(ss->htmplt), &usb_stor_host_template, - sizeof(usb_stor_host_template)); - - /* Grab the next host number */ - ss->host_number = my_host_number++; - - /* We abuse this pointer so we can pass the ss pointer to - * the host controller thread in us_detect. But how else are - * we to do it? - */ - (struct us_data *)ss->htmplt.proc_dir = ss; - - /* Just before we start our control thread, initialize - * the device if it needs initialization */ - if (unusual_dev && unusual_dev->initFunction) - unusual_dev->initFunction(ss); - - /* start up our control thread */ - atomic_set(&ss->sm_state, US_STATE_IDLE); - ss->pid = kernel_thread(usb_stor_control_thread, ss, - CLONE_VM); - if (ss->pid < 0) { - printk(KERN_WARNING USB_STORAGE - "Unable to start control thread\n"); - goto BadDevice; - } - - /* wait for the thread to start */ - wait_for_completion(&(ss->notify)); + default: + /* ss->protocol_name = "Unknown"; */ + goto BadDevice; + } + US_DEBUGP("Protocol: %s\n", ss->protocol_name); + + /* allocate the URB, the usb_ctrlrequest, and the IRQ URB */ + if (usb_stor_allocate_urbs(ss)) + goto BadDevice; - /* unlock the device pointers */ - up(&(ss->dev_semaphore)); + /* + * Since this is a new device, we need to generate a scsi + * host definition, and register with the higher SCSI layers + */ - /* now register - our detect function will be called */ - ss->htmplt.module = THIS_MODULE; - result = scsi_register_host(&(ss->htmplt)); - if (result) { - printk(KERN_WARNING USB_STORAGE - "Unable to register the scsi host\n"); - - /* tell the control thread to exit */ - ss->srb = NULL; - up(&ss->sema); - wait_for_completion(&ss->notify); - - /* re-lock the device pointers */ - down(&ss->dev_semaphore); - goto BadDevice; - } + /* Just before we start our control thread, initialize + * the device if it needs initialization */ + if (unusual_dev && unusual_dev->initFunction) + unusual_dev->initFunction(ss); + + /* start up our control thread */ + atomic_set(&ss->sm_state, US_STATE_IDLE); + ss->pid = kernel_thread(usb_stor_control_thread, ss, + CLONE_VM); + if (ss->pid < 0) { + printk(KERN_WARNING USB_STORAGE + "Unable to start control thread\n"); + goto BadDevice; + } - /* lock access to the data structures */ - down(&us_list_semaphore); + /* wait for the thread to start */ + wait_for_completion(&(ss->notify)); - /* put us in the list */ - ss->next = us_list; - us_list = ss; + /* unlock the device pointers */ + up(&(ss->dev_semaphore)); - /* release the data structure lock */ - up(&us_list_semaphore); + /* now register */ + ss->host = scsi_register(&usb_stor_host_template, sizeof(ss)); + if (!ss->host) { + printk(KERN_WARNING USB_STORAGE + "Unable to register the scsi host\n"); + + /* tell the control thread to exit */ + ss->srb = NULL; + up(&ss->sema); + wait_for_completion(&ss->notify); + + /* re-lock the device pointers */ + down(&ss->dev_semaphore); + goto BadDevice; + } + + /* set the hostdata to prepare for scanning */ + ss->host->hostdata[0] = (unsigned long)ss; + + /* associate this host with our interface */ + scsi_set_device(ss->host, &intf->dev); + + /* now add the host */ + result = scsi_add_host(ss->host, NULL); + if (result) { + printk(KERN_WARNING USB_STORAGE + "Unable to add the scsi host\n"); + + /* tell the control thread to exit */ + ss->srb = NULL; + up(&ss->sema); + wait_for_completion(&ss->notify); + + /* re-lock the device pointers */ + down(&ss->dev_semaphore); + goto BadDevice; } printk(KERN_DEBUG @@ -1041,33 +929,96 @@ /* we come here if there are any problems */ /* ss->dev_semaphore must be locked */ - BadDevice: +BadDevice: US_DEBUGP("storage_probe() failed\n"); usb_stor_deallocate_urbs(ss); up(&ss->dev_semaphore); - if (new_device) - kfree(ss); + kfree(ss); return -EIO; } /* Handle a disconnect event from the USB core */ static void storage_disconnect(struct usb_interface *intf) { - struct us_data *ss = usb_get_intfdata(intf); + struct us_data *ss; + struct scsi_device *sdev; US_DEBUGP("storage_disconnect() called\n"); + ss = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); - /* this is the odd case -- we disconnected but weren't using it */ - if (!ss) { - US_DEBUGP("-- device was not in use\n"); - return; - } + /* serious error -- we're attempting to disconnect an interface but + * cannot locate the local data structure + */ + BUG_ON(ss == NULL); + /* set devices offline -- need host lock for this */ + scsi_lock(ss->host); + list_for_each_entry(sdev, &ss->host->my_devices, siblings) + sdev->online = 0; + scsi_unlock(ss->host); + + /* lock device access -- no need to unlock, as we're going away */ down(&(ss->dev_semaphore)); + + /* Complete all pending commands with * cmd->result = DID_ERROR << 16. + * Since we only queue one command at a time, this is pretty easy. */ + if (ss->srb) { + ss->srb->result = DID_ERROR << 16; + ss->srb->scsi_done(ss->srb); + } + + /* TODO: somehow, wait for the device to + * be 'idle' (tasklet completion) */ + + /* remove the pointer to the data structure we were using */ + (struct us_data*)ss->host->hostdata[0] = NULL; + + /* begin SCSI host removal sequence */ + if(scsi_remove_host(ss->host)) { + US_DEBUGP("-- SCSI refused to unregister\n"); + BUG(); + return; + }; + + /* finish SCSI host removal sequence */ + scsi_unregister(ss->host); + + /* Kill the control threads + * + * Enqueue the command, wake up the thread, and wait for + * notification that it has exited. + */ + US_DEBUGP("-- sending exit command to thread\n"); + BUG_ON(atomic_read(&ss->sm_state) != US_STATE_IDLE); + ss->srb = NULL; + up(&(ss->sema)); + wait_for_completion(&(ss->notify)); + + /* free allocated urbs */ usb_stor_deallocate_urbs(ss); + + /* If there's extra data in the us_data structure then + * free that first */ + if (ss->extra) { + /* call the destructor routine, if it exists */ + if (ss->extra_destructor) { + US_DEBUGP("-- calling extra_destructor()\n"); + ss->extra_destructor(ss->extra); + } + + /* destroy the extra data */ + US_DEBUGP("-- freeing the data structure\n"); + kfree(ss->extra); + } + + /* up the semaphore so auto-code-checkers won't complain about + * the down/up imbalance */ up(&(ss->dev_semaphore)); + + /* free the structure itself */ + kfree (ss); } /*********************************************************************** @@ -1078,11 +1029,6 @@ { printk(KERN_INFO "Initializing USB Mass Storage driver...\n"); - /* initialize internal global data elements */ - us_list = NULL; - init_MUTEX(&us_list_semaphore); - my_host_number = 0; - /* register the driver, return -1 if error */ if (usb_register(&usb_storage_driver) < 0) return -1; @@ -1094,16 +1040,16 @@ void __exit usb_stor_exit(void) { - struct us_data *next; - US_DEBUGP("usb_stor_exit() called\n"); /* Deregister the driver - * This eliminates races with probes and disconnects + * This will cause disconnect() to be called for each + * attached unit */ US_DEBUGP("-- calling usb_deregister()\n"); usb_deregister(&usb_storage_driver) ; +#if 0 /* While there are still virtual hosts, unregister them * Note that it's important to do this completely before removing * the structures because of possible races with the /proc @@ -1111,7 +1057,7 @@ */ for (next = us_list; next; next = next->next) { US_DEBUGP("-- calling scsi_unregister_host()\n"); - scsi_unregister_host(&(next->htmplt)); + scsi_unregister_host(&usb_stor_host_template); } /* While there are still structures, free them. Note that we are @@ -1137,11 +1083,12 @@ } /* free the structure itself */ - kfree (us_list); + kfree (us_list); /* advance the list pointer */ us_list = next; } +#endif } module_init(usb_stor_init); diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h --- a/drivers/usb/storage/usb.h Sun Feb 9 21:13:33 2003 +++ b/drivers/usb/storage/usb.h Sun Feb 9 21:13:33 2003 @@ -52,33 +52,6 @@ #include "scsi.h" #include "hosts.h" -/* - * GUID definitions - */ - -#define GUID(x) __u32 x[3] -#define GUID_EQUAL(x, y) (x[0] == y[0] && x[1] == y[1] && x[2] == y[2]) -#define GUID_CLEAR(x) x[0] = x[1] = x[2] = 0; -#define GUID_NONE(x) (!x[0] && !x[1] && !x[2]) -#define GUID_FORMAT "%08x%08x%08x" -#define GUID_ARGS(x) x[0], x[1], x[2] - -static inline void make_guid( __u32 *pg, __u16 vendor, __u16 product, char *serial) -{ - pg[0] = (vendor << 16) | product; - pg[1] = pg[2] = 0; - while (*serial) { - pg[1] <<= 4; - pg[1] |= pg[2] >> 28; - pg[2] <<= 4; - if (*serial >= 'a') - *serial -= 'a' - 'A'; - pg[2] |= (*serial <= '9' && *serial >= '0') ? *serial - '0' - : *serial - 'A' + 10; - serial++; - } -} - struct us_data; /* @@ -104,7 +77,6 @@ #define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs fixing */ #define US_FL_FIX_CAPACITY 0x00000080 /* READ CAPACITY response too big */ -#define US_FL_DEV_ATTACHED 0x00010000 /* is the device attached? */ #define US_FLIDX_CAN_CANCEL 18 /* 0x00040000 okay to cancel current_urb? */ #define US_FLIDX_CANCEL_SG 19 /* 0x00080000 okay to cancel current_sg? */ @@ -124,12 +96,9 @@ /* we allocate one of these for every device that we remember */ struct us_data { - struct us_data *next; /* next device */ - /* The device we're working with * It's important to note: * (o) you must hold dev_semaphore to change pusb_dev - * (o) DEV_ATTACHED in flags should change whenever pusb_dev does */ struct semaphore dev_semaphore; /* protect pusb_dev */ struct usb_device *pusb_dev; /* this usb_device */ @@ -163,11 +132,7 @@ proto_cmnd proto_handler; /* protocol handler */ /* SCSI interfaces */ - GUID(guid); /* unique dev id */ struct Scsi_Host *host; /* our dummy host data */ - Scsi_Host_Template htmplt; /* own host template */ - int host_number; /* to find us */ - int host_no; /* allocated by scsi */ Scsi_Cmnd *srb; /* current srb */ /* thread information */ @@ -191,10 +156,6 @@ void *extra; /* Any extra data */ extra_data_destructor extra_destructor;/* extra data destructor */ }; - -/* The list of structures and the protective lock for them */ -extern struct us_data *us_list; -extern struct semaphore us_list_semaphore; /* The structure which defines our driver */ extern struct usb_driver usb_storage_driver; diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig --- a/drivers/video/Kconfig Sun Feb 9 21:13:28 2003 +++ b/drivers/video/Kconfig Sun Feb 9 21:13:28 2003 @@ -160,7 +160,7 @@ The driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The - module will be called amifb.o. If you want to compile it as a + module will be called amifb. If you want to compile it as a module, say M here and read . config FB_AMIGA_OCS @@ -292,7 +292,7 @@ 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 - vga16fb.o. + vga16fb. config FB_STI tristate "HP STI frame buffer device support" @@ -350,7 +350,7 @@ This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). - The module will be called hgafb.o. If you want to compile it as + The module will be called hgafb. If you want to compile it as a module, say M here and read . As this card technology is 15 years old, most people will answer N @@ -406,7 +406,7 @@ This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). - The module will be called pvr2fb.o. If you want to compile it as + The module will be called pvr2fb. If you want to compile it as a module, say M here and read . You can pass several parameters to the driver at boot time or at @@ -462,7 +462,7 @@ The driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The - module will be called rivafb.o. If you want to compile it as a + module will be called rivafb. If you want to compile it as a module, say M here and read . config FB_I810 @@ -474,7 +474,7 @@ The driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). - The module will be called i810fb.o. If you want to compile it as a + The module will be called i810fb. If you want to compile it as a module, say M here and read . For more information, please read @@ -514,7 +514,7 @@ This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). - The module will be called matroxfb.o. If you want to compile it as + The module will be called matroxfb. If you want to compile it as a module, say M here and read . You can pass several parameters to the driver at boot time or at @@ -606,7 +606,7 @@ second head of G400 or MGA-TVO on G200 or G400. If you compile it as module, it will create a module named - i2c-matroxfb.o. + i2c-matroxfb. config FB_MATROX_MAVEN tristate "G400 second head support" @@ -622,7 +622,7 @@ the fbdev driver on first head and the fbdev driver on second head. If you compile it as module, two modules are created, - matroxfb_crtc2.o and matroxfb_maven.o. Matroxfb_maven is needed for + matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for both G200 and G400, matroxfb_crtc2 is needed only by G400. You must also load i2c-matroxfb to get it to run. @@ -651,7 +651,7 @@ If you said M to "Matrox unified accelerated driver" and N here, you will still be able to use several Matrox devices simultaneously: - insert several instances of the module matroxfb.o into the kernel + insert several instances of the module matroxfb into the kernel with insmod, supplying the parameter "dev=N" where N is 0, 1, etc. for the different Matrox devices. This method is slightly faster but uses 40 KB of kernel memory per Matrox card. @@ -679,7 +679,7 @@ The driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The - module will be called aty128fb.o. If you want to compile it as a + module will be called aty128fb. If you want to compile it as a module, say M here and read . config FB_ATY @@ -691,7 +691,7 @@ The driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The - module will be called atyfb.o. If you want to compile it as a + module will be called atyfb. If you want to compile it as a module, say M here and read . config FB_ATY_CT @@ -746,7 +746,7 @@ The driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The - module will be called neofb.o. If you want to compile it as a + module will be called neofb. If you want to compile it as a module, say M here and read Documentation/modules.txt. config FB_3DFX @@ -758,7 +758,7 @@ The driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The - module will be called tdfxfb.o. If you want to compile it as a + module will be called tdfxfb. If you want to compile it as a module, say M here and read . config FB_VOODOO1 @@ -770,7 +770,7 @@ This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). - The module will be called sstfb.o. If you want to compile it as + The module will be called sstfb. If you want to compile it as a module, say M here and read Documentation/modules.txt. WARNING: Do not use any application that uses the 3D engine @@ -791,7 +791,7 @@ The driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The - module will be called tridentfb.o. If you want to compile it as a + module will be called tridentfb. If you want to compile it as a module, say M here and read . config FB_PM3 @@ -917,7 +917,7 @@ This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The - module will be called vfb.o. If you want to compile it as a module, + module will be called vfb. If you want to compile it as a module, say M here and read . If unsure, say N. diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile --- a/drivers/video/Makefile Sun Feb 9 21:13:29 2003 +++ b/drivers/video/Makefile Sun Feb 9 21:13:29 2003 @@ -2,12 +2,6 @@ # 5 Aug 1999, James Simmons, # Rewritten to use lists instead of if-statements. -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := fbmem.o fbcmap.o fbmon.o modedb.o softcursor.o cfbfillrect.o \ - cfbcopyarea.o cfbimgblt.o cyber2000fb.o vgastate.o - # Each configuration option enables a list of files. obj-$(CONFIG_VT) += console/ diff -Nru a/drivers/video/acornfb.c b/drivers/video/acornfb.c --- a/drivers/video/acornfb.c Sun Feb 9 21:13:36 2003 +++ b/drivers/video/acornfb.c Sun Feb 9 21:13:36 2003 @@ -896,6 +896,7 @@ .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_mmap = acornfb_mmap, + .fb_cursor = soft_cursor, }; /* diff -Nru a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c --- a/drivers/video/aty/atyfb_base.c Sun Feb 9 21:13:34 2003 +++ b/drivers/video/aty/atyfb_base.c Sun Feb 9 21:13:34 2003 @@ -2587,12 +2587,12 @@ if (info->screen_base) iounmap((void *) info->screen_base); #ifdef __BIG_ENDIAN - if (info->cursor && par->cursor->ram) + if (par->cursor && par->cursor->ram) iounmap(par->cursor->ram); #endif #endif - if (info->cursor) - kfree(info->cursor); + if (par->cursor) + kfree(par->cursor); #ifdef __sparc__ if (par->mmap_map) kfree(par->mmap_map); diff -Nru a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig --- a/drivers/video/console/Kconfig Sun Feb 9 21:13:29 2003 +++ b/drivers/video/console/Kconfig Sun Feb 9 21:13:29 2003 @@ -52,7 +52,7 @@ This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). - The module will be called mdacon.o. If you want to compile it as + The module will be called mdacon. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -131,7 +131,7 @@ Low level frame buffer console drivers can be modules ( = code which can be inserted and removed from the running kernel whenever you - want). The modules will be called fbcon-*.o. If you want to compile + want). The modules will be called fbcon-*. If you want to compile (some of) them as modules, read . If unsure, say N. diff -Nru a/drivers/video/console/Makefile b/drivers/video/console/Makefile --- a/drivers/video/console/Makefile Sun Feb 9 21:13:32 2003 +++ b/drivers/video/console/Makefile Sun Feb 9 21:13:32 2003 @@ -2,11 +2,6 @@ # 5 Aug 1999, James Simmons, # Rewritten to use lists instead of if-statements. -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := fbcon.o fonts.o - # Font handling font-objs := fonts.o diff -Nru a/drivers/video/matrox/Makefile b/drivers/video/matrox/Makefile --- a/drivers/video/matrox/Makefile Sun Feb 9 21:13:30 2003 +++ b/drivers/video/matrox/Makefile Sun Feb 9 21:13:30 2003 @@ -2,11 +2,6 @@ # 5 Aug 1999, James Simmons, # Rewritten to use lists instead of if-statements. -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := matroxfb_base.o matroxfb_accel.o matroxfb_DAC1064.o matroxfb_Ti3026.o matroxfb_misc.o g450_pll.o matroxfb_g450.o - # Each configuration option enables a list of files. my-obj-$(CONFIG_FB_MATROX_G100) += g450_pll.o diff -Nru a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c --- a/drivers/video/riva/fbdev.c Sun Feb 9 21:13:34 2003 +++ b/drivers/video/riva/fbdev.c Sun Feb 9 21:13:34 2003 @@ -1759,7 +1759,7 @@ case NV_ARCH_03: /* Riva128's PRAMIN is in the "framebuffer" space * Since these cards were never made with more than 8 megabytes - * we can safely allocate this seperately. + * we can safely allocate this separately. */ if (!request_mem_region(rivafb_fix.smem_start + 0x00C00000, 0x00008000, "rivafb")) { diff -Nru a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c --- a/drivers/video/sa1100fb.c Sun Feb 9 21:13:30 2003 +++ b/drivers/video/sa1100fb.c Sun Feb 9 21:13:30 2003 @@ -1122,6 +1122,7 @@ .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_blank = sa1100fb_blank, + .fb_cursor = soft_cursor, }; /* diff -Nru a/drivers/video/sis/Makefile b/drivers/video/sis/Makefile --- a/drivers/video/sis/Makefile Sun Feb 9 21:13:36 2003 +++ b/drivers/video/sis/Makefile Sun Feb 9 21:13:36 2003 @@ -2,8 +2,6 @@ # Makefile for the SiS framebuffer device driver # -export-objs := sis_main.o - obj-$(CONFIG_FB_SIS) += sisfb.o sisfb-objs := sis_main.o sis_accel.o init.o init301.o diff -Nru a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c --- a/drivers/video/skeletonfb.c Sun Feb 9 21:13:29 2003 +++ b/drivers/video/skeletonfb.c Sun Feb 9 21:13:29 2003 @@ -19,7 +19,7 @@ * struct vc_data to data in a device independent way in struct fb_info. Then * various functions in struct fb_ops will be called to store the device * dependent state in the par field in struct fb_info and to change the - * hardware to that state. This allows a very clean seperation of the fbdev + * hardware to that state. This allows a very clean separation of the fbdev * layer from the console layer. It also allows one to use fbdev on its own * which is a bounus for embedded devices. The reason this approach works is * for each framebuffer device when used as a tty/console device is allocated @@ -93,7 +93,7 @@ * Modern graphical hardware not only supports pipelines but some * also support multiple monitors where each display can have its * its own unique data. In this case each display could be - * represented by a seperate framebuffer device thus a seperate + * represented by a separate framebuffer device thus a separate * struct fb_info. Now the struct xxx_par represents the graphics * hardware state thus only one exist per card. In this case the * struct xxx_par for each graphics card would be shared between @@ -513,7 +513,7 @@ * for a graphics card take a specific amount of time. * Often we have to wait for the accelerator to finish * its operation before we can write to the framebuffer - * so we can have consistant display output. + * so we can have consistent display output. * * @info: frame buffer structure that represents a single frame buffer */ diff -Nru a/drivers/video/vesafb.c b/drivers/video/vesafb.c --- a/drivers/video/vesafb.c Sun Feb 9 21:13:28 2003 +++ b/drivers/video/vesafb.c Sun Feb 9 21:13:29 2003 @@ -62,6 +62,7 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { +#ifdef __i386__ int offset; if (!ypan) @@ -83,11 +84,13 @@ "c" (offset), /* ECX */ "d" (offset >> 16), /* EDX */ "D" (&pmi_start)); /* EDI */ +#endif return 0; } static void vesa_setpalette(int regno, unsigned red, unsigned green, unsigned blue) { +#ifdef __i386__ struct { u_char blue, green, red, pad; } entry; if (pmi_setpal) { @@ -111,6 +114,7 @@ outb_p(green >> 10, dac_val); outb_p(blue >> 10, dac_val); } +#endif } static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, @@ -224,6 +228,10 @@ vesafb_fix.smem_len = screen_info.lfb_size * 65536; vesafb_fix.visual = (vesafb_defined.bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; + +#ifndef __i386__ + screen_info.vesapm_seg = 0; +#endif if (!request_mem_region(vesafb_fix.smem_start, vesafb_fix.smem_len, "vesafb")) { printk(KERN_WARNING diff -Nru a/drivers/zorro/Makefile b/drivers/zorro/Makefile --- a/drivers/zorro/Makefile Sun Feb 9 21:13:30 2003 +++ b/drivers/zorro/Makefile Sun Feb 9 21:13:30 2003 @@ -2,8 +2,6 @@ # Makefile for the Zorro bus specific drivers. # -export-objs := zorro.o - obj-$(CONFIG_ZORRO) += zorro.o names.o obj-$(CONFIG_PROC_FS) += proc.o diff -Nru a/fs/Kconfig b/fs/Kconfig --- a/fs/Kconfig Sun Feb 9 21:13:32 2003 +++ b/fs/Kconfig Sun Feb 9 21:13:32 2003 @@ -56,7 +56,7 @@ 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 autofs.o. + will be called autofs. If you are not a part of a fairly large, distributed network, you probably do not need an automounter, and can say N here. @@ -76,7 +76,7 @@ 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 autofs4.o. You will need to add "alias autofs + will be called autofs4. You will need to add "alias autofs autofs4" to your modules configuration file. If you are not a part of a fairly large, distributed network or @@ -150,7 +150,7 @@ /dev/[hs]d?1) on each of your drives. Please read the file for further details. - This code is also available as a module called adfs.o ( = code which + This code is also available as a module called adfs ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -186,7 +186,7 @@ This file system 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 affs.o. If you want to compile it as a module, + The module is called affs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -201,7 +201,7 @@ This file system support 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 hfs.o. If you want to + whenever you want). The module is called hfs. If you want to compile it as a module, say M here and read . @@ -224,7 +224,7 @@ 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 Documentation/modules.txt. The module will be - called befs.o. + called befs. config BEFS_DEBUG bool "Debug BeFS" @@ -252,7 +252,7 @@ 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 bfs.o. Note that the file system of your root + will be called bfs. Note that the file system of your root partition (the one containing the directory /) cannot be compiled as a module. @@ -285,7 +285,7 @@ If you want to compile this file system 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 ext3.o. Be aware however that the file system + module will be called ext3. Be aware however that the file system of your root partition (the one containing the directory /) cannot be compiled as a module, and so this may be dangerous. @@ -332,7 +332,7 @@ If you want to compile this device 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 jbd.o. If you are compiling ext3 into the kernel, + will be called jbd. If you are compiling ext3 into the kernel, you cannot compile this code as a module. config JBD_DEBUG @@ -388,7 +388,7 @@ If you want to compile this as a module however ( = 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 fat.o. Note that if you compile the FAT + module will be called fat. Note that if you compile the FAT support as a module, you cannot compile any of the FAT-based file systems into the kernel -- they will have to be modules as well. The file system of your root partition (the one containing the @@ -425,7 +425,7 @@ which can be inserted in and removed from the running kernel whenever you want), say M here and read . - The module will be called msdos.o. + The module will be called msdos. #dep_tristate ' UMSDOS: Unix-like file system on top of standard MSDOS fs' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS # UMSDOS is temprory broken @@ -454,7 +454,7 @@ above. 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 umsdos.o. Note that the file system of your + module will be called umsdos. Note that the file system of your root partition (the one containing the directory /) cannot be a module, so saying M could be dangerous. If unsure, say N. @@ -480,7 +480,7 @@ 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 vfat.o. + will be called vfat. config EFS_FS tristate "EFS file system support (read only) (EXPERIMENTAL)" @@ -497,7 +497,7 @@ If you want to compile the EFS file system support 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 efs.o. + . The module will be called efs. config JFFS_FS tristate "Journalling Flash File System (JFFS) support" @@ -583,7 +583,7 @@ 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 cramfs.o. Note that the root file system (the one + will be called cramfs. Note that the root file system (the one containing the directory /) cannot be compiled as a module. If unsure, say N. @@ -614,7 +614,7 @@ 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 ramfs.o. + will be called ramfs. config HUGETLBFS bool "HugeTLB file system support" @@ -636,7 +636,7 @@ 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 isofs.o. + will be called isofs. config JOLIET bool "Microsoft Joliet CDROM extensions" @@ -711,7 +711,7 @@ 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 minix.o. Note that the file system of your root + will be called minix. Note that the file system of your root partition (the one containing the directory /) cannot be compiled as a module. @@ -730,7 +730,7 @@ This file system 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 freevxfs.o. If you want to compile it as a + The module is called freevxfs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -743,7 +743,7 @@ This file system is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called ntfs.o. If you want to compile it as a + The module will be called ntfs. If you want to compile it as a module, say M here and read . If you are not using Windows NT/2000/XP in addition to Linux on your @@ -796,7 +796,7 @@ This file system 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 hpfs.o. If you want to compile it as a module, + The module is called hpfs. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -907,7 +907,7 @@ This file system support 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 qnx4.o. If you want to + whenever you want). The module is called qnx4. If you want to compile it as a module, say M here and read . @@ -933,7 +933,7 @@ This file system support 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 romfs.o. If you want to + whenever you want). The module is called romfs. If you want to compile it as a module, say M here and read . Note that the file system of your root partition (the one containing the directory /) cannot be a @@ -984,7 +984,7 @@ If you want to compile this file system 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 ext2.o. Be aware however that the file system + module will be called ext2. Be aware however that the file system of your root partition (the one containing the directory /) cannot be compiled as a module, and so this could be dangerous. Most everyone wants to say Y here. @@ -1045,7 +1045,7 @@ 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 sysv.o. + will be called sysv. If you haven't heard about all of this before, it's safe to say N. @@ -1059,7 +1059,7 @@ This file system support 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 udf.o. If you want to + whenever you want). The module is called udf. If you want to compile it as a module, say M here and read . @@ -1092,7 +1092,7 @@ If you want to compile the UFS file system support 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 ufs.o. + . The module will be called ufs. If you haven't heard about all of this before, it's safe to say N. @@ -1120,7 +1120,7 @@ If you want to compile this file system 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 xfs.o. Be aware, however, that if the file + module will be called xfs. Be aware, however, that if the file system of your root partition is compiled as a module, you'll need to use an initial ramdisk (initrd) to boot. @@ -1196,7 +1196,7 @@ If you want to compile the coda client support 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 coda.o. + . The module will be called coda. config INTERMEZZO_FS tristate "InterMezzo file system support (replicating fs) (EXPERIMENTAL)" @@ -1235,7 +1235,7 @@ This file system 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 nfs.o. If you want to compile it as a module, + The module is called nfs. If you want to compile it as a module, say M here and read . If you are configuring a diskless machine which will mount its root @@ -1307,7 +1307,7 @@ The NFS server 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 nfsd.o. If you want to compile it as a module, + The module is called nfsd. If you want to compile it as a module, say M here and read . If unsure, say N. @@ -1425,7 +1425,7 @@ If you want to compile the SMB support 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 smbfs.o. Most people say N, however. + module will be called smbfs. Most people say N, however. config SMB_NLS_DEFAULT bool "Use a default NLS" @@ -1477,7 +1477,7 @@ 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 ncpfs.o. Say N unless you are connected to a Novell + will be called ncpfs. Say N unless you are connected to a Novell network. source "fs/ncpfs/Kconfig" diff -Nru a/fs/Makefile b/fs/Makefile --- a/fs/Makefile Sun Feb 9 21:13:32 2003 +++ b/fs/Makefile Sun Feb 9 21:13:32 2003 @@ -5,9 +5,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs := open.o dcache.o buffer.o bio.o inode.o dquot.o mpage.o aio.o \ - fcntl.o read_write.o dcookies.o mbcache.o posix_acl.o xattr_acl.o - obj-y := open.o read_write.o file_table.o buffer.o \ bio.o super.o block_dev.o char_dev.o stat.o exec.o pipe.o \ namei.o fcntl.o ioctl.o readdir.o select.o fifo.o locks.o \ diff -Nru a/fs/afs/cmservice.c b/fs/afs/cmservice.c --- a/fs/afs/cmservice.c Sun Feb 9 21:13:32 2003 +++ b/fs/afs/cmservice.c Sun Feb 9 21:13:32 2003 @@ -127,10 +127,10 @@ complete(&kafscmd_alive); /* only certain signals are of interest */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked,0); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + 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 Sun Feb 9 21:13:31 2003 +++ b/fs/afs/internal.h Sun Feb 9 21:13:31 2003 @@ -46,9 +46,9 @@ while (signal_pending(current)) { siginfo_t sinfo; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); dequeue_signal(¤t->blocked,&sinfo); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c --- a/fs/afs/kafsasyncd.c Sun Feb 9 21:13:36 2003 +++ b/fs/afs/kafsasyncd.c Sun Feb 9 21:13:36 2003 @@ -101,10 +101,10 @@ complete(&kafsasyncd_alive); /* only certain signals are of interest */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked,0); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + 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 Sun Feb 9 21:13:33 2003 +++ b/fs/afs/kafstimod.c Sun Feb 9 21:13:33 2003 @@ -78,10 +78,10 @@ complete(&kafstimod_alive); /* only certain signals are of interest */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked,0); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); /* loop around looking for things to attend to */ loop: diff -Nru a/fs/autofs/waitq.c b/fs/autofs/waitq.c --- a/fs/autofs/waitq.c Sun Feb 9 21:13:29 2003 +++ b/fs/autofs/waitq.c Sun Feb 9 21:13:29 2003 @@ -70,10 +70,10 @@ /* Keep the currently executing process from receiving a SIGPIPE unless it was already supposed to get one */ if (wr == -EPIPE && !sigpipe) { - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); sigdelset(¤t->pending.signal, SIGPIPE); recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); } return (bytes > 0); @@ -158,21 +158,14 @@ if ( wq->name ) { /* Block all but "shutdown" signals while waiting */ - sigset_t oldset; - unsigned long irqflags; + sigset_t sigmask; - spin_lock_irqsave(¤t->sig->siglock, irqflags); - oldset = current->blocked; - siginitsetinv(¤t->blocked, SHUTDOWN_SIGS & ~oldset.sig[0]); - recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, irqflags); + siginitsetinv(&sigmask, SHUTDOWN_SIGS); + sigprocmask(SIG_BLOCK, &sigmask, &sigmask); interruptible_sleep_on(&wq->queue); - spin_lock_irqsave(¤t->sig->siglock, irqflags); - current->blocked = oldset; - recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, irqflags); + sigprocmask(SIG_SETMASK, &sigmask, NULL); } else { DPRINTK(("autofs_wait: skipped sleeping\n")); } diff -Nru a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c --- a/fs/autofs4/waitq.c Sun Feb 9 21:13:36 2003 +++ b/fs/autofs4/waitq.c Sun Feb 9 21:13:36 2003 @@ -74,10 +74,10 @@ /* Keep the currently executing process from receiving a SIGPIPE unless it was already supposed to get one */ if (wr == -EPIPE && !sigpipe) { - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); sigdelset(¤t->pending.signal, SIGPIPE); recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); } return (bytes > 0); @@ -198,18 +198,18 @@ sigset_t oldset; unsigned long irqflags; - spin_lock_irqsave(¤t->sig->siglock, irqflags); + spin_lock_irqsave(¤t->sighand->siglock, irqflags); oldset = current->blocked; siginitsetinv(¤t->blocked, SHUTDOWN_SIGS & ~oldset.sig[0]); recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, irqflags); + spin_unlock_irqrestore(¤t->sighand->siglock, irqflags); interruptible_sleep_on(&wq->queue); - spin_lock_irqsave(¤t->sig->siglock, irqflags); + spin_lock_irqsave(¤t->sighand->siglock, irqflags); current->blocked = oldset; recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, irqflags); + spin_unlock_irqrestore(¤t->sighand->siglock, irqflags); } else { DPRINTK(("autofs_wait: skipped sleeping\n")); } diff -Nru a/fs/befs/ChangeLog b/fs/befs/ChangeLog --- a/fs/befs/ChangeLog Sun Feb 9 21:13:29 2003 +++ b/fs/befs/ChangeLog Sun Feb 9 21:13:29 2003 @@ -60,7 +60,7 @@ * Documentation improvements in source. [WD] -* Makefile fix for independant module when CONFIG_MODVERSION is set in +* Makefile fix for independent module when CONFIG_MODVERSION is set in kernel config [Pavel Roskin ] * Compile warning fix for namei.c. [Sergey S. Kostyliov ] diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c --- a/fs/binfmt_elf.c Sun Feb 9 21:13:31 2003 +++ b/fs/binfmt_elf.c Sun Feb 9 21:13:31 2003 @@ -236,7 +236,7 @@ return; p += len; } - __put_user(NULL, argv); + __put_user(0, argv); current->mm->arg_end = current->mm->env_start = p; while (envc-- > 0) { size_t len; @@ -246,7 +246,7 @@ return; p += len; } - __put_user(NULL, envp); + __put_user(0, envp); current->mm->env_end = p; /* Put the elf_info on the stack in the right place. */ @@ -362,8 +362,6 @@ } } - /* Now use mmap to map the library into memory. */ - /* * Now fill out the bss section. First pad the last page up * to the page boundary, and then perform a mmap to make sure @@ -536,6 +534,25 @@ strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) ibcs2_interpreter = 1; + /* + * The early SET_PERSONALITY here is so that the lookup + * for the interpreter happens in the namespace of the + * to-be-execed image. SET_PERSONALITY can select an + * alternate root. + * + * However, SET_PERSONALITY is NOT allowed to switch + * this task into the new images's memory mapping + * policy - that is, TASK_SIZE must still evaluate to + * that which is appropriate to the execing application. + * This is because exit_mmap() needs to have TASK_SIZE + * evaluate to the size of the old image. + * + * So if (say) a 64-bit application is execing a 32-bit + * application it is the architecture's responsibility + * to defer changing the value of TASK_SIZE until the + * switch really is going to happen - do this in + * flush_thread(). - akpm + */ SET_PERSONALITY(elf_ex, ibcs2_interpreter); interpreter = open_exec(elf_interpreter); @@ -1041,7 +1058,7 @@ /* * fill up all the fields in prstatus from the given task struct, except registers - * which need to be filled up seperately. + * which need to be filled up separately. */ static inline void fill_prstatus(struct elf_prstatus *prstatus, struct task_struct *p, long signr) { diff -Nru a/fs/binfmt_flat.c b/fs/binfmt_flat.c --- a/fs/binfmt_flat.c Sun Feb 9 21:13:28 2003 +++ b/fs/binfmt_flat.c Sun Feb 9 21:13:28 2003 @@ -403,7 +403,7 @@ set_personality(PER_LINUX); /* - * there are a couple of cases here, the seperate code/data + * there are a couple of cases here, the separate code/data * case, and then the fully copied to RAM case which lumps * it all together. */ diff -Nru a/fs/binfmt_som.c b/fs/binfmt_som.c --- a/fs/binfmt_som.c Sun Feb 9 21:13:31 2003 +++ b/fs/binfmt_som.c Sun Feb 9 21:13:31 2003 @@ -56,7 +56,7 @@ static struct linux_binfmt som_format = { .module = THIS_MODULE, .load_binary = load_som_binary, - .load_library = load_som_library, + .load_shlib = load_som_library, .core_dump = som_core_dump, .min_coredump = SOM_PAGESIZE }; diff -Nru a/fs/buffer.c b/fs/buffer.c --- a/fs/buffer.c Sun Feb 9 21:13:32 2003 +++ b/fs/buffer.c Sun Feb 9 21:13:32 2003 @@ -81,21 +81,11 @@ * Return the address of the waitqueue_head to be used for this * buffer_head */ -static wait_queue_head_t *bh_waitq_head(struct buffer_head *bh) +wait_queue_head_t *bh_waitq_head(struct buffer_head *bh) { return &bh_wait_queue_heads[hash_ptr(bh, BH_WAIT_TABLE_ORDER)].wqh; } - -/* - * Wait on a buffer until someone does a wakeup on it. Needs - * lots of external locking. ext3 uses this. Fix it. - */ -void sleep_on_buffer(struct buffer_head *bh) -{ - wait_queue_head_t *wq = bh_waitq_head(bh); - sleep_on(wq); -} -EXPORT_SYMBOL(sleep_on_buffer); +EXPORT_SYMBOL(bh_waitq_head); void wake_up_buffer(struct buffer_head *bh) { @@ -137,9 +127,10 @@ get_bh(bh); do { prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE); - blk_run_queues(); - if (buffer_locked(bh)) - schedule(); + if (buffer_locked(bh)) { + blk_run_queues(); + io_schedule(); + } } while (buffer_locked(bh)); put_bh(bh); finish_wait(wqh, &wait); @@ -969,8 +960,6 @@ * the reserve list is empty, we're sure there are * async buffer heads in use. */ - blk_run_queues(); - free_more_memory(); goto try_again; } diff -Nru a/fs/char_dev.c b/fs/char_dev.c --- a/fs/char_dev.c Sun Feb 9 21:13:30 2003 +++ b/fs/char_dev.c Sun Feb 9 21:13:30 2003 @@ -1,5 +1,5 @@ /* - * linux/fs/block_dev.c + * linux/fs/char_dev.c * * Copyright (C) 1991, 1992 Linus Torvalds */ @@ -38,16 +38,13 @@ ((struct char_device *) kmem_cache_alloc(cdev_cachep, SLAB_KERNEL)) #define destroy_cdev(cdev) kmem_cache_free(cdev_cachep, (cdev)) -static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) +static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { - struct char_device * cdev = (struct char_device *) foo; + struct char_device *cdev = (struct char_device *) foo; if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) - { memset(cdev, 0, sizeof(*cdev)); - sema_init(&cdev->sem, 1); - } } void __init cdev_cache_init(void) diff -Nru a/fs/dcache.c b/fs/dcache.c --- a/fs/dcache.c Sun Feb 9 21:13:29 2003 +++ b/fs/dcache.c Sun Feb 9 21:13:29 2003 @@ -1147,21 +1147,24 @@ namelen = dentry->d_name.len; buflen -= namelen + 1; if (buflen < 0) - break; + return ERR_PTR(-ENAMETOOLONG); end -= namelen; memcpy(end, dentry->d_name.name, namelen); *--end = '/'; retval = end; dentry = parent; } + return retval; + global_root: namelen = dentry->d_name.len; buflen -= namelen; if (buflen >= 0) { retval -= namelen-1; /* hit the slash */ memcpy(retval, dentry->d_name.name, namelen); - } + } else + retval = ERR_PTR(-ENAMETOOLONG); return retval; } @@ -1229,6 +1232,10 @@ cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE); spin_unlock(&dcache_lock); + error = PTR_ERR(cwd); + if (IS_ERR(cwd)) + goto out; + error = -ERANGE; len = PAGE_SIZE + page - cwd; if (len <= size) { @@ -1238,6 +1245,8 @@ } } else spin_unlock(&dcache_lock); + +out: dput(pwd); mntput(pwdmnt); dput(root); diff -Nru a/fs/devfs/Makefile b/fs/devfs/Makefile --- a/fs/devfs/Makefile Sun Feb 9 21:13:28 2003 +++ b/fs/devfs/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for the linux devfs-filesystem routines. # -export-objs := base.o util.o - obj-$(CONFIG_DEVFS_FS) += devfs.o devfs-objs := base.o util.o diff -Nru a/fs/direct-io.c b/fs/direct-io.c --- a/fs/direct-io.c Sun Feb 9 21:13:32 2003 +++ b/fs/direct-io.c Sun Feb 9 21:13:32 2003 @@ -892,15 +892,14 @@ ret = do_direct_IO(dio); - if (ret) { - dio_cleanup(dio); - break; - } - dio->result += iov[seg].iov_len - ((dio->final_block_in_request - dio->block_in_file) << blkbits); + if (ret) { + dio_cleanup(dio); + break; + } } /* end iovec loop */ /* diff -Nru a/fs/dquot.c b/fs/dquot.c --- a/fs/dquot.c Sun Feb 9 21:13:34 2003 +++ b/fs/dquot.c Sun Feb 9 21:13:34 2003 @@ -159,7 +159,7 @@ * Note that any operation which operates on dquot data (ie. dq_dqb) must * hold dq_data_lock. * - * Any operation working with dquots must hold dqoff_sem. If operation is + * Any operation working with dquots must hold dqptr_sem. If operation is * just reading pointers from inodes than read lock is enough. If pointers * are altered function must hold write lock. * @@ -270,7 +270,7 @@ } /* Invalidate all dquots on the list. Note that this function is called after - * quota is disabled so no new quota might be created. Because we hold dqoff_sem + * quota is disabled so no new quota might be created. Because we hold dqptr_sem * for writing and pointers were already removed from inodes we actually know that * no quota for this sb+type should be held. */ static void invalidate_dquots(struct super_block *sb, int type) @@ -287,7 +287,7 @@ if (dquot->dq_type != type) continue; #ifdef __DQUOT_PARANOIA - /* There should be no users of quota - we hold dqoff_sem for writing */ + /* There should be no users of quota - we hold dqptr_sem for writing */ if (atomic_read(&dquot->dq_count)) BUG(); #endif @@ -307,7 +307,7 @@ struct quota_info *dqopt = sb_dqopt(sb); int cnt; - down_read(&dqopt->dqoff_sem); + down_read(&dqopt->dqptr_sem); restart: /* At this point any dirty dquot will definitely be written so we can clear dirty flag from info */ @@ -340,7 +340,7 @@ spin_lock(&dq_list_lock); dqstats.syncs++; spin_unlock(&dq_list_lock); - up_read(&dqopt->dqoff_sem); + up_read(&dqopt->dqptr_sem); return 0; } @@ -427,7 +427,7 @@ /* * Put reference to dquot * NOTE: If you change this function please check whether dqput_blocks() works right... - * MUST be called with dqoff_sem held + * MUST be called with dqptr_sem held */ static void dqput(struct dquot *dquot) { @@ -492,7 +492,7 @@ /* * Get reference to dquot - * MUST be called with dqoff_sem held + * MUST be called with dqptr_sem held */ static struct dquot *dqget(struct super_block *sb, unsigned int id, int type) { @@ -553,7 +553,7 @@ return 0; } -/* This routine is guarded by dqoff_sem semaphore */ +/* This routine is guarded by dqptr_sem semaphore */ static void add_dquot_ref(struct super_block *sb, int type) { struct list_head *p; @@ -586,7 +586,7 @@ } /* Remove references to dquots from inode - add dquot to list for freeing if needed */ -/* We can't race with anybody because we hold dqoff_sem for writing... */ +/* We can't race with anybody because we hold dqptr_sem for writing... */ int remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head) { struct dquot *dquot = inode->i_dquot[type]; @@ -829,10 +829,10 @@ unsigned int id = 0; int cnt; - down_write(&sb_dqopt(inode->i_sb)->dqoff_sem); - /* Having dqoff lock we know NOQUOTA flags can't be altered... */ + down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + /* Having dqptr_sem we know NOQUOTA flags can't be altered... */ if (IS_NOQUOTA(inode)) { - up_write(&sb_dqopt(inode->i_sb)->dqoff_sem); + up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); return; } /* Build list of quotas to initialize... */ @@ -853,7 +853,7 @@ inode->i_flags |= S_QUOTA; } } - up_write(&sb_dqopt(inode->i_sb)->dqoff_sem); + up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); } /* @@ -876,9 +876,9 @@ void dquot_drop(struct inode *inode) { - down_write(&sb_dqopt(inode->i_sb)->dqoff_sem); + down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); dquot_drop_nolock(inode); - up_write(&sb_dqopt(inode->i_sb)->dqoff_sem); + up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); } /* @@ -892,7 +892,7 @@ for (cnt = 0; cnt < MAXQUOTAS; cnt++) warntype[cnt] = NOWARN; - down_read(&sb_dqopt(inode->i_sb)->dqoff_sem); + down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (inode->i_dquot[cnt] == NODQUOT) @@ -910,7 +910,7 @@ warn_put_all: spin_unlock(&dq_data_lock); flush_warnings(inode->i_dquot, warntype); - up_read(&sb_dqopt(inode->i_sb)->dqoff_sem); + up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return ret; } @@ -924,7 +924,7 @@ for (cnt = 0; cnt < MAXQUOTAS; cnt++) warntype[cnt] = NOWARN; - down_read(&sb_dqopt(inode->i_sb)->dqoff_sem); + down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (inode->i_dquot[cnt] == NODQUOT) @@ -942,7 +942,7 @@ warn_put_all: spin_unlock(&dq_data_lock); flush_warnings((struct dquot **)inode->i_dquot, warntype); - up_read(&sb_dqopt(inode->i_sb)->dqoff_sem); + up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return ret; } @@ -953,7 +953,7 @@ { unsigned int cnt; - down_read(&sb_dqopt(inode->i_sb)->dqoff_sem); + down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (inode->i_dquot[cnt] == NODQUOT) @@ -962,7 +962,7 @@ } inode_sub_bytes(inode, number); spin_unlock(&dq_data_lock); - up_read(&sb_dqopt(inode->i_sb)->dqoff_sem); + up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); } /* @@ -972,7 +972,7 @@ { unsigned int cnt; - down_read(&sb_dqopt(inode->i_sb)->dqoff_sem); + down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (inode->i_dquot[cnt] == NODQUOT) @@ -980,7 +980,7 @@ dquot_decr_inodes(inode->i_dquot[cnt], number); } spin_unlock(&dq_data_lock); - up_read(&sb_dqopt(inode->i_sb)->dqoff_sem); + up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); } /* @@ -1002,7 +1002,7 @@ transfer_to[cnt] = transfer_from[cnt] = NODQUOT; warntype[cnt] = NOWARN; } - down_write(&sb_dqopt(inode->i_sb)->dqoff_sem); + down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); if (IS_NOQUOTA(inode)) /* File without quota accounting? */ goto warn_put_all; /* First build the transfer_to list - here we can block on reading of dquots... */ @@ -1058,7 +1058,7 @@ for (cnt = 0; cnt < MAXQUOTAS; cnt++) if (transfer_from[cnt] != NODQUOT) dqput(transfer_from[cnt]); - up_write(&sb_dqopt(inode->i_sb)->dqoff_sem); + up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); return ret; } @@ -1114,7 +1114,8 @@ goto out; /* We need to serialize quota_off() for device */ - down_write(&dqopt->dqoff_sem); + down(&dqopt->dqonoff_sem); + down_write(&dqopt->dqptr_sem); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (type != -1 && cnt != type) continue; @@ -1145,7 +1146,8 @@ dqopt->info[cnt].dqi_bgrace = 0; dqopt->ops[cnt] = NULL; } - up_write(&dqopt->dqoff_sem); + up_write(&dqopt->dqptr_sem); + up(&dqopt->dqonoff_sem); out: return 0; } @@ -1157,6 +1159,7 @@ struct quota_info *dqopt = sb_dqopt(sb); struct quota_format_type *fmt = find_quota_format(format_id); int error; + unsigned int oldflags; if (!fmt) return -ESRCH; @@ -1176,15 +1179,17 @@ if (!S_ISREG(inode->i_mode)) goto out_f; - down_write(&dqopt->dqoff_sem); + down(&dqopt->dqonoff_sem); + down_write(&dqopt->dqptr_sem); if (sb_has_quota_enabled(sb, type)) { error = -EBUSY; goto out_lock; } + oldflags = inode->i_flags; dqopt->files[type] = f; error = -EINVAL; if (!fmt->qf_ops->check_quota_file(sb, type)) - goto out_lock; + goto out_file_init; /* We don't want quota on quota files */ dquot_drop_nolock(inode); inode->i_flags |= S_NOQUOTA; @@ -1194,20 +1199,23 @@ down(&dqopt->dqio_sem); if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) { up(&dqopt->dqio_sem); - goto out_lock; + goto out_file_init; } up(&dqopt->dqio_sem); set_enable_flags(dqopt, type); + up_write(&dqopt->dqptr_sem); add_dquot_ref(sb, type); + up(&dqopt->dqonoff_sem); - up_write(&dqopt->dqoff_sem); return 0; -out_lock: - inode->i_flags &= ~S_NOQUOTA; +out_file_init: + inode->i_flags = oldflags; dqopt->files[type] = NULL; - up_write(&dqopt->dqoff_sem); +out_lock: + up_write(&dqopt->dqptr_sem); + up(&dqopt->dqonoff_sem); out_f: filp_close(f, NULL); out_fmt: @@ -1238,14 +1246,14 @@ { struct dquot *dquot; - down_read(&sb_dqopt(sb)->dqoff_sem); + down_read(&sb_dqopt(sb)->dqptr_sem); if (!(dquot = dqget(sb, id, type))) { - up_read(&sb_dqopt(sb)->dqoff_sem); + up_read(&sb_dqopt(sb)->dqptr_sem); return -ESRCH; } do_get_dqblk(dquot, di); dqput(dquot); - up_read(&sb_dqopt(sb)->dqoff_sem); + up_read(&sb_dqopt(sb)->dqptr_sem); return 0; } @@ -1307,14 +1315,14 @@ { struct dquot *dquot; - down_read(&sb_dqopt(sb)->dqoff_sem); + down_read(&sb_dqopt(sb)->dqptr_sem); if (!(dquot = dqget(sb, id, type))) { - up_read(&sb_dqopt(sb)->dqoff_sem); + up_read(&sb_dqopt(sb)->dqptr_sem); return -ESRCH; } do_set_dqblk(dquot, di); dqput(dquot); - up_read(&sb_dqopt(sb)->dqoff_sem); + up_read(&sb_dqopt(sb)->dqptr_sem); return 0; } @@ -1323,9 +1331,9 @@ { struct mem_dqinfo *mi; - down_read(&sb_dqopt(sb)->dqoff_sem); + down_read(&sb_dqopt(sb)->dqptr_sem); if (!sb_has_quota_enabled(sb, type)) { - up_read(&sb_dqopt(sb)->dqoff_sem); + up_read(&sb_dqopt(sb)->dqptr_sem); return -ESRCH; } mi = sb_dqopt(sb)->info + type; @@ -1335,7 +1343,7 @@ ii->dqi_flags = mi->dqi_flags & DQF_MASK; ii->dqi_valid = IIF_ALL; spin_unlock(&dq_data_lock); - up_read(&sb_dqopt(sb)->dqoff_sem); + up_read(&sb_dqopt(sb)->dqptr_sem); return 0; } @@ -1344,9 +1352,9 @@ { struct mem_dqinfo *mi; - down_read(&sb_dqopt(sb)->dqoff_sem); + down_read(&sb_dqopt(sb)->dqptr_sem); if (!sb_has_quota_enabled(sb, type)) { - up_read(&sb_dqopt(sb)->dqoff_sem); + up_read(&sb_dqopt(sb)->dqptr_sem); return -ESRCH; } mi = sb_dqopt(sb)->info + type; @@ -1359,7 +1367,7 @@ mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK); mark_info_dirty(mi); spin_unlock(&dq_data_lock); - up_read(&sb_dqopt(sb)->dqoff_sem); + up_read(&sb_dqopt(sb)->dqptr_sem); return 0; } diff -Nru a/fs/eventpoll.c b/fs/eventpoll.c --- a/fs/eventpoll.c Sun Feb 9 21:13:31 2003 +++ b/fs/eventpoll.c Sun Feb 9 21:13:31 2003 @@ -1543,7 +1543,7 @@ /* Allocates slab cache used to allocate "struct epitem" items */ error = -ENOMEM; - epi_cache = kmem_cache_create("eventpoll epi", + epi_cache = kmem_cache_create("eventpoll_epi", sizeof(struct epitem), 0, SLAB_HWCACHE_ALIGN | EPI_SLAB_DEBUG, NULL, NULL); @@ -1552,7 +1552,7 @@ /* Allocates slab cache used to allocate "struct eppoll_entry" */ error = -ENOMEM; - pwq_cache = kmem_cache_create("eventpoll pwq", + pwq_cache = kmem_cache_create("eventpoll_pwq", sizeof(struct eppoll_entry), 0, EPI_SLAB_DEBUG, NULL, NULL); diff -Nru a/fs/exec.c b/fs/exec.c --- a/fs/exec.c Sun Feb 9 21:13:31 2003 +++ b/fs/exec.c Sun Feb 9 21:13:31 2003 @@ -300,6 +300,8 @@ pgd = pgd_offset(tsk->mm, address); pte_chain = pte_chain_alloc(GFP_KERNEL); + if (!pte_chain) + goto out_sig; spin_lock(&tsk->mm->page_table_lock); pmd = pmd_alloc(tsk->mm, pgd, address); if (!pmd) @@ -325,6 +327,7 @@ return; out: spin_unlock(&tsk->mm->page_table_lock); +out_sig: __free_page(page); force_sig(SIGKILL, tsk); pte_chain_free(pte_chain); @@ -556,35 +559,70 @@ * disturbing other processes. (Other processes might share the signal * table via the CLONE_SIGHAND option to clone().) */ -static inline int de_thread(struct signal_struct *oldsig) +static inline int de_thread(struct task_struct *tsk) { - struct signal_struct *newsig; + struct signal_struct *newsig, *oldsig = tsk->signal; + struct sighand_struct *newsighand, *oldsighand = tsk->sighand; + spinlock_t *lock = &oldsighand->siglock; int count; - if (atomic_read(¤t->sig->count) <= 1) + /* + * If we don't share sighandlers, then we aren't sharing anything + * and we can just re-use it all. + */ + if (atomic_read(&oldsighand->count) <= 1) return 0; - newsig = kmem_cache_alloc(sigact_cachep, GFP_KERNEL); - if (!newsig) + newsighand = kmem_cache_alloc(sighand_cachep, GFP_KERNEL); + if (!newsighand) return -ENOMEM; + spin_lock_init(&newsighand->siglock); + atomic_set(&newsighand->count, 1); + memcpy(newsighand->action, oldsighand->action, sizeof(newsighand->action)); + + /* + * See if we need to allocate a new signal structure + */ + newsig = NULL; + if (atomic_read(&oldsig->count) > 1) { + newsig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); + if (!newsig) { + kmem_cache_free(sighand_cachep, newsighand); + return -ENOMEM; + } + atomic_set(&newsig->count, 1); + newsig->group_exit = 0; + newsig->group_exit_code = 0; + newsig->group_exit_task = NULL; + newsig->group_stop_count = 0; + init_sigpending(&newsig->shared_pending); + } + if (thread_group_empty(current)) - goto out; + goto no_thread_group; + /* - * Kill all other threads in the thread group: + * Kill all other threads in the thread group. + * We must hold tasklist_lock to call zap_other_threads. */ - spin_lock_irq(&oldsig->siglock); + read_lock(&tasklist_lock); + spin_lock_irq(lock); if (oldsig->group_exit) { /* * Another group action in progress, just * return so that the signal is processed. */ - spin_unlock_irq(&oldsig->siglock); - kmem_cache_free(sigact_cachep, newsig); + spin_unlock_irq(lock); + read_unlock(&tasklist_lock); + kmem_cache_free(sighand_cachep, newsighand); + if (newsig) + kmem_cache_free(signal_cachep, newsig); return -EAGAIN; } oldsig->group_exit = 1; - __broadcast_thread_group(current, SIGKILL); + zap_other_threads(current); + read_unlock(&tasklist_lock); /* * Account for the thread group leader hanging around: @@ -595,13 +633,13 @@ while (atomic_read(&oldsig->count) > count) { oldsig->group_exit_task = current; current->state = TASK_UNINTERRUPTIBLE; - spin_unlock_irq(&oldsig->siglock); + spin_unlock_irq(lock); schedule(); - spin_lock_irq(&oldsig->siglock); + spin_lock_irq(lock); if (oldsig->group_exit_task) BUG(); } - spin_unlock_irq(&oldsig->siglock); + spin_unlock_irq(lock); /* * At this point all other threads have exited, all we have to @@ -656,7 +694,8 @@ current->ptrace = ptrace; __ptrace_link(current, parent); } - + + list_del(¤t->tasks); list_add_tail(¤t->tasks, &init_task.tasks); current->exit_signal = SIGCHLD; state = leader->state; @@ -671,31 +710,29 @@ release_task(leader); } -out: - spin_lock_init(&newsig->siglock); - atomic_set(&newsig->count, 1); - newsig->group_exit = 0; - newsig->group_exit_code = 0; - newsig->group_exit_task = NULL; - memcpy(newsig->action, current->sig->action, sizeof(newsig->action)); - init_sigpending(&newsig->shared_pending); +no_thread_group: write_lock_irq(&tasklist_lock); - spin_lock(&oldsig->siglock); - spin_lock(&newsig->siglock); + spin_lock(&oldsighand->siglock); + spin_lock(&newsighand->siglock); if (current == oldsig->curr_target) oldsig->curr_target = next_thread(current); - current->sig = newsig; + if (newsig) + current->signal = newsig; + current->sighand = newsighand; init_sigpending(¤t->pending); recalc_sigpending(); - spin_unlock(&newsig->siglock); - spin_unlock(&oldsig->siglock); + spin_unlock(&newsighand->siglock); + spin_unlock(&oldsighand->siglock); write_unlock_irq(&tasklist_lock); - if (atomic_dec_and_test(&oldsig->count)) - kmem_cache_free(sigact_cachep, oldsig); + if (newsig && atomic_dec_and_test(&oldsig->count)) + kmem_cache_free(signal_cachep, oldsig); + + if (atomic_dec_and_test(&oldsighand->count)) + kmem_cache_free(sighand_cachep, oldsighand); if (!thread_group_empty(current)) BUG(); @@ -741,21 +778,20 @@ { char * name; int i, ch, retval; - struct signal_struct * oldsig = current->sig; /* * Release all of the old mmap stuff */ retval = exec_mmap(bprm->mm); if (retval) - goto mmap_failed; + goto out; /* * Make sure we have a private signal table and that * we are unassociated from the previous thread group. */ - retval = de_thread(oldsig); + retval = de_thread(current); if (retval) - goto flush_failed; + goto out; /* This is the point of no return */ @@ -789,14 +825,7 @@ return 0; -mmap_failed: -flush_failed: - spin_lock_irq(¤t->sig->siglock); - if (current->sig != oldsig) { - kmem_cache_free(sigact_cachep, current->sig); - current->sig = oldsig; - } - spin_unlock_irq(¤t->sig->siglock); +out: return retval; } @@ -873,29 +902,25 @@ void compute_creds(struct linux_binprm *bprm) { - int do_unlock = 0; - + task_lock(current); if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) { current->mm->dumpable = 0; - lock_kernel(); if (must_not_trace_exec(current) || atomic_read(¤t->fs->count) > 1 || atomic_read(¤t->files->count) > 1 - || atomic_read(¤t->sig->count) > 1) { + || atomic_read(¤t->sighand->count) > 1) { if(!capable(CAP_SETUID)) { bprm->e_uid = current->uid; bprm->e_gid = current->gid; } } - do_unlock = 1; } current->suid = current->euid = current->fsuid = bprm->e_uid; current->sgid = current->egid = current->fsgid = bprm->e_gid; - if(do_unlock) - unlock_kernel(); + task_unlock(current); security_bprm_compute_creds(bprm); } @@ -1166,7 +1191,7 @@ case 'p': pid_in_pattern = 1; rc = snprintf(out_ptr, out_end - out_ptr, - "%d", current->pid); + "%d", current->tgid); if (rc > out_end - out_ptr) goto out; out_ptr += rc; @@ -1238,7 +1263,7 @@ if (!pid_in_pattern && (core_uses_pid || atomic_read(¤t->mm->mm_users) != 1)) { rc = snprintf(out_ptr, out_end - out_ptr, - ".%d", current->pid); + ".%d", current->tgid); if (rc > out_end - out_ptr) goto out; out_ptr += rc; @@ -1301,8 +1326,8 @@ } mm->dumpable = 0; init_completion(&mm->core_done); - current->sig->group_exit = 1; - current->sig->group_exit_code = exit_code; + current->signal->group_exit = 1; + current->signal->group_exit_code = exit_code; coredump_wait(mm); if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump) @@ -1329,7 +1354,7 @@ retval = binfmt->core_dump(signr, regs, file); - current->sig->group_exit_code |= 0x80; + current->signal->group_exit_code |= 0x80; close_fail: filp_close(file, NULL); fail_unlock: diff -Nru a/fs/exportfs/Makefile b/fs/exportfs/Makefile --- a/fs/exportfs/Makefile Sun Feb 9 21:13:30 2003 +++ b/fs/exportfs/Makefile Sun Feb 9 21:13:30 2003 @@ -1,8 +1,6 @@ # # Makefile for the filesystem export support routines. -export-objs := expfs.o - obj-$(CONFIG_EXPORTFS) += exportfs.o exportfs-objs := expfs.o diff -Nru a/fs/ext2/Makefile b/fs/ext2/Makefile --- a/fs/ext2/Makefile Sun Feb 9 21:13:34 2003 +++ b/fs/ext2/Makefile Sun Feb 9 21:13:34 2003 @@ -7,8 +7,6 @@ ext2-objs := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ ioctl.o namei.o super.o symlink.o -export-objs += xattr.o - ifeq ($(CONFIG_EXT2_FS_XATTR),y) ext2-objs += xattr.o xattr_user.o endif diff -Nru a/fs/ext2/balloc.c b/fs/ext2/balloc.c --- a/fs/ext2/balloc.c Sun Feb 9 21:13:31 2003 +++ b/fs/ext2/balloc.c Sun Feb 9 21:13:31 2003 @@ -334,22 +334,23 @@ if (!prealloc_count || *prealloc_count) prealloc_goal = 0; - *err = -EDQUOT; - if (DQUOT_ALLOC_BLOCK(inode, 1)) + if (DQUOT_ALLOC_BLOCK(inode, 1)) { + *err = -EDQUOT; goto out; + } while (prealloc_goal && DQUOT_PREALLOC_BLOCK(inode, prealloc_goal)) prealloc_goal--; dq_alloc = prealloc_goal + 1; - *err = -ENOSPC; - lock_super (sb); es_alloc = reserve_blocks(sb, dq_alloc); - if (!es_alloc) + if (!es_alloc) { + *err = -ENOSPC; goto out_unlock; + } ext2_debug ("goal=%lu.\n", goal); @@ -396,8 +397,10 @@ goto io_error; group_alloc = group_reserve_blocks(desc, gdp_bh, es_alloc); } - if (bit >= sbi->s_groups_count) + if (bit >= sbi->s_groups_count) { + *err = -ENOSPC; goto out_release; + } brelse(bitmap_bh); bitmap_bh = read_block_bitmap(sb, group_no); if (!bitmap_bh) @@ -409,7 +412,7 @@ "Free blocks count corrupted for block group %d", group_no); group_alloc = 0; - goto out_release; + goto io_error; } got_block: @@ -432,7 +435,7 @@ "block(%d) >= blocks count(%d) - " "block_group = %d, es == %p ", ret_block, le32_to_cpu(es->s_blocks_count), group_no, es); - goto out_release; + goto io_error; } block = target_block; @@ -470,10 +473,10 @@ ext2_debug ("allocating block %d. ", block); + *err = 0; out_release: group_release_blocks(desc, gdp_bh, group_alloc); release_blocks(sb, es_alloc); - *err = 0; out_unlock: unlock_super (sb); DQUOT_FREE_BLOCK(inode, dq_alloc); diff -Nru a/fs/ext2/inode.c b/fs/ext2/inode.c --- a/fs/ext2/inode.c Sun Feb 9 21:13:28 2003 +++ b/fs/ext2/inode.c Sun Feb 9 21:13:28 2003 @@ -1239,6 +1239,12 @@ error = inode_change_ok(inode, iattr); if (error) return error; + if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || + (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { + error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0; + if (error) + return error; + } inode_setattr(inode, iattr); if (iattr->ia_valid & ATTR_MODE) error = ext2_acl_chmod(inode); diff -Nru a/fs/ext2/super.c b/fs/ext2/super.c --- a/fs/ext2/super.c Sun Feb 9 21:13:33 2003 +++ b/fs/ext2/super.c Sun Feb 9 21:13:33 2003 @@ -673,7 +673,7 @@ if(!bh) { printk("EXT2-fs: Couldn't read superblock on " "2nd try.\n"); - goto failed_mount; + goto failed_sbi; } es = (struct ext2_super_block *) (((char *)bh->b_data) + offset); sbi->s_es = es; diff -Nru a/fs/ext3/Makefile b/fs/ext3/Makefile --- a/fs/ext3/Makefile Sun Feb 9 21:13:29 2003 +++ b/fs/ext3/Makefile Sun Feb 9 21:13:29 2003 @@ -7,8 +7,6 @@ ext3-objs := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ ioctl.o namei.o super.o symlink.o hash.o -export-objs += xattr.o - ifeq ($(CONFIG_EXT3_FS_XATTR),y) ext3-objs += xattr.o xattr_user.o endif diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c --- a/fs/ext3/inode.c Sun Feb 9 21:13:33 2003 +++ b/fs/ext3/inode.c Sun Feb 9 21:13:34 2003 @@ -99,6 +99,34 @@ return err; } +/* + * Work out how many blocks we need to progress with the next chunk of a + * truncate transaction. + */ + +static unsigned long blocks_for_truncate(struct inode *inode) +{ + unsigned long needed; + + needed = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9); + + /* Give ourselves just enough room to cope with inodes in which + * i_blocks is corrupt: we've seen disk corruptions in the past + * which resulted in random data in an inode which looked enough + * like a regular file for ext3 to try to delete it. Things + * will go a bit crazy if that happens, but at least we should + * try not to panic the whole kernel. */ + if (needed < 2) + needed = 2; + + /* But we need to bound the transaction so we don't overflow the + * journal. */ + if (needed > EXT3_MAX_TRANS_DATA) + needed = EXT3_MAX_TRANS_DATA; + + return EXT3_DATA_TRANS_BLOCKS + needed; +} + /* * Truncate transactions can be complex and absolutely huge. So we need to * be able to restart the transaction at a conventient checkpoint to make @@ -112,14 +140,9 @@ static handle_t *start_transaction(struct inode *inode) { - long needed; handle_t *result; - needed = inode->i_blocks; - if (needed > EXT3_MAX_TRANS_DATA) - needed = EXT3_MAX_TRANS_DATA; - - result = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS + needed); + result = ext3_journal_start(inode, blocks_for_truncate(inode)); if (!IS_ERR(result)) return result; @@ -135,14 +158,9 @@ */ static int try_to_extend_transaction(handle_t *handle, struct inode *inode) { - long needed; - if (handle->h_buffer_credits > EXT3_RESERVE_TRANS_BLOCKS) return 0; - needed = inode->i_blocks; - if (needed > EXT3_MAX_TRANS_DATA) - needed = EXT3_MAX_TRANS_DATA; - if (!ext3_journal_extend(handle, EXT3_RESERVE_TRANS_BLOCKS + needed)) + if (!ext3_journal_extend(handle, blocks_for_truncate(inode))) return 0; return 1; } @@ -154,11 +172,8 @@ */ static int ext3_journal_test_restart(handle_t *handle, struct inode *inode) { - long needed = inode->i_blocks; - if (needed > EXT3_MAX_TRANS_DATA) - needed = EXT3_MAX_TRANS_DATA; jbd_debug(2, "restarting handle %p\n", handle); - return ext3_journal_restart(handle, EXT3_DATA_TRANS_BLOCKS + needed); + return ext3_journal_restart(handle, blocks_for_truncate(inode)); } /* diff -Nru a/fs/fat/Makefile b/fs/fat/Makefile --- a/fs/fat/Makefile Sun Feb 9 21:13:28 2003 +++ b/fs/fat/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux fat filesystem support. # -export-objs := fatfs_syms.o - obj-$(CONFIG_FAT_FS) += fat.o fat-objs := cache.o dir.o file.o inode.o misc.o fatfs_syms.o diff -Nru a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c --- a/fs/freevxfs/vxfs_fshead.c Sun Feb 9 21:13:28 2003 +++ b/fs/freevxfs/vxfs_fshead.c Sun Feb 9 21:13:28 2003 @@ -111,13 +111,15 @@ struct vxfs_fsh *pfp, *sfp; struct vxfs_inode_info *vip, *tip; - if (!(vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino))) { + vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino); + if (!vip) { printk(KERN_ERR "vxfs: unabled to read fsh inode\n"); return -EINVAL; - } else if (!VXFS_ISFSH(vip)) { + } + if (!VXFS_ISFSH(vip)) { printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n", vip->vii_mode & VXFS_TYPE_MASK); - return -EINVAL; + goto out_free_fship; } @@ -126,23 +128,26 @@ vxfs_dumpi(vip, infp->vsi_fshino); #endif - if (!(infp->vsi_fship = vxfs_get_fake_inode(sbp, vip))) { + infp->vsi_fship = vxfs_get_fake_inode(sbp, vip); + if (!infp->vsi_fship) { printk(KERN_ERR "vxfs: unabled to get fsh inode\n"); - return -EINVAL; + goto out_free_fship; } - if (!(sfp = vxfs_getfsh(infp->vsi_fship, 0))) { + sfp = vxfs_getfsh(infp->vsi_fship, 0); + if (!sfp) { printk(KERN_ERR "vxfs: unabled to get structural fsh\n"); - return -EINVAL; + goto out_iput_fship; } #ifdef DIAGNOSTIC vxfs_dumpfsh(sfp); #endif - if (!(pfp = vxfs_getfsh(infp->vsi_fship, 1))) { + pfp = vxfs_getfsh(infp->vsi_fship, 1); + if (!pfp) { printk(KERN_ERR "vxfs: unabled to get primary fsh\n"); - return -EINVAL; + goto out_free_sfp; } #ifdef DIAGNOSTIC @@ -150,24 +155,50 @@ #endif tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]); - if (!tip || ((infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip)) == NULL)) { + if (!tip) + goto out_free_pfp; + + infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip); + if (!infp->vsi_stilist) { printk(KERN_ERR "vxfs: unabled to get structual list inode\n"); - return -EINVAL; - } else if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) { + kfree(tip); + goto out_free_pfp; + } + if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) { printk(KERN_ERR "vxfs: structual list inode is of wrong type (%x)\n", VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); - return -EINVAL; + goto out_iput_stilist; } tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]); - if (!tip || ((infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip)) == NULL)) { + if (!tip) + goto out_iput_stilist; + infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip); + if (!infp->vsi_ilist) { printk(KERN_ERR "vxfs: unabled to get inode list inode\n"); - return -EINVAL; - } else if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) { + kfree(tip); + goto out_iput_stilist; + } + if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) { printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n", VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK); - return -EINVAL; + goto out_iput_ilist; } return 0; + + out_iput_ilist: + iput(infp->vsi_ilist); + out_iput_stilist: + iput(infp->vsi_stilist); + out_free_pfp: + kfree(pfp); + out_free_sfp: + kfree(sfp); + out_iput_fship: + iput(infp->vsi_fship); + return -EINVAL; + out_free_fship: + kfree(vip); + return -EINVAL; } diff -Nru a/fs/fs-writeback.c b/fs/fs-writeback.c --- a/fs/fs-writeback.c Sun Feb 9 21:13:37 2003 +++ b/fs/fs-writeback.c Sun Feb 9 21:13:37 2003 @@ -61,12 +61,19 @@ sb->s_op->dirty_inode(inode); } + /* + * make sure that changes are seen by all cpus before we test i_state + * -- mikulas + */ + smp_mb(); + /* avoid the locking if we can */ if ((inode->i_state & flags) == flags) return; spin_lock(&inode_lock); if ((inode->i_state & flags) != flags) { + const int was_dirty = inode->i_state & I_DIRTY; struct address_space *mapping = inode->i_mapping; inode->i_state |= flags; @@ -90,7 +97,7 @@ * If the inode was already on s_dirty or s_io, don't * reposition it (that would break s_dirty time-ordering). */ - if (!mapping->dirtied_when) { + if (!was_dirty) { mapping->dirtied_when = jiffies|1; /* 0 is special */ list_move(&inode->i_list, &sb->s_dirty); } @@ -122,12 +129,12 @@ * Called under inode_lock. */ static void -__sync_single_inode(struct inode *inode, int wait, - struct writeback_control *wbc) +__sync_single_inode(struct inode *inode, struct writeback_control *wbc) { unsigned dirty; struct address_space *mapping = inode->i_mapping; struct super_block *sb = inode->i_sb; + int wait = wbc->sync_mode == WB_SYNC_ALL; BUG_ON(inode->i_state & I_LOCK); @@ -136,6 +143,12 @@ inode->i_state |= I_LOCK; inode->i_state &= ~I_DIRTY; + /* + * smp_rmb(); note: if you remove write_lock below, you must add this. + * mark_inode_dirty doesn't take spinlock, make sure that inode is not + * read speculatively by this cpu before &= ~I_DIRTY -- mikulas + */ + write_lock(&mapping->page_lock); if (wait || !wbc->for_kupdate || list_empty(&mapping->io_pages)) list_splice_init(&mapping->dirty_pages, &mapping->io_pages); @@ -181,14 +194,17 @@ * Write out an inode's dirty pages. Called under inode_lock. */ static void -__writeback_single_inode(struct inode *inode, int sync, +__writeback_single_inode(struct inode *inode, struct writeback_control *wbc) { - if (current_is_pdflush() && (inode->i_state & I_LOCK)) { + if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) { list_move(&inode->i_list, &inode->i_sb->s_dirty); return; } + /* + * It's a data-integrity sync. We must wait. + */ while (inode->i_state & I_LOCK) { __iget(inode); spin_unlock(&inode_lock); @@ -196,7 +212,7 @@ iput(inode); spin_lock(&inode_lock); } - __sync_single_inode(inode, sync, wbc); + __sync_single_inode(inode, wbc); } /* @@ -242,7 +258,6 @@ struct inode, i_list); struct address_space *mapping = inode->i_mapping; struct backing_dev_info *bdi = mapping->backing_dev_info; - int really_sync; if (bdi->memory_backed) break; @@ -275,12 +290,11 @@ if (current_is_pdflush() && !writeback_acquire(bdi)) break; - really_sync = (wbc->sync_mode == WB_SYNC_ALL); BUG_ON(inode->i_state & I_FREEING); __iget(inode); - __writeback_single_inode(inode, really_sync, wbc); + __writeback_single_inode(inode, wbc); if (wbc->sync_mode == WB_SYNC_HOLD) { - mapping->dirtied_when = jiffies; + mapping->dirtied_when = jiffies|1; list_move(&inode->i_list, &sb->s_dirty); } if (current_is_pdflush()) @@ -332,7 +346,6 @@ } spin_unlock(&sb_lock); spin_unlock(&inode_lock); - blk_run_queues(); } /* @@ -451,10 +464,11 @@ { struct writeback_control wbc = { .nr_to_write = LONG_MAX, + .sync_mode = WB_SYNC_ALL, }; spin_lock(&inode_lock); - __writeback_single_inode(inode, sync, &wbc); + __writeback_single_inode(inode, &wbc); spin_unlock(&inode_lock); if (sync) wait_on_inode(inode); diff -Nru a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c --- a/fs/hugetlbfs/inode.c Sun Feb 9 21:13:35 2003 +++ b/fs/hugetlbfs/inode.c Sun Feb 9 21:13:35 2003 @@ -34,6 +34,7 @@ static struct address_space_operations hugetlbfs_aops; struct file_operations hugetlbfs_file_operations; static struct inode_operations hugetlbfs_dir_inode_operations; +static struct inode_operations hugetlbfs_inode_operations; static struct backing_dev_info hugetlbfs_backing_dev_info = { .ra_pages = 0, /* No readahead */ @@ -44,7 +45,6 @@ { struct inode *inode =file->f_dentry->d_inode; struct address_space *mapping = inode->i_mapping; - size_t len; int ret; if (!capable(CAP_IPC_LOCK)) @@ -65,15 +65,52 @@ vma->vm_flags |= VM_HUGETLB | VM_RESERVED; vma->vm_ops = &hugetlb_vm_ops; ret = hugetlb_prefault(mapping, vma); - len = (vma->vm_end - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); - if (inode->i_size < len) - inode->i_size = len; - up(&inode->i_sem); return ret; } /* + * Called under down_write(mmap_sem), page_table_lock is not held + */ + +#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA +unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags); +#else +static unsigned long +hugetlb_get_unmapped_area(struct file *file, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + + if (len & ~HPAGE_MASK) + return -EINVAL; + if (len > TASK_SIZE) + return -ENOMEM; + + if (addr) { + addr = ALIGN(addr, HPAGE_SIZE); + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && + (!vma || addr + len <= vma->vm_start)) + return addr; + } + + addr = ALIGN(mm->free_area_cache, HPAGE_SIZE); + + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { + /* At this point: (!vma || addr < vma->vm_end). */ + if (TASK_SIZE - len < addr) + return -ENOMEM; + if (!vma || addr + len <= vma->vm_start) + return addr; + addr = ALIGN(vma->vm_end, HPAGE_SIZE); + } +} +#endif + +/* * Read a page. Again trivial. If it didn't already exist * in the page cache, it is zero-filled. */ @@ -83,12 +120,14 @@ return -EINVAL; } -static int hugetlbfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) +static int hugetlbfs_prepare_write(struct file *file, + struct page *page, unsigned offset, unsigned to) { return -EINVAL; } -static int hugetlbfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) +static int hugetlbfs_commit_write(struct file *file, + struct page *page, unsigned offset, unsigned to) { return -EINVAL; } @@ -103,28 +142,8 @@ pagevec_reinit(pvec); } -void truncate_partial_hugepage(struct page *page, unsigned partial) +void truncate_huge_page(struct page *page) { - int i; - const unsigned piece = partial & (PAGE_SIZE - 1); - const unsigned tailstart = PAGE_SIZE - piece; - const unsigned whole_pages = partial / PAGE_SIZE; - const unsigned last_page_offset = HPAGE_SIZE/PAGE_SIZE - whole_pages; - - for (i = HPAGE_SIZE/PAGE_SIZE - 1; i >= last_page_offset; ++i) - memclear_highpage_flush(&page[i], 0, PAGE_SIZE); - - if (!piece) - return; - - memclear_highpage_flush(&page[last_page_offset - 1], tailstart, piece); -} - -void truncate_huge_page(struct address_space *mapping, struct page *page) -{ - if (page->mapping != mapping) - return; - clear_page_dirty(page); ClearPageUptodate(page); remove_from_page_cache(page); @@ -133,52 +152,13 @@ void truncate_hugepages(struct address_space *mapping, loff_t lstart) { - const pgoff_t start = (lstart + HPAGE_SIZE - 1) >> HPAGE_SHIFT; - const unsigned partial = lstart & (HPAGE_SIZE - 1); + const pgoff_t start = lstart >> HPAGE_SHIFT; struct pagevec pvec; pgoff_t next; int i; pagevec_init(&pvec, 0); next = start; - - while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { - for (i = 0; i < pagevec_count(&pvec); ++i) { - struct page *page = pvec.pages[i]; - pgoff_t page_index = page->index; - - if (page_index > next) - next = page_index; - - ++next; - - if (TestSetPageLocked(page)) - continue; - - if (PageWriteback(page)) { - unlock_page(page); - continue; - } - - truncate_huge_page(mapping, page); - unlock_page(page); - } - huge_pagevec_release(&pvec); - cond_resched(); - } - - if (partial) { - struct page *page = find_lock_page(mapping, start - 1); - if (page) { - wait_on_page_writeback(page); - truncate_partial_hugepage(page, partial); - unlock_page(page); - huge_page_release(page); - } - } - - next = start; - while (1) { if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { if (next == start) @@ -191,11 +171,10 @@ struct page *page = pvec.pages[i]; lock_page(page); - wait_on_page_writeback(page); if (page->index > next) next = page->index; ++next; - truncate_huge_page(mapping, page); + truncate_huge_page(page); unlock_page(page); } huge_pagevec_release(&pvec); @@ -259,70 +238,73 @@ hugetlbfs_forget_inode(inode); } -static void hugetlb_vmtruncate_list(struct list_head *list, unsigned long pgoff) +/* + * h_pgoff is in HPAGE_SIZE units. + * vma->vm_pgoff is in PAGE_SIZE units. + */ +static void +hugetlb_vmtruncate_list(struct list_head *list, unsigned long h_pgoff) { - unsigned long start, end, length, delta; struct vm_area_struct *vma; list_for_each_entry(vma, list, shared) { - start = vma->vm_start; - end = vma->vm_end; - length = end - start; - - if (vma->vm_pgoff >= pgoff) { - zap_hugepage_range(vma, start, length); + unsigned long h_vm_pgoff; + unsigned long v_length; + unsigned long h_length; + unsigned long v_offset; + + h_vm_pgoff = vma->vm_pgoff << (HPAGE_SHIFT - PAGE_SHIFT); + v_length = vma->vm_end - vma->vm_start; + h_length = v_length >> HPAGE_SHIFT; + v_offset = (h_pgoff - h_vm_pgoff) << HPAGE_SHIFT; + + /* + * Is this VMA fully outside the truncation point? + */ + if (h_vm_pgoff >= h_pgoff) { + zap_hugepage_range(vma, vma->vm_start, v_length); continue; } - length >>= PAGE_SHIFT; - delta = pgoff = vma->vm_pgoff; - if (delta >= length) + /* + * Is this VMA fully inside the truncaton point? + */ + if (h_vm_pgoff + (v_length >> HPAGE_SHIFT) <= h_pgoff) continue; - start += delta << PAGE_SHIFT; - length = (length - delta) << PAGE_SHIFT; - zap_hugepage_range(vma, start, length); + /* + * The VMA straddles the truncation point. v_offset is the + * offset (in bytes) into the VMA where the point lies. + */ + zap_hugepage_range(vma, + vma->vm_start + v_offset, + v_length - v_offset); } } +/* + * Expanding truncates are not allowed. + */ static int hugetlb_vmtruncate(struct inode *inode, loff_t offset) { unsigned long pgoff; struct address_space *mapping = inode->i_mapping; - unsigned long limit; - pgoff = (offset + HPAGE_SIZE - 1) >> HPAGE_SHIFT; + if (offset > inode->i_size) + return -EINVAL; - if (inode->i_size < offset) - goto do_expand; + BUG_ON(offset & ~HPAGE_MASK); + pgoff = offset >> HPAGE_SHIFT; inode->i_size = offset; down(&mapping->i_shared_sem); - if (list_empty(&mapping->i_mmap) && list_empty(&mapping->i_mmap_shared)) - goto out_unlock; if (!list_empty(&mapping->i_mmap)) hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff); if (!list_empty(&mapping->i_mmap_shared)) hugetlb_vmtruncate_list(&mapping->i_mmap_shared, pgoff); - -out_unlock: up(&mapping->i_shared_sem); truncate_hugepages(mapping, offset); return 0; - -do_expand: - limit = current->rlim[RLIMIT_FSIZE].rlim_cur; - if (limit != RLIM_INFINITY && offset > limit) - goto out_sig; - if (offset > inode->i_sb->s_maxbytes) - goto out; - inode->i_size = offset; - return 0; - -out_sig: - send_sig(SIGXFSZ, current, 0); -out: - return -EFBIG; } static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr) @@ -341,15 +323,10 @@ error = security_inode_setattr(dentry, attr); if (error) goto out; - - if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) - error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; - if (error) - goto out; - if (ia_valid & ATTR_SIZE) { - error = hugetlb_vmtruncate(inode, attr->ia_size); + error = -EINVAL; + if (!(attr->ia_size & ~HPAGE_MASK)) + error = hugetlb_vmtruncate(inode, attr->ia_size); if (error) goto out; attr->ia_valid &= ~ATTR_SIZE; @@ -364,8 +341,8 @@ return error; } -static struct inode * -hugetlbfs_get_inode(struct super_block *sb, int mode, dev_t dev) +static struct inode *hugetlbfs_get_inode(struct super_block *sb, + int mode, dev_t dev) { struct inode * inode = new_inode(sb); @@ -377,13 +354,14 @@ inode->i_blocks = 0; inode->i_rdev = NODEV; inode->i_mapping->a_ops = &hugetlbfs_aops; - inode->i_mapping->backing_dev_info = &hugetlbfs_backing_dev_info; + inode->i_mapping->backing_dev_info =&hugetlbfs_backing_dev_info; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; switch (mode & S_IFMT) { default: init_special_inode(inode, mode, dev); break; case S_IFREG: + inode->i_op = &hugetlbfs_inode_operations; inode->i_fop = &hugetlbfs_file_operations; break; case S_IFDIR: @@ -405,8 +383,8 @@ * File creation. Allocate an inode, and we're done.. */ /* SMP-safe */ -static int -hugetlbfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +static int hugetlbfs_mknod(struct inode *dir, + struct dentry *dentry, int mode, dev_t dev) { struct inode * inode = hugetlbfs_get_inode(dir->i_sb, mode, dev); int error = -ENOSPC; @@ -419,7 +397,7 @@ return error; } -static int hugetlbfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) +static int hugetlbfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { int retval = hugetlbfs_mknod(dir, dentry, mode | S_IFDIR, 0); if (!retval) @@ -432,7 +410,8 @@ return hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0); } -static int hugetlbfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) +static int hugetlbfs_symlink(struct inode *dir, + struct dentry *dentry, const char *symname) { struct inode *inode; int error = -ENOSPC; @@ -450,15 +429,25 @@ return error; } +/* + * For direct-IO reads into hugetlb pages + */ +int hugetlbfs_set_page_dirty(struct page *page) +{ + return 0; +} + static struct address_space_operations hugetlbfs_aops = { .readpage = hugetlbfs_readpage, .prepare_write = hugetlbfs_prepare_write, - .commit_write = hugetlbfs_commit_write + .commit_write = hugetlbfs_commit_write, + .set_page_dirty = hugetlbfs_set_page_dirty, }; struct file_operations hugetlbfs_file_operations = { - .mmap = hugetlbfs_file_mmap, - .fsync = simple_sync_file, + .mmap = hugetlbfs_file_mmap, + .fsync = simple_sync_file, + .get_unmapped_area = hugetlb_get_unmapped_area, }; static struct inode_operations hugetlbfs_dir_inode_operations = { @@ -474,12 +463,17 @@ .setattr = hugetlbfs_setattr, }; +static struct inode_operations hugetlbfs_inode_operations = { + .setattr = hugetlbfs_setattr, +}; + static struct super_operations hugetlbfs_ops = { .statfs = simple_statfs, .drop_inode = hugetlbfs_drop_inode, }; -static int hugetlbfs_fill_super(struct super_block * sb, void * data, int silent) +static int +hugetlbfs_fill_super(struct super_block * sb, void * data, int silent) { struct inode * inode; struct dentry * root; diff -Nru a/fs/inode.c b/fs/inode.c --- a/fs/inode.c Sun Feb 9 21:13:37 2003 +++ b/fs/inode.c Sun Feb 9 21:13:37 2003 @@ -16,6 +16,7 @@ #include #include #include +#include #include /* @@ -176,6 +177,7 @@ spin_lock_init(&inode->i_data.private_lock); INIT_LIST_HEAD(&inode->i_data.i_mmap); INIT_LIST_HEAD(&inode->i_data.i_mmap_shared); + spin_lock_init(&inode->i_lock); } static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) @@ -391,6 +393,7 @@ LIST_HEAD(freeable); int nr_pruned = 0; int nr_scanned; + unsigned long reap = 0; spin_lock(&inode_lock); for (nr_scanned = 0; nr_scanned < nr_to_scan; nr_scanned++) { @@ -409,7 +412,7 @@ __iget(inode); spin_unlock(&inode_lock); if (remove_inode_buffers(inode)) - invalidate_inode_pages(&inode->i_data); + reap += invalidate_inode_pages(&inode->i_data); iput(inode); spin_lock(&inode_lock); @@ -427,6 +430,10 @@ inodes_stat.nr_unused -= nr_pruned; spin_unlock(&inode_lock); dispose_list(&freeable); + if (current_is_kswapd) + mod_page_state(kswapd_inodesteal, reap); + else + mod_page_state(pginodesteal, reap); } /* diff -Nru a/fs/ioctl.c b/fs/ioctl.c --- a/fs/ioctl.c Sun Feb 9 21:13:29 2003 +++ b/fs/ioctl.c Sun Feb 9 21:13:29 2003 @@ -57,7 +57,6 @@ filp = fget(fd); if (!filp) goto out; - error = 0; error = security_file_ioctl(filp, cmd, arg); if (error) { diff -Nru a/fs/jbd/Makefile b/fs/jbd/Makefile --- a/fs/jbd/Makefile Sun Feb 9 21:13:31 2003 +++ b/fs/jbd/Makefile Sun Feb 9 21:13:31 2003 @@ -2,8 +2,6 @@ # Makefile for the linux journaling routines. # -export-objs := journal.o - obj-$(CONFIG_JBD) += jbd.o jbd-objs := transaction.o commit.o recovery.o checkpoint.o revoke.o journal.o diff -Nru a/fs/jbd/journal.c b/fs/jbd/journal.c --- a/fs/jbd/journal.c Sun Feb 9 21:13:29 2003 +++ b/fs/jbd/journal.c Sun Feb 9 21:13:29 2003 @@ -205,10 +205,10 @@ lock_kernel(); daemonize(); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigfillset(¤t->blocked); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); sprintf(current->comm, "kjournald"); @@ -732,14 +732,21 @@ * need to set up all of the mapping information to tell the journaling * system where the journal blocks are. * - * journal_init_dev creates a journal which maps a fixed contiguous - * range of blocks on an arbitrary block device. - * - * journal_init_inode creates a journal which maps an on-disk inode as - * the journal. The inode must exist already, must support bmap() and - * must have all data blocks preallocated. */ +/** + * journal_t * journal_init_dev() - creates an initialises a journal structure + * @bdev: Block device on which to create the journal + * @fs_dev: Device which hold journalled filesystem for this journal. + * @start: Block nr Start of journal. + * @len: Lenght of the journal in blocks. + * @blocksize: blocksize of journalling device + * @returns: a newly created journal_t * + * + * journal_init_dev creates a journal which maps a fixed contiguous + * range of blocks on an arbitrary block device. + * + */ journal_t * journal_init_dev(struct block_device *bdev, struct block_device *fs_dev, int start, int len, int blocksize) @@ -763,7 +770,15 @@ return journal; } - + +/** + * journal_t * journal_init_inode () - creates a journal which maps to a inode. + * @inode: An inode to create the journal in + * + * journal_init_inode creates a journal which maps an on-disk inode as + * the journal. The inode must exist already, must support bmap() and + * must have all data blocks preallocated. + */ journal_t * journal_init_inode (struct inode *inode) { struct buffer_head *bh; @@ -852,12 +867,15 @@ return 0; } -/* +/** + * int journal_create() - Initialise the new journal file + * @journal: Journal to create. This structure must have been initialised + * * Given a journal_t structure which tells us which disk blocks we can * use, create a new journal superblock and initialise all of the - * journal fields from scratch. */ - -int journal_create (journal_t *journal) + * journal fields from scratch. + **/ +int journal_create(journal_t *journal) { unsigned long blocknr; struct buffer_head *bh; @@ -920,11 +938,14 @@ return journal_reset(journal); } -/* +/** + * void journal_update_superblock() - Update journal sb on disk. + * @journal: The journal to update. + * @wait: Set to '0' if you don't want to wait for IO completion. + * * Update a journal's dynamic superblock fields and write it to disk, * optionally waiting for the IO to complete. -*/ - + */ void journal_update_superblock(journal_t *journal, int wait) { journal_superblock_t *sb = journal->j_superblock; @@ -1040,12 +1061,14 @@ } -/* +/** + * int journal_load() - Read journal from disk. + * @journal: Journal to act on. + * * Given a journal_t structure which tells us which disk blocks contain * a journal, read the journal from disk to initialise the in-memory * structures. */ - int journal_load(journal_t *journal) { int err; @@ -1090,11 +1113,13 @@ return -EIO; } -/* +/** + * void journal_destroy() - Release a journal_t structure. + * @journal: Journal to act on. +* * Release a journal_t structure once it is no longer in use by the * journaled object. */ - void journal_destroy (journal_t *journal) { /* Wait for the commit thread to wake up and die. */ @@ -1131,8 +1156,12 @@ } -/* Published API: Check whether the journal uses all of a given set of - * features. Return true (non-zero) if it does. */ +/** + *int journal_check_used_features () - Check if features specified are used. + * + * Check whether the journal uses all of a given set of + * features. Return true (non-zero) if it does. + **/ int journal_check_used_features (journal_t *journal, unsigned long compat, unsigned long ro, unsigned long incompat) @@ -1154,7 +1183,10 @@ return 0; } -/* Published API: Check whether the journaling code supports the use of +/** + * int journal_check_available_features() - Check feature set in journalling layer + * + * Check whether the journaling code supports the use of * all of a given set of features on this journal. Return true * (non-zero) if it can. */ @@ -1183,8 +1215,13 @@ return 0; } -/* Published API: Mark a given journal feature as present on the - * superblock. Returns true if the requested features could be set. */ +/** + * int journal_set_features () - Mark a given journal feature in the superblock + * + * Mark a given journal feature as present on the + * superblock. Returns true if the requested features could be set. + * + */ int journal_set_features (journal_t *journal, unsigned long compat, unsigned long ro, unsigned long incompat) @@ -1210,12 +1247,12 @@ } -/* - * Published API: +/** + * int journal_update_format () - Update on-disk journal structure. + * * Given an initialised but unloaded journal struct, poke about in the * on-disk structure to update it to the most recent supported version. */ - int journal_update_format (journal_t *journal) { journal_superblock_t *sb; @@ -1265,7 +1302,10 @@ } -/* +/** + * int journal_flush () - Flush journal + * @journal: Journal to act on. + * * Flush all data for a given journal to disk and empty the journal. * Filesystems can use this when remounting readonly to ensure that * recovery does not need to happen on remount. @@ -1319,12 +1359,16 @@ return err; } -/* +/** + * int journal_wipe() - Wipe journal contents + * @journal: Journal to act on. + * @write: flag (see below) + * * Wipe out all of the contents of a journal, safely. This will produce * a warning if the journal contains any valid recovery information. * Must be called between journal_init_*() and journal_load(). * - * If (write) is non-zero, then we wipe out the journal on disk; otherwise + * If 'write' is non-zero, then we wipe out the journal on disk; otherwise * we merely suppress recovery. */ @@ -1373,43 +1417,11 @@ } /* - * journal_abort: perform a complete, immediate shutdown of the ENTIRE - * journal (not of a single transaction). This operation cannot be - * undone without closing and reopening the journal. - * - * The journal_abort function is intended to support higher level error - * recovery mechanisms such as the ext2/ext3 remount-readonly error - * mode. - * - * Journal abort has very specific semantics. Any existing dirty, - * unjournaled buffers in the main filesystem will still be written to - * disk by bdflush, but the journaling mechanism will be suspended - * immediately and no further transaction commits will be honoured. - * - * Any dirty, journaled buffers will be written back to disk without - * hitting the journal. Atomicity cannot be guaranteed on an aborted - * filesystem, but we _do_ attempt to leave as much data as possible - * behind for fsck to use for cleanup. - * - * Any attempt to get a new transaction handle on a journal which is in - * ABORT state will just result in an -EROFS error return. A - * journal_stop on an existing handle will return -EIO if we have - * entered abort state during the update. - * - * Recursive transactions are not disturbed by journal abort until the - * final journal_stop, which will receive the -EIO error. - * - * Finally, the journal_abort call allows the caller to supply an errno - * which will be recored (if possible) in the journal superblock. This - * allows a client to record failure conditions in the middle of a - * transaction without having to complete the transaction to record the - * failure to disk. ext3_error, for example, now uses this - * functionality. + * Journal abort has very specific semantics, which we describe + * for journal abort. * - * Errors which originate from within the journaling layer will NOT - * supply an errno; a null errno implies that absolutely no further - * writes are done to the journal (unless there are any already in - * progress). + * Two internal function, which provide abort to te jbd layer + * itself are here. */ /* Quick version for internal journal use (doesn't lock the journal). @@ -1447,7 +1459,52 @@ journal_update_superblock(journal, 1); } -/* Full version for external use */ +/** + * void journal_abort () - Shutdown the journal immediately. + * @journal: the journal to shutdown. + * @errno: an error number to record in the journal indicating + * the reason for the shutdown. + * + * Perform a complete, immediate shutdown of the ENTIRE + * journal (not of a single transaction). This operation cannot be + * undone without closing and reopening the journal. + * + * The journal_abort function is intended to support higher level error + * recovery mechanisms such as the ext2/ext3 remount-readonly error + * mode. + * + * Journal abort has very specific semantics. Any existing dirty, + * unjournaled buffers in the main filesystem will still be written to + * disk by bdflush, but the journaling mechanism will be suspended + * immediately and no further transaction commits will be honoured. + * + * Any dirty, journaled buffers will be written back to disk without + * hitting the journal. Atomicity cannot be guaranteed on an aborted + * filesystem, but we _do_ attempt to leave as much data as possible + * behind for fsck to use for cleanup. + * + * Any attempt to get a new transaction handle on a journal which is in + * ABORT state will just result in an -EROFS error return. A + * journal_stop on an existing handle will return -EIO if we have + * entered abort state during the update. + * + * Recursive transactions are not disturbed by journal abort until the + * final journal_stop, which will receive the -EIO error. + * + * Finally, the journal_abort call allows the caller to supply an errno + * which will be recorded (if possible) in the journal superblock. This + * allows a client to record failure conditions in the middle of a + * transaction without having to complete the transaction to record the + * failure to disk. ext3_error, for example, now uses this + * functionality. + * + * Errors which originate from within the journaling layer will NOT + * supply an errno; a null errno implies that absolutely no further + * writes are done to the journal (unless there are any already in + * progress). + * + */ + void journal_abort (journal_t *journal, int errno) { lock_journal(journal); @@ -1455,6 +1512,17 @@ unlock_journal(journal); } +/** + * int journal_errno () - returns the journal's error state. + * @journal: journal to examine. + * + * This is the errno numbet set with journal_abort(), the last + * time the journal was mounted - if the journal was stopped + * without calling abort this will be 0. + * + * If the journal has been aborted on this mount time -EROFS will + * be returned. + */ int journal_errno (journal_t *journal) { int err; @@ -1468,6 +1536,14 @@ return err; } + + +/** + * int journal_clear_err () - clears the journal's error state + * + * An error must be cleared or Acked to take a FS out of readonly + * mode. + */ int journal_clear_err (journal_t *journal) { int err = 0; @@ -1481,6 +1557,13 @@ return err; } + +/** + * void journal_ack_err() - Ack journal err. + * + * An error must be cleared or Acked to take a FS out of readonly + * mode. + */ void journal_ack_err (journal_t *journal) { lock_journal(journal); diff -Nru a/fs/jbd/recovery.c b/fs/jbd/recovery.c --- a/fs/jbd/recovery.c Sun Feb 9 21:13:35 2003 +++ b/fs/jbd/recovery.c Sun Feb 9 21:13:35 2003 @@ -206,20 +206,22 @@ var -= ((journal)->j_last - (journal)->j_first); \ } while (0) -/* - * journal_recover - * +/** + * int journal_recover(journal_t *journal) - recovers a on-disk journal + * @journal: the journal to recover + * * 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; @@ -263,20 +265,23 @@ return err; } -/* - * journal_skip_recovery - * +/** + * int journal_skip_recovery() - Start journal and wipe exiting records + * @journal: journal to startup + * * Locate any valid recovery information from the journal and set up the * 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 Sun Feb 9 21:13:30 2003 +++ b/fs/jbd/transaction.c Sun Feb 9 21:13:30 2003 @@ -222,19 +222,20 @@ return handle; } -/* - * Obtain a new handle. +/** + * handle_t *journal_start() - Obtain a new handle. + * @journal: Journal to start transaction on. + * @nblocks: number of block buffer we might modify * * We make sure that the transaction can guarantee at least nblocks of * modified buffers in the log. We block until the log can guarantee * that much space. * - * This function is visible to journal users (like ext2fs), so is not + * This function is visible to journal users (like ext3fs), so is not * called with the journal already locked. * * Return a pointer to a newly allocated handle, or NULL on failure */ - handle_t *journal_start(journal_t *journal, int nblocks) { handle_t *handle = journal_current_handle(); @@ -324,7 +325,11 @@ 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. */ @@ -368,16 +373,18 @@ return handle; } -/* - * journal_extend: extend buffer credits. - * +/** + * int journal_extend() - extend buffer credits. + * @handle: handle to 'extend' + * @nblocks: nr blocks to try to extend by. + * * Some transactions, such as large extends and truncates, can be done * atomically all at once or in several stages. The operation requests * a credit for a number of buffer modications in advance, but can * extend its credit if it needs more. * * journal_extend tries to give the running handle more buffer credits. - * It does not guarantee that allocation: this is a best-effort only. + * It does not guarantee that allocation - this is a best-effort only. * The calling process MUST be able to deal cleanly with a failure to * extend here. * @@ -386,7 +393,6 @@ * return code < 0 implies an error * return code > 0 implies normal transaction-full status. */ - int journal_extend (handle_t *handle, int nblocks) { transaction_t *transaction = handle->h_transaction; @@ -435,8 +441,12 @@ } -/* - * journal_restart: restart a handle for a multi-transaction filesystem +/** + * int journal_restart() - restart a handle . + * @handle: handle to restart + * @nblocks: nr credits requested + * + * Restart a handle for a multi-transaction filesystem * operation. * * If the journal_extend() call above fails to grant new buffer credits @@ -478,8 +488,9 @@ } -/* - * Barrier operation: establish a transaction barrier. +/** + * void journal_lock_updates () - establish a transaction barrier. + * @journal: Journal to establish a barrier on. * * This locks out any further updates from being started, and blocks * until all existing updates have completed, returning only once the @@ -487,7 +498,6 @@ * * The journal lock should not be held on entry. */ - void journal_lock_updates (journal_t *journal) { lock_journal(journal); @@ -515,12 +525,14 @@ down(&journal->j_barrier); } -/* +/** + * void journal_unlock_updates (journal_t* journal) - release barrier + * @journal: Journal to release the barrier on. + * * Release a transaction barrier obtained with journal_lock_updates(). * * Should be called without the journal lock held. */ - void journal_unlock_updates (journal_t *journal) { lock_journal(journal); @@ -566,9 +578,6 @@ } /* - * journal_get_write_access: notify intent to modify a buffer for metadata - * (not data) update. - * * If the buffer is already part of the current transaction, then there * is nothing we need to do. If it is already part of a prior * transaction which we are still committing to disk, then we need to @@ -577,7 +586,6 @@ * the handle's metadata buffer credits (unless the buffer is already * part of the transaction, that is). * - * Returns an error code or 0 on success. */ static int @@ -689,11 +697,14 @@ * disk then we cannot do copy-out here. */ if (jh->b_jlist == BJ_Shadow) { + wait_queue_head_t *wqh; + JBUFFER_TRACE(jh, "on shadow: sleep"); spin_unlock(&journal_datalist_lock); unlock_journal(journal); /* commit wakes up all shadow buffers after IO */ - sleep_on_buffer(jh2bh(jh)); + wqh = bh_waitq_head(jh2bh(jh)); + wait_event(*wqh, (jh->b_jlist != BJ_Shadow)); lock_journal(journal); goto repeat; } @@ -783,6 +794,17 @@ return error; } +/** + * int journal_get_write_access() - notify intent to modify a buffer for metadata (not data) update. + * @handle: transaction to add buffer modifications to + * @bh: bh to be used for metadata writes + * + * Returns an error code or 0 on success. + * + * In full data journalling mode the buffer may be of type BJ_AsyncData, + * because we're write()ing a buffer which is also part of a shared mapping. + */ + int journal_get_write_access (handle_t *handle, struct buffer_head *bh) { transaction_t *transaction = handle->h_transaction; @@ -813,6 +835,13 @@ * There is no lock ranking violation: it was a newly created, * unlocked buffer beforehand. */ +/** + * int journal_get_create_access () - notify intent to use newly created bh + * @handle: transaction to new buffer to + * @bh: new buffer. + * + * Call this if you create a new bh. + */ int journal_get_create_access (handle_t *handle, struct buffer_head *bh) { transaction_t *transaction = handle->h_transaction; @@ -872,13 +901,14 @@ -/* - * journal_get_undo_access: Notify intent to modify metadata with non- - * rewindable consequences - * +/** + * int journal_get_undo_access() - Notify intent to modify metadata with non-rewindable consequences + * @handle: transaction + * @bh: buffer to undo + * * Sometimes there is a need to distinguish between metadata which has * been committed to disk and that which has not. The ext3fs code uses - * this for freeing and allocating space: we have to make sure that we + * this for freeing and allocating space, we have to make sure that we * do not reuse freed space until the deallocation has been committed, * since if we overwrote that space we would make the delete * un-rewindable in case of a crash. @@ -890,13 +920,12 @@ * as we know that the buffer has definitely been committed to disk. * * We never need to know which transaction the committed data is part - * of: buffers touched here are guaranteed to be dirtied later and so + * of, buffers touched here are guaranteed to be dirtied later and so * will be committed to a new transaction in due course, at which point * we can discard the old committed data pointer. * * Returns error number or 0 on success. */ - int journal_get_undo_access (handle_t *handle, struct buffer_head *bh) { journal_t *journal = handle->h_transaction->t_journal; @@ -939,21 +968,23 @@ return err; } -/* - * 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) +{ +/* * 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; @@ -1094,24 +1125,28 @@ return 0; } -/* - * journal_dirty_metadata: mark a buffer as containing dirty metadata - * which needs to be journaled as part of the current transaction. +/** + * int journal_dirty_metadata() - mark a buffer as containing dirty metadata + * @handle: transaction to add buffer to. + * @bh: buffer to mark + * + * 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. * - * Returns error number or 0 on success. */ - -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); @@ -1196,9 +1231,12 @@ } #endif -/* - * journal_forget: bforget() for potentially-journaled buffers. We can - * only do the bforget if there are no commits pending against the +/** + * void journal_forget() - bforget() for potentially-journaled buffers. + * @handle: transaction handle + * @bh: bh to 'forget' + * + * We can only do the bforget if there are no commits pending against the * buffer. If the buffer is dirty in the current running transaction we * can safely unlink it. * @@ -1210,7 +1248,6 @@ * Allow this call even if the handle has aborted --- it may be part of * the caller's cleanup after an abort. */ - void journal_forget (handle_t *handle, struct buffer_head *bh) { transaction_t *transaction = handle->h_transaction; @@ -1349,8 +1386,14 @@ } #endif -/* - * Register a callback function for this handle. The function will be +/** + * void journal_callback_set() - Register a callback function for this handle. + * @handle: handle to attach the callback to. + * @func: function to callback. + * @jcb: structure with additional information required by func() , and + * some space for jbd internal information. + * + * The function will be * called when the transaction that this handle is part of has been * committed to disk with the original callback data struct and the * error status of the journal as parameters. There is no guarantee of @@ -1371,7 +1414,11 @@ jcb->jcb_func = func; } -/* + +/** + * int journal_stop() - complete a transaction + * @handle: tranaction to complete. + * * All done for a particular handle. * * There is not much action needed here. We just return any remaining @@ -1384,7 +1431,6 @@ * return -EIO if a journal_abort has been executed since the * transaction began. */ - int journal_stop(handle_t *handle) { transaction_t *transaction = handle->h_transaction; @@ -1470,8 +1516,10 @@ return err; } -/* - * For synchronous operations: force any uncommitted trasnactions +/**int journal_force_commit() - force any uncommitted transactions + * @journal: journal to force + * + * For synchronous operations: force any uncommitted transactions * to disk. May seem kludgy, but it reuses all the handle batching * code in a very simple manner. */ @@ -1664,6 +1712,26 @@ return 0; } + +/** + * int journal_try_to_free_buffers() - try to free page buffers. + * @journal: journal for operation + * @page: to try and free + * @gfp_mask: 'IO' mode for try_to_free_buffers() + * + * + * For all the buffers on this page, + * if they are fully written out ordered data, move them onto BUF_CLEAN + * so try_to_free_buffers() can reap them. + * + * This function returns non-zero if we wish try_to_free_buffers() + * 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. @@ -1686,9 +1754,6 @@ * 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; @@ -1883,8 +1948,15 @@ return may_free; } -/* - * Return non-zero if the page's buffers were successfully reaped +/** + * int journal_invalidatepage() + * @journal: journal to use for flush... + * @page: page to flush + * @offset: length of page to invalidate. + * + * Reap page buffers containing data after offset in page. + * + * Return non-zero if the page's buffers were successfully reaped. */ int journal_invalidatepage(journal_t *journal, struct page *page, diff -Nru a/fs/jffs/intrep.c b/fs/jffs/intrep.c --- a/fs/jffs/intrep.c Sun Feb 9 21:13:33 2003 +++ b/fs/jffs/intrep.c Sun Feb 9 21:13:33 2003 @@ -3344,13 +3344,12 @@ lock_kernel(); exit_mm(c->gc_task); - current->session = 1; - current->pgrp = 1; + set_special_pids(1, 1); init_completion(&c->gc_thread_comp); /* barrier */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv (¤t->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT)); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); strcpy(current->comm, "jffs_gcd"); D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): Starting infinite loop.\n")); @@ -3378,9 +3377,9 @@ siginfo_t info; unsigned long signr = 0; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); signr = dequeue_signal(¤t->blocked, &info); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); switch(signr) { case SIGSTOP: diff -Nru a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h --- a/fs/jffs2/os-linux.h Sun Feb 9 21:13:29 2003 +++ b/fs/jffs2/os-linux.h Sun Feb 9 21:13:29 2003 @@ -54,7 +54,7 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,40) #define current_sig_lock current->sigmask_lock #else -#define current_sig_lock current->sig->siglock +#define current_sig_lock current->sighand->siglock #endif static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) diff -Nru a/fs/jfs/inode.c b/fs/jfs/inode.c --- a/fs/jfs/inode.c Sun Feb 9 21:13:28 2003 +++ b/fs/jfs/inode.c Sun Feb 9 21:13:28 2003 @@ -85,7 +85,7 @@ tid_t tid; static int noisy = 5; - jFYI(1, ("In jfs_commit_inode, inode = 0x%p\n", inode)); + jfs_info("In jfs_commit_inode, inode = 0x%p", inode); /* * Don't commit if inode has been committed since last being @@ -100,9 +100,9 @@ * partitions and may think inode is dirty */ if (!special_file(inode->i_mode) && noisy) { - jERROR(1, ("jfs_commit_inode(0x%p) called on " - "read-only volume\n", inode)); - jERROR(1, ("Is remount racy?\n")); + jfs_err("jfs_commit_inode(0x%p) called on " + "read-only volume", inode); + jfs_err("Is remount racy?"); noisy--; } return 0; @@ -128,13 +128,13 @@ return; if (jfs_commit_inode(inode, wait)) { - jERROR(1, ("jfs_write_inode: jfs_commit_inode failed!\n")); + jfs_err("jfs_write_inode: jfs_commit_inode failed!"); } } void jfs_delete_inode(struct inode *inode) { - jFYI(1, ("In jfs_delete_inode, inode = 0x%p\n", inode)); + jfs_info("In jfs_delete_inode, inode = 0x%p", inode); if (test_cflag(COMMIT_Freewmap, inode)) freeZeroLink(inode); @@ -153,9 +153,8 @@ /* kernel allows writes to devices on read-only * partitions and may try to mark inode dirty */ - jERROR(1, ("jfs_dirty_inode called on " - "read-only volume\n")); - jERROR(1, ("Is remount racy?\n")); + jfs_err("jfs_dirty_inode called on read-only volume"); + jfs_err("Is remount racy?"); noisy--; } return; @@ -302,7 +301,7 @@ static int jfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { - return block_prepare_write(page, from, to, jfs_get_block); + return nobh_prepare_write(page, from, to, jfs_get_block); } static sector_t jfs_bmap(struct address_space *mapping, sector_t block) @@ -327,7 +326,7 @@ .writepages = jfs_writepages, .sync_page = block_sync_page, .prepare_write = jfs_prepare_write, - .commit_write = generic_commit_write, + .commit_write = nobh_commit_write, .bmap = jfs_bmap, .direct_IO = jfs_direct_IO, }; @@ -378,9 +377,9 @@ void jfs_truncate(struct inode *ip) { - jFYI(1, ("jfs_truncate: size = 0x%lx\n", (ulong) ip->i_size)); + jfs_info("jfs_truncate: size = 0x%lx", (ulong) ip->i_size); - block_truncate_page(ip->i_mapping, ip->i_size, jfs_get_block); + nobh_truncate_page(ip->i_mapping, ip->i_size); IWRITE_LOCK(ip); jfs_truncate_nolock(ip, ip->i_size); diff -Nru a/fs/jfs/jfs_btree.h b/fs/jfs/jfs_btree.h --- a/fs/jfs/jfs_btree.h Sun Feb 9 21:13:28 2003 +++ b/fs/jfs/jfs_btree.h Sun Feb 9 21:13:28 2003 @@ -71,19 +71,16 @@ MP = (struct metapage *)&JFS_IP(IP)->bxflag;\ P = (TYPE *)&JFS_IP(IP)->ROOT;\ RC = 0;\ - jEVENT(0,("%d BT_GETPAGE returning root\n", __LINE__));\ }\ else\ {\ - jEVENT(0,("%d BT_GETPAGE reading block %d\n", __LINE__,\ - (int)BN));\ MP = read_metapage((IP), BN, SIZE, 1);\ if (MP) {\ RC = 0;\ P = (MP)->data;\ } else {\ P = NULL;\ - jERROR(1,("bread failed!\n"));\ + jfs_err("bread failed!");\ RC = EIO;\ }\ }\ diff -Nru a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h --- a/fs/jfs/jfs_debug.h Sun Feb 9 21:13:30 2003 +++ b/fs/jfs/jfs_debug.h Sun Feb 9 21:13:30 2003 @@ -41,13 +41,13 @@ /* kgdb stuff */ #define assert(p) KERNEL_ASSERT(#p, p) #else -#define assert(p) {\ -if (!(p))\ - {\ - printk("assert(%s)\n",#p);\ - BUG();\ - }\ -} +#define assert(p) do { \ + if (!(p)) { \ + printk(KERN_CRIT "BUG at %s:%d assert(%s)\n", \ + __FILE__, __LINE__, #p); \ + BUG(); \ + } \ +} while (0) #endif /* @@ -57,33 +57,53 @@ #ifdef CONFIG_JFS_DEBUG #define ASSERT(p) assert(p) +/* printk verbosity */ +#define JFS_LOGLEVEL_ERR 1 +#define JFS_LOGLEVEL_WARN 2 +#define JFS_LOGLEVEL_DEBUG 3 +#define JFS_LOGLEVEL_INFO 4 + +extern int jfsloglevel; + /* dump memory contents */ extern void dump_mem(char *label, void *data, int length); -extern int jfsloglevel; /* information message: e.g., configuration, major event */ -#define jFYI(button, prspec) \ - do { if (button && jfsloglevel > 1) printk prspec; } while (0) +#define jfs_info(fmt, arg...) do { \ + if (jfsloglevel >= JFS_LOGLEVEL_INFO) \ + printk(KERN_INFO fmt "\n", ## arg); \ +} while (0) + +/* debug message: ad hoc */ +#define jfs_debug(fmt, arg...) do { \ + if (jfsloglevel >= JFS_LOGLEVEL_DEBUG) \ + printk(KERN_DEBUG fmt "\n", ## arg); \ +} while (0) + +/* warn message: */ +#define jfs_warn(fmt, arg...) do { \ + if (jfsloglevel >= JFS_LOGLEVEL_WARN) \ + printk(KERN_WARNING fmt "\n", ## arg); \ +} while (0) /* error event message: e.g., i/o error */ -extern int jfsERROR; -#define jERROR(button, prspec) \ - do { if (button && jfsloglevel > 0) { printk prspec; } } while (0) - -/* debug event message: */ -#define jEVENT(button,prspec) \ - do { if (button) printk prspec; } while (0) +#define jfs_err(fmt, arg...) do { \ + if (jfsloglevel >= JFS_LOGLEVEL_ERR) \ + printk(KERN_ERR "%s:%d " fmt "\n", \ + __FILE__, __LINE__, ## arg); \ +} while (0) /* * debug OFF * --------- */ #else /* CONFIG_JFS_DEBUG */ -#define dump_mem(label,data,length) -#define ASSERT(p) -#define jEVENT(button,prspec) -#define jERROR(button,prspec) -#define jFYI(button,prspec) +#define dump_mem(label,data,length) do {} while (0) +#define ASSERT(p) do {} while (0) +#define jfs_info(fmt, arg...) do {} while (0) +#define jfs_debug(fmt, arg...) do {} while (0) +#define jfs_warn(fmt, arg...) do {} while (0) +#define jfs_err(fmt, arg...) do {} while (0) #endif /* CONFIG_JFS_DEBUG */ /* diff -Nru a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c --- a/fs/jfs/jfs_dmap.c Sun Feb 9 21:13:35 2003 +++ b/fs/jfs/jfs_dmap.c Sun Feb 9 21:13:35 2003 @@ -314,7 +314,7 @@ BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage, PSIZE, 0); if (mp == NULL) { - jERROR(1,("dbSync: read_metapage failed!\n")); + jfs_err("dbSync: read_metapage failed!"); return (EIO); } /* copy the in-memory version of the bmap to the on-disk version */ @@ -1444,10 +1444,10 @@ /* assert(!(rc == ENOSPC && bmp->db_agfree[agno] == bmp->db_agsize)); */ if ((rc == ENOSPC) && (bmp->db_agfree[agno] == bmp->db_agsize)) { - jERROR(1, - ("dbAllocAG: removed assert, but still need to debug here\nblkno = 0x%Lx, nblocks = 0x%Lx\n", + jfs_err("dbAllocAG: removed assert, but still need to " + "debug here\nblkno = 0x%Lx, nblocks = 0x%Lx", (unsigned long long) blkno, - (unsigned long long) nblocks)); + (unsigned long long) nblocks); } return (rc); } @@ -1829,8 +1829,7 @@ * to indicate that we have leaked blocks. */ fsDirty(); /* !!! */ - jERROR(1, - ("dbAllocCtl: I/O Error: Block Leakage.\n")); + jfs_err("dbAllocCtl: I/O Error: Block Leakage."); continue; } dp = (struct dmap *) mp->data; @@ -1843,7 +1842,7 @@ */ release_metapage(mp); fsDirty(); /* !!! */ - jERROR(1, ("dbAllocCtl: Block Leakage.\n")); + jfs_err("dbAllocCtl: Block Leakage."); continue; } @@ -3276,9 +3275,8 @@ newsize = blkno + nblocks; - jEVENT(0, ("dbExtendFS: blkno:%Ld nblocks:%Ld newsize:%Ld\n", - (long long) blkno, (long long) nblocks, - (long long) newsize)); + jfs_info("dbExtendFS: blkno:%Ld nblocks:%Ld newsize:%Ld", + (long long) blkno, (long long) nblocks, (long long) newsize); /* * initialize bmap control page. diff -Nru a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c --- a/fs/jfs/jfs_dtree.c Sun Feb 9 21:13:34 2003 +++ b/fs/jfs/jfs_dtree.c Sun Feb 9 21:13:34 2003 @@ -130,7 +130,7 @@ if (((P)->header.nextindex > (((BN)==0)?DTROOTMAXSLOT:(P)->header.maxslot)) ||\ ((BN) && ((P)->header.maxslot > DTPAGEMAXSLOT)))\ {\ - jERROR(1,("DT_GETPAGE: dtree page corrupt\n"));\ + jfs_err("DT_GETPAGE: dtree page corrupt");\ BT_PUTPAGE(MP);\ updateSuper((IP)->i_sb, FM_DIRTY);\ MP = NULL;\ @@ -222,6 +222,25 @@ } /* + * get_index_page() + * + * Same as get_index_page(), but get's a new page without reading + */ +static struct metapage *get_index_page(struct inode *inode, s64 blkno) +{ + int rc; + s64 xaddr; + int xflag; + s32 xlen; + + rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); + if (rc || (xlen == 0)) + return NULL; + + return get_metapage(inode, xaddr, PSIZE, 1); +} + +/* * find_index() * * Returns dtree page containing directory table entry for specified @@ -241,15 +260,14 @@ if (index < 2) { if (maxWarnings) { - jERROR(1, ("find_entry called with index = %d\n", - index)); + jfs_warn("find_entry called with index = %d", index); maxWarnings--; } return 0; } if (index >= jfs_ip->next_index) { - jFYI(1, ("find_entry called with index >= next_index\n")); + jfs_warn("find_entry called with index >= next_index"); return 0; } @@ -274,8 +292,7 @@ *mp = read_index_page(ip, blkno); } if (*mp == 0) { - jERROR(1, - ("free_index: error reading directory table\n")); + jfs_err("free_index: error reading directory table"); return 0; } @@ -336,8 +353,8 @@ ASSERT(DO_INDEX(ip)); if (jfs_ip->next_index < 2) { - jERROR(1, ("next_index = %d. Please fix this!\n", - jfs_ip->next_index)); + jfs_warn("add_index: next_index = %d. Resetting!", + jfs_ip->next_index); jfs_ip->next_index = 2; } @@ -386,14 +403,14 @@ if ((rc = xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0))) { - jFYI(1, ("add_index: xtInsert failed!\n")); + jfs_warn("add_index: xtInsert failed!"); return -1; } ip->i_size = PSIZE; ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage); - if ((mp = read_index_page(ip, 0)) == 0) { - jERROR(1, ("add_index: get_metapage failed!\n")); + if ((mp = get_index_page(ip, 0)) == 0) { + jfs_err("add_index: get_metapage failed!"); xtTruncate(tid, ip, 0, COMMIT_PWMAP); return -1; } @@ -428,14 +445,14 @@ if ((rc = xtInsert(tid, ip, 0, blkno, sbi->nbperpage, &xaddr, 0))) { - jFYI(1, ("add_index: xtInsert failed!\n")); + jfs_warn("add_index: xtInsert failed!"); jfs_ip->next_index--; return -1; } ip->i_size += PSIZE; ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage); - if ((mp = read_index_page(ip, blkno))) + if ((mp = get_index_page(ip, blkno))) memset(mp->data, 0, PSIZE); /* Just looks better */ else xtTruncate(tid, ip, offset, COMMIT_PWMAP); @@ -443,7 +460,7 @@ mp = read_index_page(ip, blkno); if (mp == 0) { - jERROR(1, ("add_index: get/read_metapage failed!\n")); + jfs_err("add_index: get/read_metapage failed!"); return -1; } @@ -751,7 +768,7 @@ /* Something's corrupted, mark filesytem dirty so * chkdsk will fix it. */ - jERROR(1, ("stack overrun in dtSearch!\n")); + jfs_err("stack overrun in dtSearch!"); updateSuper(sb, FM_DIRTY); rc = EIO; goto out; @@ -1162,7 +1179,7 @@ break; default: - jERROR(2, ("dtSplitUp(): UFO!\n")); + jfs_err("dtSplitUp(): UFO!"); break; } @@ -1313,8 +1330,7 @@ if (rmp == NULL) return EIO; - jEVENT(0, - ("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p\n", ip, smp, rmp)); + jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp); BT_MARK_DIRTY(rmp, ip); /* @@ -1420,9 +1436,8 @@ * acquire a transaction lock on the next page */ tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); - jEVENT(0, - ("dtSplitPage: tlck = 0x%p, ip = 0x%p, mp=0x%p\n", - tlck, ip, mp)); + jfs_info("dtSplitPage: tlck = 0x%p, ip = 0x%p, mp=0x%p", + tlck, ip, mp); dtlck = (struct dt_lock *) & tlck->lock; /* linelock header of previous right sibling page */ @@ -1564,7 +1579,6 @@ ip->i_blocks += LBLK2PBLK(sb, lengthPXD(pxd)); - jEVENT(0, ("dtSplitPage: ip:0x%p sp:0x%p rp:0x%p\n", ip, sp, rp)); return 0; } @@ -1665,8 +1679,7 @@ */ sp->header.self = *pxd; - jEVENT(0, - ("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p\n", ip, smp, sp)); + jfs_info("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p", ip, smp, sp); BT_MARK_DIRTY(smp, ip); /* @@ -1804,10 +1817,6 @@ ((JFS_IP(ip)->acl.flag & DXD_EXTENT) ? lengthDXD(&JFS_IP(ip)->acl) : 0)); - jEVENT(0, - ("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p\n", ip, smp, sp)); - - DT_PUTPAGE(pmp); return 0; } @@ -2401,9 +2410,9 @@ oxaddr = addressPXD(opxd); xlen = lengthPXD(opxd); - jEVENT(0, ("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d\n", + jfs_info("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d", (long long)lmxaddr, (long long)oxaddr, (long long)nxaddr, - xlen)); + xlen); /* * 1. get the internal parent dtpage covering @@ -2415,7 +2424,7 @@ /* retrieve search result */ DT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); - jEVENT(0, ("dtRelocate: parent router entry validated.\n")); + jfs_info("dtRelocate: parent router entry validated."); /* * 2. relocate the target dtpage @@ -2521,7 +2530,7 @@ #endif /* _STILL_TO_PORT */ /* unpin the relocated page */ DT_PUTPAGE(mp); - jEVENT(0, ("dtRelocate: target dtpage relocated.\n")); + jfs_info("dtRelocate: target dtpage relocated."); /* the moved extent is dtpage, then a LOG_NOREDOPAGE log rec * needs to be written (in logredo(), the LOG_NOREDOPAGE log rec @@ -2549,7 +2558,7 @@ * acquire tlck for the parent entry covering the target dtpage; * write LOG_REDOPAGE to apply after image only; */ - jEVENT(0, ("dtRelocate: update parent router entry.\n")); + jfs_info("dtRelocate: update parent router entry."); tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY); dtlck = (struct dt_lock *) & tlck->lock; lv = & dtlck->lv[dtlck->index]; @@ -2708,9 +2717,8 @@ * action: update prev pointer; */ tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); - jEVENT(0, - ("dtRelink nextbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n", - tlck, ip, mp)); + jfs_info("dtRelink nextbn: tlck = 0x%p, ip = 0x%p, mp=0x%p", + tlck, ip, mp); dtlck = (struct dt_lock *) & tlck->lock; /* linelock header */ @@ -2738,9 +2746,8 @@ * action: update next pointer; */ tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK); - jEVENT(0, - ("dtRelink prevbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n", - tlck, ip, mp)); + jfs_info("dtRelink prevbn: tlck = 0x%p, ip = 0x%p, mp=0x%p", + tlck, ip, mp); dtlck = (struct dt_lock *) & tlck->lock; /* linelock header */ @@ -3012,8 +3019,8 @@ } if (dirtab_slot.flag == DIR_INDEX_FREE) { if (loop_count++ > JFS_IP(ip)->next_index) { - jERROR(1, ("jfs_readdir detected " - "infinite loop!\n")); + jfs_err("jfs_readdir detected " + "infinite loop!"); filp->f_pos = DIREND; return 0; } @@ -3032,7 +3039,7 @@ return 0; } if (p->header.flag & BT_INTERNAL) { - jERROR(1,("jfs_readdir: bad index table\n")); + jfs_err("jfs_readdir: bad index table"); DT_PUTPAGE(mp); filp->f_pos = -1; return 0; @@ -3097,8 +3104,8 @@ PARENT(ip), DT_DIR)) return 0; } else { - jERROR(1, - ("jfs_readdir called with invalid offset!\n")); + jfs_err("jfs_readdir called with " + "invalid offset!"); } dtoffset->pn = 1; dtoffset->index = 0; @@ -3111,9 +3118,8 @@ } if ((rc = dtReadNext(ip, &filp->f_pos, &btstack))) { - jERROR(1, - ("jfs_readdir: unexpected rc = %d from dtReadNext\n", - rc)); + jfs_err("jfs_readdir: unexpected rc = %d " + "from dtReadNext", rc); filp->f_pos = DIREND; return 0; } @@ -3130,7 +3136,7 @@ dirent_buf = __get_free_page(GFP_KERNEL); if (dirent_buf == 0) { DT_PUTPAGE(mp); - jERROR(1, ("jfs_readdir: __get_free_page failed!\n")); + jfs_warn("jfs_readdir: __get_free_page failed!"); filp->f_pos = DIREND; return -ENOMEM; } @@ -3202,9 +3208,10 @@ d_namleft -= len; /* Sanity Check */ if (d_namleft == 0) { - jERROR(1,("JFS:Dtree error: " - "ino = %ld, bn=%Ld, index = %d\n", - (long)ip->i_ino, (long long)bn, i)); + jfs_err("JFS:Dtree error: ino = " + "%ld, bn=%Ld, index = %d", + (long)ip->i_ino,(long long)bn, + i); updateSuper(ip->i_sb, FM_DIRTY); goto skip_one; } diff -Nru a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c --- a/fs/jfs/jfs_imap.c Sun Feb 9 21:13:29 2003 +++ b/fs/jfs/jfs_imap.c Sun Feb 9 21:13:29 2003 @@ -137,7 +137,7 @@ /* allocate the in-memory inode map control structure. */ imap = (struct inomap *) kmalloc(sizeof(struct inomap), GFP_KERNEL); if (imap == NULL) { - jERROR(1, ("diMount: kmalloc returned NULL!\n")); + jfs_err("diMount: kmalloc returned NULL!"); return (ENOMEM); } @@ -253,7 +253,7 @@ IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage, PSIZE, 0); if (mp == NULL) { - jERROR(1,("diSync: get_metapage failed!\n")); + jfs_err("diSync: get_metapage failed!"); return EIO; } @@ -339,7 +339,7 @@ uint pageno; int rel_inode; - jFYI(1, ("diRead: ino = %ld\n", ip->i_ino)); + jfs_info("diRead: ino = %ld", ip->i_ino); ipimap = sbi->ipimap; JFS_IP(ip)->ipimap = ipimap; @@ -353,7 +353,7 @@ rc = diIAGRead(imap, iagno, &mp); IREAD_UNLOCK(ipimap); if (rc) { - jERROR(1, ("diRead: diIAGRead returned %d\n", rc)); + jfs_err("diRead: diIAGRead returned %d", rc); return (rc); } @@ -400,7 +400,7 @@ /* read the page of disk inode */ mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1); if (mp == 0) { - jERROR(1, ("diRead: read_metapage failed\n")); + jfs_err("diRead: read_metapage failed"); return EIO; } @@ -409,7 +409,7 @@ dp += rel_inode; if (ip->i_ino != le32_to_cpu(dp->di_number)) { - jERROR(1, ("diRead: i_ino != di_number\n")); + jfs_err("diRead: i_ino != di_number"); updateSuper(ip->i_sb, FM_DIRTY); rc = EIO; } else if (le32_to_cpu(dp->di_nlink) == 0) @@ -460,8 +460,7 @@ ip = new_inode(sb); if (ip == NULL) { - jERROR(1, - ("diReadSpecial: new_inode returned NULL!\n")); + jfs_err("diReadSpecial: new_inode returned NULL!"); return ip; } @@ -480,9 +479,6 @@ address += inum >> 3; /* 8 inodes per 4K page */ /* read the page of fixed disk inode (AIT) in raw mode */ - jEVENT(0, - ("Reading aggregate inode %d from block %d\n", (uint) inum, - address)); mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1); if (mp == NULL) { ip->i_sb = NULL; @@ -553,13 +549,10 @@ address += inum >> 3; /* 8 inodes per 4K page */ /* read the page of fixed disk inode (AIT) in raw mode */ - jEVENT(0, - ("Reading aggregate inode %d from block %d\n", (uint) inum, - address)); mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1); if (mp == NULL) { - jERROR(1, - ("diWriteSpecial: failed to read aggregate inode extent!\n")); + jfs_err("diWriteSpecial: failed to read aggregate inode " + "extent!"); return; } @@ -586,7 +579,7 @@ void diFreeSpecial(struct inode *ip) { if (ip == NULL) { - jERROR(1, ("diFreeSpecial called with NULL ip!\n")); + jfs_err("diFreeSpecial called with NULL ip!"); return; } filemap_fdatawrite(ip->i_mapping); @@ -794,7 +787,7 @@ lv->length << L2DTSLOTSIZE); } } else { - jERROR(1, ("diWrite: UFO tlock\n")); + jfs_err("diWrite: UFO tlock"); } inlineData: @@ -926,8 +919,8 @@ */ //assert(iagno < imap->im_nextiag); if (iagno >= imap->im_nextiag) { - jERROR(1, ("diFree: inum = %d, iagno = %d, nextiag = %d\n", - (uint) inum, iagno, imap->im_nextiag)); + jfs_err("diFree: inum = %d, iagno = %d, nextiag = %d", + (uint) inum, iagno, imap->im_nextiag); dump_mem("imap", imap, 32); updateSuper(ip->i_sb, FM_DIRTY); return EIO; @@ -974,7 +967,7 @@ bitmap = le32_to_cpu(iagp->wmap[extno]) & ~mask; if (imap->im_agctl[agno].numfree > imap->im_agctl[agno].numinos) { - jERROR(1,("diFree: numfree > numinos\n")); + jfs_err("diFree: numfree > numinos"); release_metapage(mp); IREAD_UNLOCK(ipimap); AG_UNLOCK(imap, agno); @@ -1684,7 +1677,7 @@ numinos = imap->im_agctl[agno].numinos; if (numfree > numinos) { - jERROR(1,("diAllocAG: numfree > numinos\n")); + jfs_err("diAllocAG: numfree > numinos"); updateSuper(ip->i_sb, FM_DIRTY); return EIO; } @@ -1835,9 +1828,8 @@ */ //assert(iagp->nfreeinos); if (!iagp->nfreeinos) { - jERROR(1, - ("diAllocIno: nfreeinos = 0, but iag on freelist\n")); - jERROR(1, (" agno = %d, iagno = %d\n", agno, iagno)); + jfs_err("diAllocIno: nfreeinos = 0, but iag on freelist"); + jfs_err(" agno = %d, iagno = %d", agno, iagno); dump_mem("iag", iagp, 64); updateSuper(ip->i_sb, FM_DIRTY); return EIO; @@ -2764,18 +2756,14 @@ * the inode will be freed from working map at the release * of last reference release; */ -// assert(le32_to_cpu(iagp->wmap[extno]) & mask); if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) { - jERROR(1, - ("diUpdatePMap: inode %ld not marked as allocated in wmap!\n", - inum)); + jfs_err("diUpdatePMap: inode %ld not marked as " + "allocated in wmap!", inum); updateSuper(ipimap->i_sb, FM_DIRTY); } -// assert(le32_to_cpu(iagp->pmap[extno]) & mask); if (!(le32_to_cpu(iagp->pmap[extno]) & mask)) { - jERROR(1, - ("diUpdatePMap: inode %ld not marked as allocated in pmap!\n", - inum)); + jfs_err("diUpdatePMap: inode %ld not marked as " + "allocated in pmap!", inum); updateSuper(ipimap->i_sb, FM_DIRTY); } /* update the bitmap for the extent of the freed inode */ @@ -2851,9 +2839,9 @@ int numinos, xnuminos = 0, xnumfree = 0; s64 agstart; - jEVENT(0, ("diExtendFS: nextiag:%d numinos:%d numfree:%d\n", + jfs_info("diExtendFS: nextiag:%d numinos:%d numfree:%d", imap->im_nextiag, atomic_read(&imap->im_numinos), - atomic_read(&imap->im_numfree))); + atomic_read(&imap->im_numfree)); /* * reconstruct imap diff -Nru a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c --- a/fs/jfs/jfs_inode.c Sun Feb 9 21:13:28 2003 +++ b/fs/jfs/jfs_inode.c Sun Feb 9 21:13:28 2003 @@ -38,7 +38,7 @@ inode = new_inode(sb); if (!inode) { - jERROR(1, ("ialloc: new_inode returned NULL!\n")); + jfs_warn("ialloc: new_inode returned NULL!"); return inode; } @@ -46,7 +46,7 @@ rc = diAlloc(parent, S_ISDIR(mode), inode); if (rc) { - jERROR(1, ("ialloc: diAlloc returned %d!\n", rc)); + jfs_warn("ialloc: diAlloc returned %d!", rc); make_bad_inode(inode); iput(inode); return NULL; @@ -87,7 +87,7 @@ jfs_inode->atltail = 0; jfs_inode->xtlid = 0; - jFYI(1, ("ialloc returns inode = 0x%p\n", inode)); + jfs_info("ialloc returns inode = 0x%p\n", inode); return inode; } diff -Nru a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c --- a/fs/jfs/jfs_logmgr.c Sun Feb 9 21:13:32 2003 +++ b/fs/jfs/jfs_logmgr.c Sun Feb 9 21:13:32 2003 @@ -222,8 +222,8 @@ int diffp, difft; struct metapage *mp = NULL; - jFYI(1, ("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p\n", - log, tblk, lrd, tlck)); + jfs_info("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p", + log, tblk, lrd, tlck); LOG_LOCK(log); @@ -390,7 +390,7 @@ } #endif /* _JFS_WIP */ else { - jERROR(2, ("lmWriteRecord: UFO tlck:0x%p\n", tlck)); + jfs_err("lmWriteRecord: UFO tlck:0x%p", tlck); return 0; /* Probably should trap */ } l2linesize = linelock->l2linesize; @@ -449,9 +449,8 @@ lvd->offset = cpu_to_le16(lv->offset); lvd->length = cpu_to_le16(lv->length); dstoffset += 4; - jFYI(1, - ("lmWriteRecord: lv offset:%d length:%d\n", - lv->offset, lv->length)); + jfs_info("lmWriteRecord: lv offset:%d length:%d", + lv->offset, lv->length); } if ((i = linelock->next)) { @@ -492,9 +491,8 @@ if (lrd->type & cpu_to_le16(LOG_COMMIT)) { tblk->clsn = lsn; - jFYI(1, - ("wr: tclsn:0x%x, beor:0x%x\n", tblk->clsn, - bp->l_eor)); + jfs_info("wr: tclsn:0x%x, beor:0x%x", tblk->clsn, + bp->l_eor); INCREMENT(lmStat.commit); /* # of commit */ @@ -526,10 +524,8 @@ LOGGC_UNLOCK(log); } - jFYI(1, - ("lmWriteRecord: lrd:0x%04x bp:0x%p pn:%d eor:0x%x\n", - le16_to_cpu(lrd->type), log->bp, log->page, - dstoffset)); + jfs_info("lmWriteRecord: lrd:0x%04x bp:0x%p pn:%d eor:0x%x", + le16_to_cpu(lrd->type), log->bp, log->page, dstoffset); /* page not full ? */ if (dstoffset < LOGPSIZE - LOGPTLRSIZE) @@ -569,8 +565,6 @@ struct lbuf *nextbp; struct tblock *tblk; - jFYI(1, ("lmNextPage\n")); - /* get current log page number and log sequence page number */ pn = log->page; bp = log->bp; @@ -646,7 +640,6 @@ lp->h.page = lp->t.page = cpu_to_le32(lspn + 1); lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE); - jFYI(1, ("lmNextPage done\n")); return 0; } @@ -680,8 +673,7 @@ LOGGC_UNLOCK(log); return rc; } - jFYI(1, ("lmGroup Commit: tblk = 0x%p, gcrtc = %d\n", tblk, - log->gcrtc)); + jfs_info("lmGroup Commit: tblk = 0x%p, gcrtc = %d", tblk, log->gcrtc); if (tblk->xflag & COMMIT_LAZY) { /* @@ -783,9 +775,6 @@ tblk->flag |= tblkGC_FREE; bp->l_ceor = bp->l_eor; lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor); - jEVENT(0, - ("gc: tclsn:0x%x, bceor:0x%x\n", tblk->clsn, - bp->l_ceor)); lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmGC, cant_write); INCREMENT(lmStat.full_page); @@ -794,9 +783,6 @@ else { bp->l_ceor = tblk->eor; /* ? bp->l_ceor = bp->l_eor; */ lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor); - jEVENT(0, - ("gc: tclsn:0x%x, bceor:0x%x\n", tblk->clsn, - bp->l_ceor)); lbmWrite(log, bp, lbmWRITE | lbmGC, cant_write); INCREMENT(lmStat.partial_page); } @@ -845,9 +831,8 @@ tblk->flag &= ~tblkGC_QUEUE; tblk->cqnext = 0; - jEVENT(0, - ("lmPostGC: tblk = 0x%p, flag = 0x%x\n", tblk, - tblk->flag)); + jfs_info("lmPostGC: tblk = 0x%p, flag = 0x%x", tblk, + tblk->flag); if (!(tblk->xflag & COMMIT_FORCE)) /* @@ -877,7 +862,7 @@ lp = (struct logpage *) bp->l_ldata; bp->l_ceor = bp->l_eor; lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor); - jEVENT(0, ("lmPostGC: calling lbmWrite\n")); + jfs_info("lmPostGC: calling lbmWrite"); lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmFREE, 1); } @@ -1008,8 +993,7 @@ delta = LOGSYNC_DELTA(logsize); more = min(free / 2, delta); if (more < 2 * LOGPSIZE) { - jEVENT(1, - ("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n\n")); + jfs_warn("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n"); /* * log wrapping * @@ -1048,8 +1032,8 @@ */ if (written > LOGSYNC_BARRIER(logsize) && logsize > 32 * LOGPSIZE) { set_bit(log_SYNCBARRIER, &log->flag); - jFYI(1, ("log barrier on: lsn=0x%x syncpt=0x%x\n", lsn, - log->syncpt)); + jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn, + log->syncpt); /* * We may have to initiate group commit */ @@ -1148,7 +1132,6 @@ goto shutdown; out: - jFYI(1, ("lmLogOpen: exit(0)\n")); *logptr = log; return 0; @@ -1167,7 +1150,7 @@ free: /* free log descriptor */ kfree(log); - jFYI(1, ("lmLogOpen: exit(%d)\n", rc)); + jfs_warn("lmLogOpen: exit(%d)", rc); return rc; } @@ -1200,7 +1183,7 @@ struct logpage *lp; int lsn; - jFYI(1, ("lmLogInit: log:0x%p\n", log)); + jfs_info("lmLogInit: log:0x%p", log); /* * log inode is overlaid on generic inode where @@ -1224,14 +1207,14 @@ logsuper = (struct logsuper *) bpsuper->l_ldata; if (logsuper->magic != cpu_to_le32(LOGMAGIC)) { - jERROR(1, ("*** Log Format Error ! ***\n")); + jfs_warn("*** Log Format Error ! ***"); rc = EINVAL; goto errout20; } /* logredo() should have been run successfully. */ if (logsuper->state != cpu_to_le32(LOGREDONE)) { - jERROR(1, ("*** Log Is Dirty ! ***\n")); + jfs_warn("*** Log Is Dirty ! ***"); rc = EINVAL; goto errout20; } @@ -1242,19 +1225,17 @@ rc = EINVAL; goto errout20; } - jFYI(0, - ("lmLogInit: inline log:0x%p base:0x%Lx size:0x%x\n", - log, (unsigned long long) log->base, log->size)); + jfs_info("lmLogInit: inline log:0x%p base:0x%Lx size:0x%x", + log, (unsigned long long) log->base, log->size); } else { if (memcmp(logsuper->uuid, log->uuid, 16)) { - jERROR(1,("wrong uuid on JFS log device\n")); + jfs_warn("wrong uuid on JFS log device"); goto errout20; } log->size = le32_to_cpu(logsuper->size); log->l2bsize = le32_to_cpu(logsuper->l2bsize); - jFYI(0, - ("lmLogInit: external log:0x%p base:0x%Lx size:0x%x\n", - log, (unsigned long long) log->base, log->size)); + jfs_info("lmLogInit: external log:0x%p base:0x%Lx size:0x%x", + log, (unsigned long long) log->base, log->size); } log->page = le32_to_cpu(logsuper->end) / LOGPSIZE; @@ -1269,9 +1250,9 @@ lp = (struct logpage *) bp->l_ldata; - jFYI(1, ("lmLogInit: lsn:0x%x page:%d eor:%d:%d\n", + jfs_info("lmLogInit: lsn:0x%x page:%d eor:%d:%d", le32_to_cpu(logsuper->end), log->page, log->eor, - le16_to_cpu(lp->h.eor))); + le16_to_cpu(lp->h.eor)); // ASSERT(log->eor == lp->h.eor); @@ -1319,8 +1300,8 @@ log->sync = log->syncpt; log->nextsync = LOGSYNC_DELTA(log->logsize); - jFYI(1, ("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x\n", - log->lsn, log->syncpt, log->sync)); + jfs_info("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x", + log->lsn, log->syncpt, log->sync); LOGSYNC_LOCK_INIT(log); @@ -1345,7 +1326,6 @@ if ((rc = lbmIOWait(bpsuper, lbmFREE))) goto errout30; - jFYI(1, ("lmLogInit: exit(%d)\n", rc)); return 0; /* @@ -1360,7 +1340,7 @@ errout10: /* unwind lbmLogInit() */ lbmLogShutdown(log); - jFYI(1, ("lmLogInit: exit(%d)\n", rc)); + jfs_warn("lmLogInit: exit(%d)", rc); return rc; } @@ -1383,7 +1363,7 @@ struct block_device *bdev = log->bdev; int rc; - jFYI(1, ("lmLogClose: log:0x%p\n", log)); + jfs_info("lmLogClose: log:0x%p", log); if (!test_bit(log_INLINELOG, &log->flag)) goto externalLog; @@ -1405,7 +1385,7 @@ blkdev_put(bdev, BDEV_FS); out: - jFYI(0, ("lmLogClose: exit(%d)\n", rc)); + jfs_info("lmLogClose: exit(%d)", rc); return rc; } @@ -1420,7 +1400,7 @@ { int i; - jFYI(1, ("jfs_flush_journal: log:0x%p wait=%d\n", log, wait)); + jfs_info("jfs_flush_journal: log:0x%p wait=%d", log, wait); /* * This ensures that we will keep writing to the journal as long @@ -1485,7 +1465,7 @@ struct lbuf *bp; struct logpage *lp; - jFYI(1, ("lmLogShutdown: log:0x%p\n", log)); + jfs_info("lmLogShutdown: log:0x%p", log); jfs_flush_journal(log, 1); @@ -1525,8 +1505,8 @@ lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC); rc = lbmIOWait(bpsuper, lbmFREE); - jFYI(1, ("lmLogShutdown: lsn:0x%x page:%d eor:%d\n", - lsn, log->page, log->eor)); + jfs_info("lmLogShutdown: lsn:0x%x page:%d eor:%d", + lsn, log->page, log->eor); out: /* @@ -1535,7 +1515,7 @@ lbmLogShutdown(log); if (rc) { - jFYI(1, ("lmLogShutdown: exit(%d)\n", rc)); + jfs_warn("lmLogShutdown: exit(%d)", rc); } return rc; } @@ -1576,7 +1556,7 @@ break; } if (i == MAX_ACTIVE) { - jERROR(1,("Too many file systems sharing journal!\n")); + jfs_warn("Too many file systems sharing journal!"); lbmFree(bpsuper); return EMFILE; /* Is there a better rc? */ } @@ -1587,7 +1567,7 @@ break; } if (i == MAX_ACTIVE) { - jERROR(1,("Somebody stomped on the journal!\n")); + jfs_warn("Somebody stomped on the journal!"); lbmFree(bpsuper); return EIO; } @@ -1636,7 +1616,7 @@ int i; struct lbuf *lbuf; - jFYI(1, ("lbmLogInit: log:0x%p\n", log)); + jfs_info("lbmLogInit: log:0x%p", log); /* initialize current buffer cursor */ log->bp = NULL; @@ -1690,7 +1670,7 @@ { struct lbuf *lbuf; - jFYI(1, ("lbmLogShutdown: log:0x%p\n", log)); + jfs_info("lbmLogShutdown: log:0x%p", log); lbuf = log->lbuf_free; while (lbuf) { @@ -1804,7 +1784,7 @@ * allocate a log buffer */ *bpp = bp = lbmAllocate(log, pn); - jFYI(1, ("lbmRead: bp:0x%p pn:0x%x\n", bp, pn)); + jfs_info("lbmRead: bp:0x%p pn:0x%x", bp, pn); bp->l_flag |= lbmREAD; @@ -1852,8 +1832,7 @@ struct lbuf *tail; unsigned long flags; - jFYI(1, ("lbmWrite: bp:0x%p flag:0x%x pn:0x%x\n", - bp, flag, bp->l_pn)); + jfs_info("lbmWrite: bp:0x%p flag:0x%x pn:0x%x", bp, flag, bp->l_pn); /* map the logical block address to physical block address */ bp->l_blkno = @@ -1917,8 +1896,8 @@ */ static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag) { - jEVENT(0, ("lbmDirectWrite: bp:0x%p flag:0x%x pn:0x%x\n", - bp, flag, bp->l_pn)); + jfs_info("lbmDirectWrite: bp:0x%p flag:0x%x pn:0x%x", + bp, flag, bp->l_pn); /* * initialize buffer for device driver @@ -1950,7 +1929,7 @@ struct bio *bio; struct jfs_log *log = bp->l_log; - jFYI(1, ("lbmStartIO\n")); + jfs_info("lbmStartIO\n"); bio = bio_alloc(GFP_NOFS, 1); bio->bi_sector = bp->l_blkno << (log->l2bsize - 9); @@ -1970,8 +1949,6 @@ INCREMENT(lmStat.submitted); blk_run_queues(); - - jFYI(1, ("lbmStartIO done\n")); } @@ -1983,9 +1960,7 @@ unsigned long flags; int rc = 0; - jFYI(1, - ("lbmIOWait1: bp:0x%p flag:0x%x:0x%x\n", bp, bp->l_flag, - flag)); + jfs_info("lbmIOWait1: bp:0x%p flag:0x%x:0x%x", bp, bp->l_flag, flag); LCACHE_LOCK(flags); /* disable+lock */ @@ -1998,9 +1973,7 @@ LCACHE_UNLOCK(flags); /* unlock+enable */ - jFYI(1, - ("lbmIOWait2: bp:0x%p flag:0x%x:0x%x\n", bp, bp->l_flag, - flag)); + jfs_info("lbmIOWait2: bp:0x%p flag:0x%x:0x%x", bp, bp->l_flag, flag); return rc; } @@ -2022,7 +1995,7 @@ /* * get back jfs buffer bound to the i/o buffer */ - jEVENT(0, ("lbmIODone: bp:0x%p flag:0x%x\n", bp, bp->l_flag)); + jfs_info("lbmIODone: bp:0x%p flag:0x%x", bp, bp->l_flag); LCACHE_LOCK(flags); /* disable+lock */ @@ -2031,7 +2004,7 @@ if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { bp->l_flag |= lbmERROR; - jERROR(1, ("lbmIODone: I/O error in JFS log\n")); + jfs_err("lbmIODone: I/O error in JFS log"); } bio_put(bio); @@ -2159,8 +2132,6 @@ { struct lbuf *bp; - jFYI(1, ("jfsIOWait is here!\n")); - lock_kernel(); daemonize(); @@ -2168,10 +2139,10 @@ unlock_kernel(); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigfillset(¤t->blocked); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); complete(&jfsIOwait); @@ -2199,7 +2170,7 @@ } } while (!jfs_stop_threads); - jFYI(1,("jfsIOWait being killed!\n")); + jfs_info("jfsIOWait being killed!"); complete(&jfsIOwait); return 0; } @@ -2231,8 +2202,8 @@ int npages = 0; struct lbuf *bp; - jFYI(0, ("lmLogFormat: logAddress:%Ld logSize:%d\n", - (long long)logAddress, logSize)); + jfs_info("lmLogFormat: logAddress:%Ld logSize:%d", + (long long)logAddress, logSize); /* allocate a log buffer */ bp = lbmAllocate(log, 1); diff -Nru a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c --- a/fs/jfs/jfs_metapage.c Sun Feb 9 21:13:30 2003 +++ b/fs/jfs/jfs_metapage.c Sun Feb 9 21:13:30 2003 @@ -229,8 +229,7 @@ unsigned long page_index; unsigned long page_offset; - jFYI(1, ("__get_metapage: inode = 0x%p, lblock = 0x%lx\n", - inode, lblock)); + jfs_info("__get_metapage: inode = 0x%p, lblock = 0x%lx", inode, lblock); if (absolute) mapping = inode->i_sb->s_bdev->bd_inode->i_mapping; @@ -249,7 +248,7 @@ clear_bit(META_discard, &mp->flag); } mp->count++; - jFYI(1, ("__get_metapage: found 0x%p, in hash\n", mp)); + jfs_info("__get_metapage: found 0x%p, in hash", mp); assert(mp->logical_size == size); lock_metapage(mp); spin_unlock(&meta_lock); @@ -261,7 +260,7 @@ l2bsize; if ((page_offset + size) > PAGE_CACHE_SIZE) { spin_unlock(&meta_lock); - jERROR(1, ("MetaData crosses page boundary!!\n")); + jfs_err("MetaData crosses page boundary!!"); return NULL; } @@ -320,30 +319,28 @@ spin_unlock(&meta_lock); if (new) { - jFYI(1, - ("__get_metapage: Calling grab_cache_page\n")); + jfs_info("__get_metapage: Calling grab_cache_page"); mp->page = grab_cache_page(mapping, page_index); if (!mp->page) { - jERROR(1, ("grab_cache_page failed!\n")); + jfs_err("grab_cache_page failed!"); goto freeit; } else { INCREMENT(mpStat.pagealloc); unlock_page(mp->page); } } else { - jFYI(1, - ("__get_metapage: Calling read_cache_page\n")); + jfs_info("__get_metapage: Calling read_cache_page"); mp->page = read_cache_page(mapping, lblock, (filler_t *)mapping->a_ops->readpage, NULL); if (IS_ERR(mp->page)) { - jERROR(1, ("read_cache_page failed!\n")); + jfs_err("read_cache_page failed!"); goto freeit; } else INCREMENT(mpStat.pagealloc); } mp->data = kmap(mp->page) + page_offset; } - jFYI(1, ("__get_metapage: returning = 0x%p\n", mp)); + jfs_info("__get_metapage: returning = 0x%p", mp); return mp; freeit: @@ -378,7 +375,7 @@ unsigned long page_offset; int rc; - jFYI(1, ("__write_metapage: mp = 0x%p\n", mp)); + jfs_info("__write_metapage: mp = 0x%p", mp); if (test_bit(META_discard, &mp->flag)) { /* @@ -397,7 +394,7 @@ page_offset + mp->logical_size); if (rc) { - jERROR(1, ("prepare_write return %d!\n", rc)); + jfs_err("prepare_write return %d!", rc); ClearPageUptodate(mp->page); unlock_page(mp->page); clear_bit(META_dirty, &mp->flag); @@ -407,13 +404,13 @@ page_offset + mp->logical_size); if (rc) { - jERROR(1, ("commit_write returned %d\n", rc)); + jfs_err("commit_write returned %d", rc); } unlock_page(mp->page); clear_bit(META_dirty, &mp->flag); - jFYI(1, ("__write_metapage done\n")); + jfs_info("__write_metapage done"); } static inline void sync_metapage(struct metapage *mp) @@ -435,9 +432,7 @@ { struct jfs_log *log; - jFYI(1, - ("release_metapage: mp = 0x%p, flag = 0x%lx\n", mp, - mp->flag)); + jfs_info("release_metapage: mp = 0x%p, flag = 0x%lx", mp, mp->flag); spin_lock(&meta_lock); if (test_bit(META_forced, &mp->flag)) { @@ -491,7 +486,6 @@ free_metapage(mp); } - jFYI(1, ("release_metapage: done\n")); } void __invalidate_metapages(struct inode *ip, s64 addr, int len) diff -Nru a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c --- a/fs/jfs/jfs_mount.c Sun Feb 9 21:13:30 2003 +++ b/fs/jfs/jfs_mount.c Sun Feb 9 21:13:30 2003 @@ -87,8 +87,6 @@ struct inode *ipimap = NULL; struct inode *ipbmap = NULL; - jFYI(1, ("\nMount JFS\n")); - /* * read/validate superblock * (initialize mount inode from the superblock) @@ -99,21 +97,19 @@ ipaimap = diReadSpecial(sb, AGGREGATE_I, 0); if (ipaimap == NULL) { - jERROR(1, ("jfs_mount: Faild to read AGGREGATE_I\n")); + jfs_err("jfs_mount: Faild to read AGGREGATE_I"); rc = EIO; goto errout20; } sbi->ipaimap = ipaimap; - jFYI(1, ("jfs_mount: ipaimap:0x%p\n", ipaimap)); + jfs_info("jfs_mount: ipaimap:0x%p", ipaimap); /* * initialize aggregate inode allocation map */ if ((rc = diMount(ipaimap))) { - jERROR(1, - ("jfs_mount: diMount(ipaimap) failed w/rc = %d\n", - rc)); + jfs_err("jfs_mount: diMount(ipaimap) failed w/rc = %d", rc); goto errout21; } @@ -126,7 +122,7 @@ goto errout22; } - jFYI(1, ("jfs_mount: ipbmap:0x%p\n", ipbmap)); + jfs_info("jfs_mount: ipbmap:0x%p", ipbmap); sbi->ipbmap = ipbmap; @@ -134,7 +130,7 @@ * initialize aggregate block allocation map */ if ((rc = dbMount(ipbmap))) { - jERROR(1, ("jfs_mount: dbMount failed w/rc = %d\n", rc)); + jfs_err("jfs_mount: dbMount failed w/rc = %d", rc); goto errout22; } @@ -152,22 +148,20 @@ if ((sbi->mntflag & JFS_BAD_SAIT) == 0) { ipaimap2 = diReadSpecial(sb, AGGREGATE_I, 1); if (ipaimap2 == 0) { - jERROR(1, - ("jfs_mount: Faild to read AGGREGATE_I\n")); + jfs_err("jfs_mount: Faild to read AGGREGATE_I"); rc = EIO; goto errout35; } sbi->ipaimap2 = ipaimap2; - jFYI(1, ("jfs_mount: ipaimap2:0x%p\n", ipaimap2)); + jfs_info("jfs_mount: ipaimap2:0x%p", ipaimap2); /* * initialize secondary aggregate inode allocation map */ if ((rc = diMount(ipaimap2))) { - jERROR(1, - ("jfs_mount: diMount(ipaimap2) failed, rc = %d\n", - rc)); + jfs_err("jfs_mount: diMount(ipaimap2) failed, rc = %d", + rc); goto errout35; } } else @@ -182,23 +176,22 @@ */ ipimap = diReadSpecial(sb, FILESYSTEM_I, 0); if (ipimap == NULL) { - jERROR(1, ("jfs_mount: Failed to read FILESYSTEM_I\n")); + jfs_err("jfs_mount: Failed to read FILESYSTEM_I"); /* open fileset secondary inode allocation map */ rc = EIO; goto errout40; } - jFYI(1, ("jfs_mount: ipimap:0x%p\n", ipimap)); + jfs_info("jfs_mount: ipimap:0x%p", ipimap); /* map further access of per fileset inodes by the fileset inode */ sbi->ipimap = ipimap; /* initialize fileset inode allocation map */ if ((rc = diMount(ipimap))) { - jERROR(1, ("jfs_mount: diMount failed w/rc = %d\n", rc)); + jfs_err("jfs_mount: diMount failed w/rc = %d", rc); goto errout41; } - jFYI(1, ("Mount JFS Complete.\n")); goto out; /* @@ -234,9 +227,9 @@ out: - if (rc) { - jERROR(1, ("Mount JFS Failure: %d\n", rc)); - } + if (rc) + jfs_err("Mount JFS Failure: %d", rc); + return rc; } @@ -265,13 +258,13 @@ truncate_inode_pages(sbi->ipbmap->i_mapping, 0); diUnmount(sbi->ipimap, 1); if ((rc = diMount(sbi->ipimap))) { - jERROR(1,("jfs_mount_rw: diMount failed!\n")); + jfs_err("jfs_mount_rw: diMount failed!"); return rc; } dbUnmount(sbi->ipbmap, 1); if ((rc = dbMount(sbi->ipbmap))) { - jERROR(1,("jfs_mount_rw: dbMount failed!\n")); + jfs_err("jfs_mount_rw: dbMount failed!"); return rc; } } @@ -288,8 +281,7 @@ * update file system superblock; */ if ((rc = updateSuper(sb, FM_MOUNT))) { - jERROR(1, - ("jfs_mount: updateSuper failed w/rc = %d\n", rc)); + jfs_err("jfs_mount: updateSuper failed w/rc = %d", rc); lmLogClose(sb, log); JFS_SBI(sb)->log = 0; return rc; @@ -343,15 +335,15 @@ bsize = le32_to_cpu(j_sb->s_bsize); #ifdef _JFS_4K if (bsize != PSIZE) { - jERROR(1, ("Currently only 4K block size supported!\n")); + jfs_err("Currently only 4K block size supported!"); rc = EINVAL; goto out; } #endif /* _JFS_4K */ - jFYI(1, ("superblock: flag:0x%08x state:0x%08x size:0x%Lx\n", + jfs_info("superblock: flag:0x%08x state:0x%08x size:0x%Lx", le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state), - (unsigned long long) le64_to_cpu(j_sb->s_size))); + (unsigned long long) le64_to_cpu(j_sb->s_size)); /* validate the descriptors for Secondary AIM and AIT */ if ((j_sb->s_flag & cpu_to_le32(JFS_BAD_SAIT)) != @@ -375,15 +367,11 @@ if ((j_sb->s_flag & cpu_to_le32(JFS_GROUPCOMMIT)) != cpu_to_le32(JFS_GROUPCOMMIT)) j_sb->s_flag |= cpu_to_le32(JFS_GROUPCOMMIT); - jFYI(0, ("superblock: flag:0x%08x state:0x%08x size:0x%Lx\n", - le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state), - (unsigned long long) le64_to_cpu(j_sb->s_size))); /* validate fs state */ if (j_sb->s_state != cpu_to_le32(FM_CLEAN) && !(sb->s_flags & MS_RDONLY)) { - jERROR(1, - ("jfs_mount: Mount Failure: File System Dirty.\n")); + jfs_err("jfs_mount: Mount Failure: File System Dirty."); rc = EINVAL; goto out; } diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c --- a/fs/jfs/jfs_txnmgr.c Sun Feb 9 21:13:33 2003 +++ b/fs/jfs/jfs_txnmgr.c Sun Feb 9 21:13:33 2003 @@ -214,7 +214,7 @@ TxAnchor.freelock = TxLock[lid].next; HIGHWATERMARK(stattx.maxlid, lid); if ((++TxAnchor.tlocksInUse > TxLockHWM) && (TxAnchor.TlocksLow == 0)) { - jEVENT(0,("txLockAlloc TlocksLow\n")); + jfs_info("txLockAlloc TlocksLow"); TxAnchor.TlocksLow = 1; wake_up(&jfs_sync_thread_wait); } @@ -228,7 +228,7 @@ TxAnchor.freelock = lid; TxAnchor.tlocksInUse--; if (TxAnchor.TlocksLow && (TxAnchor.tlocksInUse < TxLockLWM)) { - jEVENT(0,("txLockFree TlocksLow no more\n")); + jfs_info("txLockFree TlocksLow no more"); TxAnchor.TlocksLow = 0; TXN_WAKEUP(&TxAnchor.lowlockwait); } @@ -336,7 +336,7 @@ struct tblock *tblk; struct jfs_log *log; - jFYI(1, ("txBegin: flag = 0x%x\n", flag)); + jfs_info("txBegin: flag = 0x%x", flag); log = JFS_SBI(sb)->log; TXN_LOCK(); @@ -372,7 +372,7 @@ * allocate transaction id/block */ if ((t = TxAnchor.freetid) == 0) { - jFYI(1, ("txBegin: waiting for free tid\n")); + jfs_info("txBegin: waiting for free tid"); INCREMENT(TxStat.txBegin_freetid); TXN_SLEEP(&TxAnchor.freewait); goto retry; @@ -382,7 +382,7 @@ if ((tblk->next == 0) && (current != jfsCommitTask)) { /* Save one tblk for jfsCommit thread */ - jFYI(1, ("txBegin: waiting for free tid\n")); + jfs_info("txBegin: waiting for free tid"); INCREMENT(TxStat.txBegin_freetid); TXN_SLEEP(&TxAnchor.freewait); goto retry; @@ -413,7 +413,7 @@ TXN_UNLOCK(); - jFYI(1, ("txBegin: returning tid = %d\n", t)); + jfs_info("txBegin: returning tid = %d", t); return t; } @@ -476,7 +476,7 @@ struct tblock *tblk = tid_to_tblock(tid); struct jfs_log *log; - jFYI(1, ("txEnd: tid = %d\n", tid)); + jfs_info("txEnd: tid = %d", tid); TXN_LOCK(); /* @@ -496,9 +496,7 @@ * routine. */ if (tblk->flag & tblkGC_LAZY) { - jFYI(1, - ("txEnd called w/lazy tid: %d, tblk = 0x%p\n", - tid, tblk)); + jfs_info("txEnd called w/lazy tid: %d, tblk = 0x%p", tid, tblk); TXN_UNLOCK(); spin_lock_irq(&log->gclock); // LOGGC_LOCK @@ -507,7 +505,7 @@ return; } - jFYI(1, ("txEnd: tid: %d, tblk = 0x%p\n", tid, tblk)); + jfs_info("txEnd: tid: %d, tblk = 0x%p", tid, tblk); assert(tblk->next == 0); @@ -529,7 +527,7 @@ /* forward log syncpt */ /* lmSync(log); */ - jFYI(1, (" log barrier off: 0x%x\n", log->lsn)); + jfs_info(" log barrier off: 0x%x", log->lsn); /* enable new transactions start */ clear_bit(log_SYNCBARRIER, &log->flag); @@ -544,7 +542,6 @@ TXN_WAKEUP(&TxAnchor.freewait); TXN_UNLOCK(); - jFYI(1, ("txEnd: exitting\n")); } @@ -589,8 +586,7 @@ if (lid == 0) goto allocateLock; - jFYI(1, ("txLock: tid:%d ip:0x%p mp:0x%p lid:%d\n", - tid, ip, mp, lid)); + jfs_info("txLock: tid:%d ip:0x%p mp:0x%p lid:%d", tid, ip, mp, lid); /* is page locked by the requester transaction ? */ tlck = lid_to_tlock(lid); @@ -676,9 +672,8 @@ mark_metapage_dirty(mp); atomic_inc(&mp->nohomeok); - jFYI(1, - ("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p\n", - mp, atomic_read(&mp->nohomeok), tid, tlck)); + jfs_info("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p", + mp, atomic_read(&mp->nohomeok), tid, tlck); /* if anonymous transaction, and buffer is on the group * commit synclist, mark inode to show this. This will @@ -774,7 +769,7 @@ break; default: - jERROR(1, ("UFO tlock:0x%p\n", tlck)); + jfs_err("UFO tlock:0x%p", tlck); } /* @@ -794,7 +789,7 @@ /* Only locks on ipimap or ipaimap should reach here */ /* assert(jfs_ip->fileset == AGGREGATE_I); */ if (jfs_ip->fileset != AGGREGATE_I) { - jERROR(1, ("txLock: trying to lock locked page!\n")); + jfs_err("txLock: trying to lock locked page!"); dump_mem("ip", ip, sizeof(struct inode)); dump_mem("mp", mp, sizeof(struct metapage)); dump_mem("Locker's tblk", tid_to_tblock(tid), @@ -805,10 +800,10 @@ INCREMENT(stattx.waitlock); /* statistics */ release_metapage(mp); - jEVENT(0, ("txLock: in waitLock, tid = %d, xtid = %d, lid = %d\n", - tid, xtid, lid)); + jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d", + tid, xtid, lid); TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor); - jEVENT(0, ("txLock: awakened tid = %d, lid = %d\n", tid, lid)); + jfs_info("txLock: awakened tid = %d, lid = %d", tid, lid); return NULL; } @@ -869,7 +864,7 @@ struct jfs_log *log; int difft, diffp; - jFYI(1, ("txUnlock: tblk = 0x%p\n", tblk)); + jfs_info("txUnlock: tblk = 0x%p", tblk); log = JFS_SBI(tblk->sb)->log; /* @@ -879,7 +874,7 @@ tlck = lid_to_tlock(lid); next = tlck->next; - jFYI(1, ("unlocking lid = %d, tlck = 0x%p\n", lid, tlck)); + jfs_info("unlocking lid = %d, tlck = 0x%p", lid, tlck); /* unbind page from tlock */ if ((mp = tlck->mp) != NULL && @@ -1113,7 +1108,7 @@ ino_t top; struct super_block *sb; - jFYI(1, ("txCommit, tid = %d, flag = %d\n", tid, flag)); + jfs_info("txCommit, tid = %d, flag = %d", tid, flag); /* is read-only file system ? */ if (isReadOnly(iplist[0])) { rc = EROFS; @@ -1312,7 +1307,7 @@ rc = rc1; TheEnd: - jFYI(1, ("txCommit: tid = %d, returning %d\n", tid, rc)); + jfs_info("txCommit: tid = %d, returning %d", tid, rc); return rc; } @@ -1376,7 +1371,7 @@ break; default: - jERROR(1, ("UFO tlock:0x%p\n", tlck)); + jfs_err("UFO tlock:0x%p", tlck); } if (tlck->mp) release_metapage(tlck->mp); @@ -1462,9 +1457,8 @@ /* mark page as homeward bound */ tlck->flag |= tlckWRITEPAGE; - } else { - jERROR(2, ("diLog: UFO type tlck:0x%p\n", tlck)); - } + } else + jfs_err("diLog: UFO type tlck:0x%p", tlck); #ifdef _JFS_WIP /* * alloc/free external EA extent @@ -1754,9 +1748,8 @@ xadlock->xdlist = &p->xad[lwm]; tblk->xflag &= ~COMMIT_LAZY; } - jFYI(1, - ("xtLog: alloc ip:0x%p mp:0x%p tlck:0x%p lwm:%d count:%d\n", - tlck->ip, mp, tlck, lwm, xadlock->count)); + jfs_info("xtLog: alloc ip:0x%p mp:0x%p tlck:0x%p lwm:%d " + "count:%d", tlck->ip, mp, tlck, lwm, xadlock->count); maplock->index = 1; @@ -1848,9 +1841,8 @@ xadlock->xdlist = &p->xad[XTENTRYSTART]; tblk->xflag &= ~COMMIT_LAZY; } - jFYI(1, - ("xtLog: free ip:0x%p mp:0x%p count:%d lwm:2\n", - tlck->ip, mp, xadlock->count)); + jfs_info("xtLog: free ip:0x%p mp:0x%p count:%d lwm:2", + tlck->ip, mp, xadlock->count); maplock->index = 1; @@ -1978,9 +1970,9 @@ xadlock->count = next - lwm; xadlock->xdlist = &p->xad[lwm]; - jFYI(1, - ("xtLog: alloc ip:0x%p mp:0x%p count:%d lwm:%d next:%d\n", - tlck->ip, mp, xadlock->count, lwm, next)); + jfs_info("xtLog: alloc ip:0x%p mp:0x%p count:%d " + "lwm:%d next:%d", + tlck->ip, mp, xadlock->count, lwm, next); maplock->index++; xadlock++; } @@ -2002,9 +1994,8 @@ pxdlock->count = 1; pxdlock->pxd = tpxd; - jFYI(1, - ("xtLog: truncate ip:0x%p mp:0x%p count:%d hwm:%d\n", - ip, mp, pxdlock->count, hwm)); + jfs_info("xtLog: truncate ip:0x%p mp:0x%p count:%d " + "hwm:%d", ip, mp, pxdlock->count, hwm); maplock->index++; xadlock++; } @@ -2022,9 +2013,9 @@ xadlock->count = hwm - next + 1; xadlock->xdlist = &p->xad[next]; - jFYI(1, - ("xtLog: free ip:0x%p mp:0x%p count:%d next:%d hwm:%d\n", - tlck->ip, mp, xadlock->count, next, hwm)); + jfs_info("xtLog: free ip:0x%p mp:0x%p count:%d " + "next:%d hwm:%d", + tlck->ip, mp, xadlock->count, next, hwm); maplock->index++; } @@ -2111,9 +2102,9 @@ lrd->log.updatemap.pxd = pxdlock->pxd; lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL)); - jFYI(1, ("mapLog: xaddr:0x%lx xlen:0x%x\n", + jfs_info("mapLog: xaddr:0x%lx xlen:0x%x", (ulong) addressPXD(&pxdlock->pxd), - lengthPXD(&pxdlock->pxd))); + lengthPXD(&pxdlock->pxd)); } /* update bmap */ @@ -2429,9 +2420,8 @@ dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk); xad->flag &= ~(XAD_NEW | XAD_EXTENDED); - jFYI(1, - ("allocPMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("allocPMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } } } else if (maplock->flag & mlckALLOCPXD) { @@ -2439,9 +2429,7 @@ xaddr = addressPXD(&pxdlock->pxd); xlen = lengthPXD(&pxdlock->pxd); dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk); - jFYI(1, - ("allocPMap: xaddr:0x%lx xlen:%d\n", (ulong) xaddr, - xlen)); + jfs_info("allocPMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen); } else { /* (maplock->flag & mlckALLOCPXDLIST) */ pxdlistlock = (struct xdlistlock *) maplock; @@ -2451,9 +2439,8 @@ xlen = lengthPXD(pxd); dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk); - jFYI(1, - ("allocPMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("allocPMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } } } @@ -2479,9 +2466,8 @@ pxd_t *pxd; int n; - jFYI(1, - ("txFreeMap: tblk:0x%p maplock:0x%p maptype:0x%x\n", - tblk, maplock, maptype)); + jfs_info("txFreeMap: tblk:0x%p maplock:0x%p maptype:0x%x", + tblk, maplock, maptype); /* * free from persistent map; @@ -2496,9 +2482,9 @@ xlen = lengthXAD(xad); dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen, tblk); - jFYI(1, - ("freePMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freePMap: xaddr:0x%lx " + "xlen:%d", + (ulong) xaddr, xlen); } } } else if (maplock->flag & mlckFREEPXD) { @@ -2507,9 +2493,8 @@ xlen = lengthPXD(&pxdlock->pxd); dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen, tblk); - jFYI(1, - ("freePMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freePMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } else { /* (maplock->flag & mlckALLOCPXDLIST) */ pxdlistlock = (struct xdlistlock *) maplock; @@ -2519,9 +2504,8 @@ xlen = lengthPXD(pxd); dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen, tblk); - jFYI(1, - ("freePMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freePMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } } } @@ -2538,18 +2522,16 @@ xlen = lengthXAD(xad); dbFree(ip, xaddr, (s64) xlen); xad->flag = 0; - jFYI(1, - ("freeWMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freeWMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } } else if (maplock->flag & mlckFREEPXD) { pxdlock = (struct pxd_lock *) maplock; xaddr = addressPXD(&pxdlock->pxd); xlen = lengthPXD(&pxdlock->pxd); dbFree(ip, xaddr, (s64) xlen); - jFYI(1, - ("freeWMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freeWMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } else { /* (maplock->flag & mlckFREEPXDLIST) */ pxdlistlock = (struct xdlistlock *) maplock; @@ -2558,9 +2540,8 @@ xaddr = addressPXD(pxd); xlen = lengthPXD(pxd); dbFree(ip, xaddr, (s64) xlen); - jFYI(1, - ("freeWMap: xaddr:0x%lx xlen:%d\n", - (ulong) xaddr, xlen)); + jfs_info("freeWMap: xaddr:0x%lx xlen:%d", + (ulong) xaddr, xlen); } } } @@ -2625,7 +2606,7 @@ struct metapage *mp; struct tblock *tblk = tid_to_tblock(tid); - jEVENT(1, ("txAbort: tid:%d dirty:0x%x\n", tid, dirty)); + jfs_warn("txAbort: tid:%d dirty:0x%x", tid, dirty); /* * free tlocks of the transaction @@ -2688,7 +2669,7 @@ struct metapage *mp; assert(exval == EIO || exval == ENOMEM); - jEVENT(1, ("txAbortCommit: cd:0x%p\n", cd)); + jfs_warn("txAbortCommit: cd:0x%p", cd); /* * free tlocks of the transaction @@ -2743,12 +2724,11 @@ ((tblk->flag & tblkGC_UNLOCKED) == 0)) { /* We must have gotten ahead of the user thread */ - jFYI(1, - ("jfs_lazycommit: tblk 0x%p not unlocked\n", tblk)); + jfs_info("jfs_lazycommit: tblk 0x%p not unlocked", tblk); schedule(); } - jFYI(1, ("txLazyCommit: processing tblk 0x%p\n", tblk)); + jfs_info("txLazyCommit: processing tblk 0x%p", tblk); txUpdateMap(tblk); @@ -2775,7 +2755,7 @@ } else spin_unlock_irq(&log->gclock); // LOGGC_UNLOCK - jFYI(1, ("txLazyCommit: done: tblk = 0x%p\n", tblk)); + jfs_info("txLazyCommit: done: tblk = 0x%p", tblk); } /* @@ -2800,10 +2780,10 @@ jfsCommitTask = current; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigfillset(¤t->blocked); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); LAZY_LOCK_INIT(); TxAnchor.unlock_queue = TxAnchor.unlock_tail = 0; @@ -2835,7 +2815,7 @@ txLazyCommit(tblk); /* - * We can be running indefinately if other processors + * We can be running indefinitely if other processors * are adding transactions to this list */ cond_resched(); @@ -2861,9 +2841,9 @@ } while (!jfs_stop_threads); if (TxAnchor.unlock_queue) - jERROR(1, ("jfs_lazycommit being killed with pending transactions!\n")); + jfs_err("jfs_lazycommit being killed w/pending transactions!"); else - jFYI(1, ("jfs_lazycommit being killed\n")); + jfs_info("jfs_lazycommit being killed\n"); complete(&jfsIOwait); return 0; } @@ -3005,10 +2985,10 @@ unlock_kernel(); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigfillset(¤t->blocked); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); complete(&jfsIOwait); @@ -3077,7 +3057,7 @@ } } while (!jfs_stop_threads); - jFYI(1, ("jfs_sync being killed\n")); + jfs_info("jfs_sync being killed"); complete(&jfsIOwait); return 0; } diff -Nru a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c --- a/fs/jfs/jfs_umount.c Sun Feb 9 21:13:32 2003 +++ b/fs/jfs/jfs_umount.c Sun Feb 9 21:13:32 2003 @@ -58,7 +58,7 @@ struct jfs_log *log; int rc = 0; - jFYI(1, ("\n UnMount JFS: sb:0x%p\n", sb)); + jfs_info("UnMount JFS: sb:0x%p", sb); /* * update superblock and close log @@ -74,7 +74,6 @@ /* * close fileset inode allocation map (aka fileset inode) */ - jEVENT(0, ("jfs_umount: close ipimap:0x%p\n", ipimap)); diUnmount(ipimap, 0); diFreeSpecial(ipimap); @@ -85,7 +84,6 @@ */ ipaimap2 = sbi->ipaimap2; if (ipaimap2) { - jEVENT(0, ("jfs_umount: close ipaimap2:0x%p\n", ipaimap2)); diUnmount(ipaimap2, 0); diFreeSpecial(ipaimap2); sbi->ipaimap2 = NULL; @@ -95,7 +93,6 @@ * close aggregate inode allocation map */ ipaimap = sbi->ipaimap; - jEVENT(0, ("jfs_umount: close ipaimap:0x%p\n", ipaimap)); diUnmount(ipaimap, 0); diFreeSpecial(ipaimap); sbi->ipaimap = NULL; @@ -103,7 +100,6 @@ /* * close aggregate block allocation map */ - jEVENT(0, ("jfs_umount: close ipbmap:%p\n", ipbmap)); dbUnmount(ipbmap, 0); diFreeSpecial(ipbmap); @@ -134,7 +130,7 @@ */ rc = lmLogClose(sb, log); } - jFYI(0, (" UnMount JFS Complete: %d\n", rc)); + jfs_info("UnMount JFS Complete: rc = %d", rc); return rc; } diff -Nru a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c --- a/fs/jfs/jfs_unicode.c Sun Feb 9 21:13:35 2003 +++ b/fs/jfs/jfs_unicode.c Sun Feb 9 21:13:35 2003 @@ -47,7 +47,6 @@ } } to[outlen] = 0; - jEVENT(0, ("jfs_strfromUCS returning %d - '%s'\n", outlen, to)); return outlen; } @@ -63,21 +62,16 @@ int charlen; int i; - jEVENT(0, ("jfs_strtoUCS - '%s'\n", from)); - for (i = 0; len && *from; i++, from += charlen, len -= charlen) { charlen = codepage->char2uni(from, len, &to[i]); if (charlen < 1) { - jERROR(1, ("jfs_strtoUCS: char2uni returned %d.\n", - charlen)); - jERROR(1, ("charset = %s, char = 0x%x\n", - codepage->charset, (unsigned char) *from)); + jfs_err("jfs_strtoUCS: char2uni returned %d.", charlen); + jfs_err("charset = %s, char = 0x%x", + codepage->charset, (unsigned char) *from); to[i] = 0x003f; /* a question mark */ charlen = 1; } } - - jEVENT(0, (" returning %d\n", i)); to[i] = 0; return i; diff -Nru a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c --- a/fs/jfs/jfs_xtree.c Sun Feb 9 21:13:32 2003 +++ b/fs/jfs/jfs_xtree.c Sun Feb 9 21:13:32 2003 @@ -69,7 +69,7 @@ (le16_to_cpu((P)->header.nextindex) > le16_to_cpu((P)->header.maxentry)) ||\ (le16_to_cpu((P)->header.maxentry) > (((BN)==0)?XTROOTMAXSLOT:PSIZE>>L2XTSLOTSIZE)))\ {\ - jERROR(1,("XT_GETPAGE: xtree page corrupt\n"));\ + jfs_err("XT_GETPAGE: xtree page corrupt");\ BT_PUTPAGE(MP);\ updateSuper((IP)->i_sb, FM_DIRTY);\ MP = NULL;\ @@ -169,9 +169,8 @@ size = ((u64) ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >> JFS_SBI(ip->i_sb)->l2bsize; if (lstart >= size) { - jERROR(1, - ("xtLookup: lstart (0x%lx) >= size (0x%lx)\n", - (ulong) lstart, (ulong) size)); + jfs_err("xtLookup: lstart (0x%lx) >= size (0x%lx)", + (ulong) lstart, (ulong) size); return 0; } } @@ -181,7 +180,7 @@ */ //search: if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) { - jERROR(1, ("xtLookup: xtSearch returned %d\n", rc)); + jfs_err("xtLookup: xtSearch returned %d", rc); return rc; } @@ -198,10 +197,8 @@ * lstart is a page start address, * i.e., lstart cannot start in a hole; */ - if (cmp) { - jFYI(1, ("xtLookup: cmp = %d\n", cmp)); + if (cmp) goto out; - } /* * lxd covered by xad @@ -212,10 +209,6 @@ xend = xoff + xlen; xaddr = addressXAD(xad); - jEVENT(0, - ("index = %d, xoff = 0x%lx, xlen = 0x%x, xaddr = 0x%lx\n", - index, (ulong) xoff, xlen, (ulong) xaddr)); - /* initialize new pxd */ *pflag = xad->flag; *paddr = xaddr + (lstart - xoff); @@ -802,8 +795,7 @@ struct tlock *tlck; struct xtlock *xtlck; - jFYI(1, - ("xtInsert: nxoff:0x%lx nxlen:0x%x\n", (ulong) xoff, xlen)); + jfs_info("xtInsert: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); /* * search for the entry location at which to insert: @@ -1248,8 +1240,7 @@ if (rmp == NULL) return EIO; - jEVENT(0, - ("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p\n", ip, smp, rmp)); + jfs_info("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp); BT_MARK_DIRTY(rmp, ip); /* @@ -1324,7 +1315,7 @@ ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd)); - jEVENT(0, ("xtSplitPage: sp:0x%p rp:0x%p\n", sp, rp)); + jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp); return 0; } @@ -1440,7 +1431,7 @@ ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd)); - jEVENT(0, ("xtSplitPage: sp:0x%p rp:0x%p\n", sp, rp)); + jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp); return rc; } @@ -1496,7 +1487,7 @@ if (rmp == NULL) return EIO; - jEVENT(0, ("xtSplitRoot: ip:0x%p rmp:0x%p\n", ip, rmp)); + jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp); /* * acquire a transaction lock on the new right page; @@ -1581,7 +1572,7 @@ ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd)); - jEVENT(0, ("xtSplitRoot: sp:0x%p rp:0x%p\n", sp, rp)); + jfs_info("xtSplitRoot: sp:0x%p rp:0x%p", sp, rp); return 0; } @@ -1615,8 +1606,7 @@ struct xtlock *xtlck = 0; int rootsplit = 0; - jFYI(1, - ("xtExtend: nxoff:0x%lx nxlen:0x%x\n", (ulong) xoff, xlen)); + jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); /* there must exist extent to be extended */ if ((rc = xtSearch(ip, xoff - 1, &cmp, &btstack, XT_INSERT))) @@ -1628,9 +1618,6 @@ /* extension must be contiguous */ xad = &p->xad[index]; - jFYI(0, ("xtExtend: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n", - (ulong) offsetXAD(xad), lengthXAD(xad), - (ulong) addressXAD(xad))); assert((offsetXAD(xad) + lengthXAD(xad)) == xoff); /* @@ -1893,10 +1880,6 @@ PXDlength(&pxdlock->pxd, rlen); pxdlock->index = 1; } - jEVENT(0, - ("xtTailgate: free extent xaddr:0x%lx xlen:0x%x\n", - (ulong) addressPXD(&pxdlock->pxd), - lengthPXD(&pxdlock->pxd))); } else /* free from WMAP */ dbFree(ip, addressXAD(xad) + llen, (s64) rlen); @@ -2408,9 +2391,8 @@ xaddr = *xaddrp; xlen = *xlenp; - jEVENT(0, - ("xtAppend: xoff:0x%lx maxblocks:%d xlen:%d xaddr:0x%lx\n", - (ulong) xoff, maxblocks, xlen, (ulong) xaddr)); + jfs_info("xtAppend: xoff:0x%lx maxblocks:%d xlen:%d xaddr:0x%lx", + (ulong) xoff, maxblocks, xlen, (ulong) xaddr); /* * search for the entry location at which to insert: @@ -2747,9 +2729,8 @@ p->header.nextindex = cpu_to_le16(le16_to_cpu(p->header.nextindex) - 1); - jEVENT(0, - ("xtDeleteUp(entry): 0x%lx[%d]\n", - (ulong) parent->bn, index)); + jfs_info("xtDeleteUp(entry): 0x%lx[%d]", + (ulong) parent->bn, index); } /* unpin the parent page */ @@ -2809,10 +2790,8 @@ if (offset >= ip->i_size) return ESTALE; /* stale extent */ - jEVENT(0, - ("xtRelocate: xtype:%d xoff:0x%lx xlen:0x%x xaddr:0x%lx:0x%lx\n", - xtype, (ulong) xoff, xlen, (ulong) oxaddr, - (ulong) nxaddr)); + jfs_info("xtRelocate: xtype:%d xoff:0x%lx xlen:0x%x xaddr:0x%lx:0x%lx", + xtype, (ulong) xoff, xlen, (ulong) oxaddr, (ulong) nxaddr); /* * 1. get and validate the parent xtpage/xad entry @@ -2855,7 +2834,7 @@ */ xad = &pp->xad[index]; } - jEVENT(0, ("xtRelocate: parent xad entry validated.\n")); + jfs_info("xtRelocate: parent xad entry validated."); /* * 2. relocate the extent @@ -2926,7 +2905,7 @@ /* get back parent page */ rc = xtSearch(ip, xoff, &cmp, &btstack, 0); XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); - jEVENT(0, ("xtRelocate: target data extent relocated.\n")); + jfs_info("xtRelocate: target data extent relocated."); } else { /* (xtype == XTPAGE) */ /* @@ -3026,7 +3005,7 @@ /* unpin the target page to new homeward bound */ XT_PUTPAGE(mp); - jEVENT(0, ("xtRelocate: target xtpage relocated.\n")); + jfs_info("xtRelocate: target xtpage relocated."); } /* @@ -3067,7 +3046,7 @@ * update which will write LOG_REDOPAGE and update bmap for * allocation of XAD_NEW destination extent; */ - jEVENT(0, ("xtRelocate: update parent xad entry.\n")); + jfs_info("xtRelocate: update parent xad entry."); BT_MARK_DIRTY(pmp, ip); tlck = txLock(tid, ip, pmp, tlckXTREE | tlckGROW); xtlck = (struct xtlock *) & tlck->lock; diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c --- a/fs/jfs/namei.c Sun Feb 9 21:13:34 2003 +++ b/fs/jfs/namei.c Sun Feb 9 21:13:34 2003 @@ -70,7 +70,7 @@ struct inode *iplist[2]; struct tblock *tblk; - jFYI(1, ("jfs_create: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + jfs_info("jfs_create: dip:0x%p name:%s", dip, dentry->d_name.name); /* * search parent directory for entry/freespace @@ -96,7 +96,7 @@ down(&JFS_IP(ip)->commit_sem); if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { - jERROR(1, ("jfs_create: dtSearch returned %d\n", rc)); + jfs_err("jfs_create: dtSearch returned %d", rc); goto out3; } @@ -118,7 +118,7 @@ */ ino = ip->i_ino; if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { - jERROR(1, ("jfs_create: dtInsert returned %d\n", rc)); + jfs_err("jfs_create: dtInsert returned %d", rc); if (rc == EIO) txAbort(tid, 1); /* Marks Filesystem dirty */ else @@ -159,7 +159,7 @@ out1: - jFYI(1, ("jfs_create: rc:%d\n", -rc)); + jfs_info("jfs_create: rc:%d", -rc); return -rc; } @@ -190,7 +190,7 @@ struct inode *iplist[2]; struct tblock *tblk; - jFYI(1, ("jfs_mkdir: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + jfs_info("jfs_mkdir: dip:0x%p name:%s", dip, dentry->d_name.name); /* link count overflow on parent directory ? */ if (dip->i_nlink == JFS_LINK_MAX) { @@ -222,7 +222,7 @@ down(&JFS_IP(ip)->commit_sem); if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { - jERROR(1, ("jfs_mkdir: dtSearch returned %d\n", rc)); + jfs_err("jfs_mkdir: dtSearch returned %d", rc); goto out3; } @@ -244,7 +244,7 @@ */ ino = ip->i_ino; if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { - jERROR(1, ("jfs_mkdir: dtInsert returned %d\n", rc)); + jfs_err("jfs_mkdir: dtInsert returned %d", rc); if (rc == EIO) txAbort(tid, 1); /* Marks Filesystem dirty */ @@ -289,7 +289,7 @@ out1: - jFYI(1, ("jfs_mkdir: rc:%d\n", -rc)); + jfs_info("jfs_mkdir: rc:%d", -rc); return -rc; } @@ -322,7 +322,7 @@ struct inode *iplist[2]; struct tblock *tblk; - jFYI(1, ("jfs_rmdir: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); /* directory must be empty to be removed */ if (!dtEmpty(ip)) { @@ -351,7 +351,7 @@ */ ino = ip->i_ino; if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) { - jERROR(1, ("jfs_rmdir: dtDelete returned %d\n", rc)); + jfs_err("jfs_rmdir: dtDelete returned %d", rc); if (rc == EIO) txAbort(tid, 1); txEnd(tid); @@ -411,7 +411,7 @@ free_UCSname(&dname); out: - jFYI(1, ("jfs_rmdir: rc:%d\n", rc)); + jfs_info("jfs_rmdir: rc:%d", rc); return -rc; } @@ -447,7 +447,7 @@ s64 new_size = 0; int commit_flag; - jFYI(1, ("jfs_unlink: dip:0x%p name:%s\n", dip, dentry->d_name.name)); + jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name); if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) goto out; @@ -467,7 +467,7 @@ */ ino = ip->i_ino; if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) { - jERROR(1, ("jfs_unlink: dtDelete returned %d\n", rc)); + jfs_err("jfs_unlink: dtDelete returned %d", rc); if (rc == EIO) txAbort(tid, 1); /* Marks FS Dirty */ txEnd(tid); @@ -560,7 +560,7 @@ out1: free_UCSname(&dname); out: - jFYI(1, ("jfs_unlink: rc:%d\n", -rc)); + jfs_info("jfs_unlink: rc:%d", -rc); return -rc; } @@ -593,7 +593,7 @@ int filetype; struct tblock *tblk; - jFYI(1, ("commitZeroLink: tid = %d, ip = 0x%p\n", tid, ip)); + jfs_info("commitZeroLink: tid = %d, ip = 0x%p", tid, ip); filetype = ip->i_mode & S_IFMT; switch (filetype) { @@ -661,7 +661,7 @@ int rc = 0; int type; - jFYI(1, ("freeZeroLink: ip = 0x%p\n", ip)); + jfs_info("freeZeroLink: ip = 0x%p", ip); /* return if not reg or symbolic link or if size is * already ok. @@ -767,9 +767,8 @@ struct btstack btstack; struct inode *iplist[2]; - jFYI(1, - ("jfs_link: %s %s\n", old_dentry->d_name.name, - dentry->d_name.name)); + jfs_info("jfs_link: %s %s", old_dentry->d_name.name, + dentry->d_name.name); tid = txBegin(ip->i_sb, 0); @@ -814,7 +813,7 @@ up(&JFS_IP(dir)->commit_sem); up(&JFS_IP(ip)->commit_sem); - jFYI(1, ("jfs_link: rc:%d\n", rc)); + jfs_info("jfs_link: rc:%d", rc); return -rc; } @@ -855,7 +854,7 @@ struct inode *iplist[2]; - jFYI(1, ("jfs_symlink: dip:0x%p name:%s\n", dip, name)); + jfs_info("jfs_symlink: dip:0x%p name:%s", dip, name); ssize = strlen(name) + 1; @@ -898,7 +897,7 @@ if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { - jERROR(1, ("jfs_symlink: dtInsert returned %d\n", rc)); + jfs_err("jfs_symlink: dtInsert returned %d", rc); /* discard ne inode */ goto out3; @@ -933,15 +932,14 @@ if (ssize > sizeof (JFS_IP(ip)->i_inline)) JFS_IP(ip)->mode2 &= ~INLINEEA; - jFYI(1, - ("jfs_symlink: fast symlink added ssize:%d name:%s \n", - ssize, name)); + jfs_info("jfs_symlink: fast symlink added ssize:%d name:%s ", + ssize, name); } /* * write source path name in a single extent */ else { - jFYI(1, ("jfs_symlink: allocate extent ip:0x%p\n", ip)); + jfs_info("jfs_symlink: allocate extent ip:0x%p", ip); ip->i_op = &page_symlink_inode_operations; ip->i_mapping->a_ops = &jfs_aops; @@ -1033,7 +1031,7 @@ #endif out1: - jFYI(1, ("jfs_symlink: rc:%d\n", -rc)); + jfs_info("jfs_symlink: rc:%d", -rc); return -rc; } @@ -1064,9 +1062,8 @@ int commit_flag; - jFYI(1, - ("jfs_rename: %s %s\n", old_dentry->d_name.name, - new_dentry->d_name.name)); + jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, + new_dentry->d_name.name); old_ip = old_dentry->d_inode; new_ip = new_dentry->d_inode; @@ -1168,18 +1165,16 @@ rc = dtSearch(new_dir, &new_dname, &ino, &btstack, JFS_CREATE); if (rc) { - jERROR(1, - ("jfs_rename didn't expect dtSearch to fail w/rc = %d\n", - rc)); + jfs_err("jfs_rename didn't expect dtSearch to fail " + "w/rc = %d", rc); goto out4; } ino = old_ip->i_ino; rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack); if (rc) { - jERROR(1, - ("jfs_rename: dtInsert failed w/rc = %d\n", - rc)); + jfs_err("jfs_rename: dtInsert failed w/rc = %d", + rc); goto out4; } if (S_ISDIR(old_ip->i_mode)) @@ -1192,9 +1187,8 @@ ino = old_ip->i_ino; rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE); if (rc) { - jERROR(1, - ("jfs_rename did not expect dtDelete to return rc = %d\n", - rc)); + jfs_err("jfs_rename did not expect dtDelete to return rc = %d", + rc); txAbort(tid, 1); /* Marks Filesystem dirty */ goto out4; } @@ -1297,7 +1291,7 @@ clear_cflag(COMMIT_Stale, old_dir); } - jFYI(1, ("jfs_rename: returning %d\n", rc)); + jfs_info("jfs_rename: returning %d", rc); return -rc; } @@ -1318,7 +1312,7 @@ tid_t tid; struct tblock *tblk; - jFYI(1, ("jfs_mknod: %s\n", dentry->d_name.name)); + jfs_info("jfs_mknod: %s", dentry->d_name.name); if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab))) goto out; @@ -1378,7 +1372,7 @@ #endif out: - jFYI(1, ("jfs_mknod: returning %d\n", rc)); + jfs_info("jfs_mknod: returning %d", rc); return -rc; } @@ -1392,7 +1386,7 @@ int len = dentry->d_name.len; int rc; - jFYI(1, ("jfs_lookup: name = %s\n", name)); + jfs_info("jfs_lookup: name = %s", name); if ((name[0] == '.') && (len == 1)) @@ -1409,17 +1403,14 @@ d_add(dentry, NULL); return ERR_PTR(0); } else if (rc) { - jERROR(1, - ("jfs_lookup: dtSearch returned %d\n", rc)); + jfs_err("jfs_lookup: dtSearch returned %d", rc); return ERR_PTR(-rc); } } ip = jfs_iget(dip->i_sb, inum); if (ip == NULL) { - jERROR(1, - ("jfs_lookup: iget failed on inum %d\n", - (uint) inum)); + jfs_err("jfs_lookup: iget failed on inum %d", (uint) inum); return ERR_PTR(-EACCES); } diff -Nru a/fs/jfs/super.c b/fs/jfs/super.c --- a/fs/jfs/super.c Sun Feb 9 21:13:31 2003 +++ b/fs/jfs/super.c Sun Feb 9 21:13:31 2003 @@ -50,7 +50,7 @@ DECLARE_COMPLETION(jfsIOwait); #ifdef CONFIG_JFS_DEBUG -int jfsloglevel = 1; +int jfsloglevel = JFS_LOGLEVEL_WARN; MODULE_PARM(jfsloglevel, "i"); MODULE_PARM_DESC(jfsloglevel, "Specify JFS loglevel (0, 1 or 2)"); #endif @@ -120,7 +120,7 @@ s64 maxinodes; struct inomap *imap = JFS_IP(sbi->ipimap)->i_imap; - jFYI(1, ("In jfs_statfs\n")); + jfs_info("In jfs_statfs"); buf->f_type = JFS_SUPER_MAGIC; buf->f_bsize = sbi->bsize; buf->f_blocks = sbi->bmap->db_mapsize; @@ -151,11 +151,10 @@ struct jfs_sb_info *sbi = JFS_SBI(sb); int rc; - jFYI(1, ("In jfs_put_super\n")); + jfs_info("In jfs_put_super"); rc = jfs_umount(sb); - if (rc) { - jERROR(1, ("jfs_umount failed with return code %d\n", rc)); - } + if (rc) + jfs_err("jfs_umount failed with return code %d", rc); unload_nls(sbi->nls_tab); sbi->nls_tab = NULL; @@ -259,7 +258,7 @@ int rc; s64 newLVSize = 0; - jFYI(1, ("In jfs_read_super: s_flags=0x%lx\n", sb->s_flags)); + jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags); sbi = kmalloc(sizeof (struct jfs_sb_info), GFP_KERNEL); if (!sbi) @@ -291,8 +290,7 @@ rc = jfs_mount(sb); if (rc) { if (!silent) { - jERROR(1, - ("jfs_mount failed w/return code = %d\n", rc)); + jfs_err("jfs_mount failed w/return code = %d", rc); } goto out_kfree; } @@ -302,9 +300,8 @@ rc = jfs_mount_rw(sb, 0); if (rc) { if (!silent) { - jERROR(1, - ("jfs_mount_rw failed w/return code = %d\n", - rc)); + jfs_err("jfs_mount_rw failed, return code = %d", + rc); } goto out_no_rw; } @@ -335,14 +332,14 @@ return 0; out_no_root: - jEVENT(1, ("jfs_read_super: get root inode failed\n")); + jfs_err("jfs_read_super: get root inode failed"); if (inode) iput(inode); out_no_rw: rc = jfs_umount(sb); if (rc) { - jERROR(1, ("jfs_umount failed with return code %d\n", rc)); + jfs_err("jfs_umount failed with return code %d", rc); } out_kfree: if (sbi->nls_tab) @@ -370,8 +367,7 @@ if (!(sb->s_flags & MS_RDONLY)) { if ((rc = lmLogInit(log))) - jERROR(1, - ("jfs_unlock failed with return code %d\n", rc)); + jfs_err("jfs_unlock failed with return code %d", rc); else txResume(sb); } @@ -458,7 +454,7 @@ */ rc = metapage_init(); if (rc) { - jERROR(1, ("metapage_init failed w/rc = %d\n", rc)); + jfs_err("metapage_init failed w/rc = %d", rc); goto free_slab; } @@ -467,7 +463,7 @@ */ rc = txInit(); if (rc) { - jERROR(1, ("txInit failed w/rc = %d\n", rc)); + jfs_err("txInit failed w/rc = %d", rc); goto free_metapage; } @@ -477,8 +473,7 @@ jfsIOthread = kernel_thread(jfsIOWait, 0, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); if (jfsIOthread < 0) { - jERROR(1, - ("init_jfs_fs: fork failed w/rc = %d\n", jfsIOthread)); + jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsIOthread); goto end_txmngr; } wait_for_completion(&jfsIOwait); /* Wait until thread starts */ @@ -486,9 +481,7 @@ jfsCommitThread = kernel_thread(jfs_lazycommit, 0, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); if (jfsCommitThread < 0) { - jERROR(1, - ("init_jfs_fs: fork failed w/rc = %d\n", - jfsCommitThread)); + jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsCommitThread); goto kill_iotask; } wait_for_completion(&jfsIOwait); /* Wait until thread starts */ @@ -496,8 +489,7 @@ jfsSyncThread = kernel_thread(jfs_sync, 0, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); if (jfsSyncThread < 0) { - jERROR(1, - ("init_jfs_fs: fork failed w/rc = %d\n", jfsSyncThread)); + jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsSyncThread); goto kill_committask; } wait_for_completion(&jfsIOwait); /* Wait until thread starts */ @@ -527,7 +519,7 @@ static void __exit exit_jfs_fs(void) { - jFYI(1, ("exit_jfs_fs called\n")); + jfs_info("exit_jfs_fs called"); jfs_stop_threads = 1; txExit(); diff -Nru a/fs/lockd/Makefile b/fs/lockd/Makefile --- a/fs/lockd/Makefile Sun Feb 9 21:13:29 2003 +++ b/fs/lockd/Makefile Sun Feb 9 21:13:29 2003 @@ -2,8 +2,6 @@ # Makefile for the linux lock manager stuff # -export-objs := lockd_syms.o - obj-$(CONFIG_LOCKD) += lockd.o lockd-objs-y := clntlock.o clntproc.o host.o svc.o svclock.o svcshare.o \ diff -Nru a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c --- a/fs/lockd/clntproc.c Sun Feb 9 21:13:28 2003 +++ b/fs/lockd/clntproc.c Sun Feb 9 21:13:28 2003 @@ -139,7 +139,7 @@ } /* Keep the old signal mask */ - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); oldset = current->blocked; /* If we're cleaning up locks because the process is exiting, @@ -149,7 +149,7 @@ && (current->flags & PF_EXITING)) { sigfillset(¤t->blocked); /* Mask all signals */ recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); call = nlmclnt_alloc_call(); if (!call) { @@ -158,7 +158,7 @@ } call->a_flags = RPC_TASK_ASYNC; } else { - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); memset(call, 0, sizeof(*call)); locks_init_lock(&call->a_args.lock.fl); locks_init_lock(&call->a_res.lock.fl); @@ -183,10 +183,10 @@ kfree(call); out_restore: - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); current->blocked = oldset; recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); done: dprintk("lockd: clnt proc returns %d\n", status); @@ -588,11 +588,11 @@ int status; /* Block all signals while setting up call */ - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); oldset = current->blocked; sigfillset(¤t->blocked); recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); req = nlmclnt_alloc_call(); if (!req) @@ -607,10 +607,10 @@ if (status < 0) kfree(req); - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); current->blocked = oldset; recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); return status; } diff -Nru a/fs/lockd/svc.c b/fs/lockd/svc.c --- a/fs/lockd/svc.c Sun Feb 9 21:13:33 2003 +++ b/fs/lockd/svc.c Sun Feb 9 21:13:33 2003 @@ -101,10 +101,10 @@ sprintf(current->comm, "lockd"); /* Process request with signals blocked. */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked, sigmask(SIGKILL)); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); /* kick rpciod */ rpciod_up(); @@ -126,9 +126,9 @@ { long timeout = MAX_SCHEDULE_TIMEOUT; if (signalled()) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); flush_signals(current); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (nlmsvc_ops) { nlmsvc_invalidate_all(); grace_period_expire = set_grace_period(); @@ -297,9 +297,9 @@ "lockd_down: lockd failed to exit, clearing pid\n"); nlmsvc_pid = 0; } - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); out: up(&nlmsvc_sema); } diff -Nru a/fs/mpage.c b/fs/mpage.c --- a/fs/mpage.c Sun Feb 9 21:13:29 2003 +++ b/fs/mpage.c Sun Feb 9 21:13:29 2003 @@ -116,6 +116,49 @@ return bio; } +/* + * support function for mpage_readpages. The fs supplied get_block might + * return an up to date buffer. This is used to map that buffer into + * the page, which allows readpage to avoid triggering a duplicate call + * to get_block. + * + * The idea is to avoid adding buffers to pages that don't already have + * them. So when the buffer is up to date and the page size == block size, + * this marks the page up to date instead of adding new buffers. + */ +static void +map_buffer_to_page(struct page *page, struct buffer_head *bh, int page_block) +{ + struct inode *inode = page->mapping->host; + struct buffer_head *page_bh, *head; + int block = 0; + + if (!page_has_buffers(page)) { + /* + * don't make any buffers if there is only one buffer on + * the page and the page just needs to be set up to date + */ + if (inode->i_blkbits == PAGE_CACHE_SHIFT && + buffer_uptodate(bh)) { + SetPageUptodate(page); + return; + } + create_empty_buffers(page, 1 << inode->i_blkbits, 0); + } + head = page_buffers(page); + page_bh = head; + do { + if (block == page_block) { + page_bh->b_state = bh->b_state; + page_bh->b_bdev = bh->b_bdev; + page_bh->b_blocknr = bh->b_blocknr; + break; + } + page_bh = page_bh->b_this_page; + block++; + } while (page_bh != head); +} + /** * mpage_readpages - populate an address space with some pages, and * start reads against them. @@ -186,6 +229,7 @@ block_in_file = page->index << (PAGE_CACHE_SHIFT - blkbits); last_block = (inode->i_size + blocksize - 1) >> blkbits; + bh.b_page = page; for (page_block = 0; page_block < blocks_per_page; page_block++, block_in_file++) { bh.b_state = 0; @@ -200,6 +244,17 @@ first_hole = page_block; continue; } + + /* some filesystems will copy data into the page during + * the get_block call, in which case we don't want to + * read it again. map_buffer_to_page copies the data + * we just collected from get_block into the page's buffers + * so readpage doesn't have to repeat the get_block call + */ + if (buffer_uptodate(&bh)) { + map_buffer_to_page(page, &bh, page_block); + goto confused; + } if (first_hole != blocks_per_page) goto confused; /* hole -> non-hole */ @@ -256,7 +311,10 @@ confused: if (bio) bio = mpage_bio_submit(READ, bio); - block_read_full_page(page, get_block); + if (!PageUptodate(page)) + block_read_full_page(page, get_block); + else + unlock_page(page); goto out; } @@ -344,6 +402,7 @@ sector_t boundary_block = 0; struct block_device *boundary_bdev = NULL; int length; + struct buffer_head map_bh; if (page_has_buffers(page)) { struct buffer_head *head = page_buffers(page); @@ -401,8 +460,8 @@ BUG_ON(!PageUptodate(page)); block_in_file = page->index << (PAGE_CACHE_SHIFT - blkbits); last_block = (inode->i_size - 1) >> blkbits; + map_bh.b_page = page; for (page_block = 0; page_block < blocks_per_page; ) { - struct buffer_head map_bh; map_bh.b_state = 0; if (get_block(inode, block_in_file, &map_bh, 1)) @@ -559,7 +618,6 @@ int (*writepage)(struct page *page, struct writeback_control *wbc); if (wbc->nonblocking && bdi_write_congested(bdi)) { - blk_run_queues(); wbc->encountered_congestion = 1; return 0; } @@ -614,7 +672,6 @@ if (ret || (--(wbc->nr_to_write) <= 0)) done = 1; if (wbc->nonblocking && bdi_write_congested(bdi)) { - blk_run_queues(); wbc->encountered_congestion = 1; done = 1; } diff -Nru a/fs/msdos/Makefile b/fs/msdos/Makefile --- a/fs/msdos/Makefile Sun Feb 9 21:13:36 2003 +++ b/fs/msdos/Makefile Sun Feb 9 21:13:36 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux msdos filesystem routines. # -export-objs := msdosfs_syms.o - obj-$(CONFIG_MSDOS_FS) += msdos.o msdos-objs := namei.o msdosfs_syms.o diff -Nru a/fs/namei.c b/fs/namei.c --- a/fs/namei.c Sun Feb 9 21:13:30 2003 +++ b/fs/namei.c Sun Feb 9 21:13:30 2003 @@ -1659,12 +1659,19 @@ return error; } +/* + * Make sure that the actual truncation of the file will occur outside its + * directory's i_sem. Truncate can take a long time if there is a lot of + * writeout happening, and we don't want to prevent access to the directory + * while waiting on the I/O. + */ asmlinkage long sys_unlink(const char * pathname) { int error = 0; char * name; struct dentry *dentry; struct nameidata nd; + struct inode *inode = NULL; name = getname(pathname); if(IS_ERR(name)) @@ -1683,6 +1690,9 @@ /* Why not before? Because we want correct error value */ if (nd.last.name[nd.last.len]) goto slashes; + inode = dentry->d_inode; + if (inode) + inode = igrab(inode); error = vfs_unlink(nd.dentry->d_inode, dentry); exit2: dput(dentry); @@ -1693,6 +1703,8 @@ exit: putname(name); + if (inode) + iput(inode); /* truncate the inode here */ return error; slashes: diff -Nru a/fs/namespace.c b/fs/namespace.c --- a/fs/namespace.c Sun Feb 9 21:13:33 2003 +++ b/fs/namespace.c Sun Feb 9 21:13:33 2003 @@ -287,7 +287,7 @@ static int do_umount(struct vfsmount *mnt, int flags) { struct super_block * sb = mnt->mnt_sb; - int retval = 0; + int retval; retval = security_sb_umount(mnt, flags); if (retval) diff -Nru a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c --- a/fs/ncpfs/sock.c Sun Feb 9 21:13:31 2003 +++ b/fs/ncpfs/sock.c Sun Feb 9 21:13:31 2003 @@ -745,7 +745,7 @@ sigset_t old_set; unsigned long mask, flags; - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); old_set = current->blocked; if (current->flags & PF_EXITING) mask = 0; @@ -764,7 +764,7 @@ } siginitsetinv(¤t->blocked, mask); recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); fs = get_fs(); set_fs(get_ds()); @@ -773,10 +773,10 @@ set_fs(fs); - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); current->blocked = old_set; recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); } DDPRINTK("do_ncp_rpc_call returned %d\n", result); diff -Nru a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c --- a/fs/nfs/mount_clnt.c Sun Feb 9 21:13:28 2003 +++ b/fs/nfs/mount_clnt.c Sun Feb 9 21:13:28 2003 @@ -93,12 +93,6 @@ * XDR encode/decode functions for MOUNT */ static int -xdr_error(struct rpc_rqst *req, u32 *p, void *dummy) -{ - return -EIO; -} - -static int xdr_encode_dirpath(struct rpc_rqst *req, u32 *p, const char *path) { p = xdr_encode_string(p, path); diff -Nru a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c --- a/fs/nfs/nfs4proc.c Sun Feb 9 21:13:34 2003 +++ b/fs/nfs/nfs4proc.c Sun Feb 9 21:13:34 2003 @@ -743,8 +743,8 @@ goto out; /* - * Now we do a seperate LOOKUP for each component of the mount path. - * The LOOKUPs are done seperately so that we can conveniently + * Now we do a separate LOOKUP for each component of the mount path. + * The LOOKUPs are done separately so that we can conveniently * catch an ERR_WRONGSEC if it occurs along the way... */ p = server->mnt_path; diff -Nru a/fs/nfs/read.c b/fs/nfs/read.c --- a/fs/nfs/read.c Sun Feb 9 21:13:28 2003 +++ b/fs/nfs/read.c Sun Feb 9 21:13:28 2003 @@ -390,11 +390,6 @@ is_sync ? readpage_sync_filler : readpage_async_filler, &desc); - while (!list_empty(pages)) { - struct page *page = list_entry(pages->prev, struct page, list); - list_del(&page->list); - page_cache_release(page); - } if (!list_empty(&head)) { int err = nfs_pagein_list(&head, server->rpages); if (!ret) diff -Nru a/fs/nfs/write.c b/fs/nfs/write.c --- a/fs/nfs/write.c Sun Feb 9 21:13:34 2003 +++ b/fs/nfs/write.c Sun Feb 9 21:13:34 2003 @@ -829,7 +829,6 @@ struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; struct nfs_writeargs *argp = &data->args; struct nfs_writeres *resp = &data->res; - struct inode *inode = data->inode; struct nfs_page *req; struct page *page; @@ -863,7 +862,7 @@ if (time_before(complain, jiffies)) { dprintk("NFS: faulty NFS server %s:" " (committed = %d) != (stable = %d)\n", - NFS_SERVER(inode)->hostname, + NFS_SERVER(data->inode)->hostname, data->verf.committed, argp->stable); complain = jiffies + 300 * HZ; } diff -Nru a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c --- a/fs/nfsd/nfssvc.c Sun Feb 9 21:13:28 2003 +++ b/fs/nfsd/nfssvc.c Sun Feb 9 21:13:28 2003 @@ -168,6 +168,7 @@ struct svc_serv *serv = rqstp->rq_server; int err; struct nfsd_list me; + sigset_t shutdown_mask, allowed_mask; /* Lock module and set up kernel thread */ MOD_INC_USE_COUNT; @@ -176,6 +177,9 @@ sprintf(current->comm, "nfsd"); current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; + siginitsetinv(&shutdown_mask, SHUTDOWN_SIGS); + siginitsetinv(&allowed_mask, ALLOWED_SIGS); + nfsdstats.th_cnt++; lockd_up(); /* start lockd */ @@ -189,10 +193,7 @@ */ for (;;) { /* Block all but the shutdown signals */ - spin_lock_irq(¤t->sig->siglock); - siginitsetinv(¤t->blocked, SHUTDOWN_SIGS); - recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + sigprocmask(SIG_SETMASK, &shutdown_mask, NULL); /* * Find a socket with data available and call its @@ -210,10 +211,7 @@ exp_readlock(); /* Process request with signals blocked. */ - spin_lock_irq(¤t->sig->siglock); - siginitsetinv(¤t->blocked, ALLOWED_SIGS); - recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + sigprocmask(SIG_SETMASK, &allowed_mask, NULL); svc_process(serv, rqstp); diff -Nru a/fs/nls/Makefile b/fs/nls/Makefile --- a/fs/nls/Makefile Sun Feb 9 21:13:29 2003 +++ b/fs/nls/Makefile Sun Feb 9 21:13:29 2003 @@ -2,8 +2,6 @@ # Makefile for native language support # -export-objs := nls_base.o - obj-$(CONFIG_NLS) += nls_base.o obj-$(CONFIG_NLS_CODEPAGE_437) += nls_cp437.o diff -Nru a/fs/partitions/Makefile b/fs/partitions/Makefile --- a/fs/partitions/Makefile Sun Feb 9 21:13:31 2003 +++ b/fs/partitions/Makefile Sun Feb 9 21:13:31 2003 @@ -2,8 +2,6 @@ # Makefile for the linux kernel. # -export-objs := msdos.o - obj-y := check.o obj-$(CONFIG_ACORN_PARTITION) += acorn.o diff -Nru a/fs/partitions/ldm.c b/fs/partitions/ldm.c --- a/fs/partitions/ldm.c Sun Feb 9 21:13:31 2003 +++ b/fs/partitions/ldm.c Sun Feb 9 21:13:31 2003 @@ -510,7 +510,7 @@ /* Are there uncommitted transactions? */ if (BE16(data + 0x10) != 0x01) { - ldm_crit ("Database is not in a consistant state. Aborting."); + ldm_crit ("Database is not in a consistent state. Aborting."); goto out; } diff -Nru a/fs/partitions/sun.c b/fs/partitions/sun.c --- a/fs/partitions/sun.c Sun Feb 9 21:13:36 2003 +++ b/fs/partitions/sun.c Sun Feb 9 21:13:36 2003 @@ -80,8 +80,8 @@ put_partition(state, slot, st_sector, num_sectors); if (label->infos[i].id == LINUX_RAID_PARTITION) state->parts[slot].flags = 1; - slot++; } + slot++; } printk("\n"); put_dev_sector(sect); diff -Nru a/fs/proc/Makefile b/fs/proc/Makefile --- a/fs/proc/Makefile Sun Feb 9 21:13:28 2003 +++ b/fs/proc/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux proc filesystem routines. # -export-objs := root.o - obj-$(CONFIG_PROC_FS) += proc.o proc-objs := inode.o root.o base.o generic.o array.o \ diff -Nru a/fs/proc/array.c b/fs/proc/array.c --- a/fs/proc/array.c Sun Feb 9 21:13:33 2003 +++ b/fs/proc/array.c Sun Feb 9 21:13:33 2003 @@ -126,8 +126,8 @@ "R (running)", /* 0 */ "S (sleeping)", /* 1 */ "D (disk sleep)", /* 2 */ - "T (stopped)", /* 8 */ - "Z (zombie)", /* 4 */ + "T (stopped)", /* 4 */ + "Z (zombie)", /* 8 */ "X (dead)" /* 16 */ }; @@ -190,16 +190,16 @@ sigemptyset(catch); read_lock(&tasklist_lock); - if (p->sig) { - spin_lock_irq(&p->sig->siglock); - k = p->sig->action; + if (p->sighand) { + spin_lock_irq(&p->sighand->siglock); + k = p->sighand->action; for (i = 1; i <= _NSIG; ++i, ++k) { if (k->sa.sa_handler == SIG_IGN) sigaddset(ign, i); else if (k->sa.sa_handler != SIG_DFL) sigaddset(catch, i); } - spin_unlock_irq(&p->sig->siglock); + spin_unlock_irq(&p->sighand->siglock); } read_unlock(&tasklist_lock); } @@ -301,7 +301,7 @@ ppid = task->pid ? task->real_parent->pid : 0; read_unlock(&tasklist_lock); res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ -%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \ +%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %llu %lu %ld %lu %lu %lu %lu %lu \ %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu\n", task->pid, task->comm, @@ -324,7 +324,7 @@ nice, 0UL /* removed */, jiffies_to_clock_t(task->it_real_value), - jiffies_to_clock_t(task->start_time), + (unsigned long long) jiffies_64_to_clock_t(task->start_time), vsize, mm ? mm->rss : 0, /* you might want to shift this left 3 */ task->rlim[RLIMIT_RSS].rlim_cur, diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c --- a/fs/proc/proc_misc.c Sun Feb 9 21:13:29 2003 +++ b/fs/proc/proc_misc.c Sun Feb 9 21:13:29 2003 @@ -41,11 +41,13 @@ #include #include #include +#include #include #include #include #include #include +#include #define LOAD_INT(x) ((x) >> FSHIFT) #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) @@ -98,34 +100,35 @@ static int uptime_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { - unsigned long uptime; - unsigned long idle; + u64 uptime; + unsigned long uptime_remainder; int len; - uptime = jiffies; - idle = init_task.utime + init_task.stime; + uptime = get_jiffies_64(); + uptime_remainder = (unsigned long) do_div(uptime, HZ); - /* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but - that would overflow about every five days at HZ == 100. - Therefore the identity a = (a / b) * b + a % b is used so that it is - calculated as (((t / HZ) * 100) + ((t % HZ) * 100) / HZ) % 100. - The part in front of the '+' always evaluates as 0 (mod 100). All divisions - in the above formulas are truncating. For HZ being a power of 10, the - calculations simplify to the version in the #else part (if the printf - format is adapted to the same number of digits as zeroes in HZ. - */ #if HZ!=100 - len = sprintf(page,"%lu.%02lu %lu.%02lu\n", - uptime / HZ, - (((uptime % HZ) * 100) / HZ) % 100, - idle / HZ, - (((idle % HZ) * 100) / HZ) % 100); + { + u64 idle = init_task.utime + init_task.stime; + unsigned long idle_remainder; + + idle_remainder = (unsigned long) do_div(idle, HZ); + len = sprintf(page,"%lu.%02lu %lu.%02lu\n", + (unsigned long) uptime, + (uptime_remainder * 100) / HZ, + (unsigned long) idle, + (idle_remainder * 100) / HZ); + } #else - len = sprintf(page,"%lu.%02lu %lu.%02lu\n", - uptime / HZ, - uptime % HZ, - idle / HZ, - idle % HZ); + { + unsigned long idle = init_task.utime + init_task.stime; + + len = sprintf(page,"%lu.%02lu %lu.%02lu\n", + (unsigned long) uptime, + uptime_remainder, + idle / HZ, + idle % HZ); + } #endif return proc_calc_metrics(page, start, off, count, eof, len); } @@ -317,7 +320,7 @@ { int i, len; extern unsigned long total_forks; - unsigned long jif = jiffies; + u64 jif = get_jiffies_64(); unsigned int sum = 0, user = 0, nice = 0, system = 0, idle = 0, iowait = 0; for (i = 0 ; i < NR_CPUS; i++) { @@ -358,6 +361,7 @@ len += sprintf(page + len, " %u", kstat_irqs(i)); #endif + do_div(jif, HZ); len += sprintf(page + len, "\nctxt %lu\n" "btime %lu\n" @@ -365,7 +369,7 @@ "procs_running %lu\n" "procs_blocked %lu\n", nr_context_switches(), - xtime.tv_sec - jif / HZ, + xtime.tv_sec - (unsigned long) jif, total_forks, nr_running(), nr_iowait()); diff -Nru a/fs/quota.c b/fs/quota.c --- a/fs/quota.c Sun Feb 9 21:13:36 2003 +++ b/fs/quota.c Sun Feb 9 21:13:36 2003 @@ -123,13 +123,13 @@ case Q_GETFMT: { __u32 fmt; - down_read(&sb_dqopt(sb)->dqoff_sem); + down_read(&sb_dqopt(sb)->dqptr_sem); if (!sb_has_quota_enabled(sb, type)) { - up_read(&sb_dqopt(sb)->dqoff_sem); + up_read(&sb_dqopt(sb)->dqptr_sem); return -ESRCH; } fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id; - up_read(&sb_dqopt(sb)->dqoff_sem); + up_read(&sb_dqopt(sb)->dqptr_sem); if (copy_to_user(addr, &fmt, sizeof(fmt))) return -EFAULT; return 0; diff -Nru a/fs/quota_v2.c b/fs/quota_v2.c --- a/fs/quota_v2.c Sun Feb 9 21:13:35 2003 +++ b/fs/quota_v2.c Sun Feb 9 21:13:35 2003 @@ -306,6 +306,7 @@ blk = get_free_dqblk(filp, info); if ((int)blk < 0) { *err = blk; + freedqbuf(buf); return 0; } memset(buf, 0, V2_DQBLKSIZE); diff -Nru a/fs/read_write.c b/fs/read_write.c --- a/fs/read_write.c Sun Feb 9 21:13:33 2003 +++ b/fs/read_write.c Sun Feb 9 21:13:33 2003 @@ -531,6 +531,10 @@ if (retval) goto fput_in; + retval = security_file_permission (in_file, MAY_READ); + if (retval) + goto fput_in; + /* * Get output file, and verify that it is ok.. */ @@ -545,6 +549,10 @@ goto fput_out; out_inode = out_file->f_dentry->d_inode; retval = locks_verify_area(FLOCK_VERIFY_WRITE, out_inode, out_file, out_file->f_pos, count); + if (retval) + goto fput_out; + + retval = security_file_permission (out_file, MAY_WRITE); if (retval) goto fput_out; diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c --- a/fs/reiserfs/inode.c Sun Feb 9 21:13:30 2003 +++ b/fs/reiserfs/inode.c Sun Feb 9 21:13:30 2003 @@ -11,6 +11,8 @@ #include #include #include +#include +#include /* args for the create parameter of reiserfs_get_block */ #define GET_BLOCK_NO_CREATE 0 /* don't create new blocks or convert tails */ @@ -262,7 +264,10 @@ blocknr = get_block_num(ind_item, path.pos_in_item) ; ret = 0 ; if (blocknr) { - map_bh(bh_result, inode->i_sb, blocknr); + map_bh(bh_result, inode->i_sb, blocknr); + if (path.pos_in_item == ((ih_item_len(ih) / UNFM_P_SIZE) - 1)) { + set_buffer_boundary(bh_result); + } } else // We do not return -ENOENT if there is a hole but page is uptodate, because it means // That there is some MMAPED data associated with it that is yet to be written to disk. @@ -286,7 +291,7 @@ return -ENOENT; } - /* if we've got a direct item, and the buffer was uptodate, + /* if we've got a direct item, and the buffer or page was uptodate, ** we don't want to pull data off disk again. skip to the ** end, where we map the buffer and return */ @@ -367,7 +372,9 @@ finished: pathrelse (&path); - /* I _really_ doubt that you want it. Chris? */ + /* this buffer has valid data, but isn't valid for io. mapping it to + * block #0 tells the rest of reiserfs it just has a tail in it + */ map_bh(bh_result, inode->i_sb, 0); set_buffer_uptodate (bh_result); return 0; @@ -842,6 +849,12 @@ return retval; } +static int +reiserfs_readpages(struct file *file, struct address_space *mapping, + struct list_head *pages, unsigned nr_pages) +{ + return mpage_readpages(mapping, pages, nr_pages, reiserfs_get_block); +} // // BAD: new directories have stat data of new type and all other items @@ -1809,13 +1822,19 @@ int use_get_block = 0 ; int bytes_copied = 0 ; int copy_size ; + int trans_running = 0; + + /* catch places below that try to log something without starting a trans */ + th.t_trans_id = 0; + + if (!buffer_uptodate(bh_result)) { + buffer_error(); + return -EIO; + } kmap(bh_result->b_page) ; start_over: reiserfs_write_lock(inode->i_sb); - journal_begin(&th, inode->i_sb, jbegin_count) ; - reiserfs_update_inode_transaction(inode) ; - make_cpu_key(&key, inode, byte_offset, TYPE_ANY, 3) ; research: @@ -1841,7 +1860,6 @@ goto out ; } set_block_dev_mapped(bh_result, get_block_num(item,pos_in_item),inode); - set_buffer_uptodate(bh_result); } else if (is_direct_le_ih(ih)) { char *p ; p = page_address(bh_result->b_page) ; @@ -1850,7 +1868,20 @@ fs_gen = get_generation(inode->i_sb) ; copy_item_head(&tmp_ih, ih) ; + + if (!trans_running) { + /* vs-3050 is gone, no need to drop the path */ + journal_begin(&th, inode->i_sb, jbegin_count) ; + reiserfs_update_inode_transaction(inode) ; + trans_running = 1; + if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) { + reiserfs_restore_prepared_buffer(inode->i_sb, bh) ; + goto research; + } + } + reiserfs_prepare_for_journal(inode->i_sb, bh, 1) ; + if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) { reiserfs_restore_prepared_buffer(inode->i_sb, bh) ; goto research; @@ -1861,7 +1892,6 @@ journal_mark_dirty(&th, inode->i_sb, bh) ; bytes_copied += copy_size ; set_block_dev_mapped(bh_result, 0, inode); - set_buffer_uptodate(bh_result); /* are there still bytes left? */ if (bytes_copied < bh_result->b_size && @@ -1878,7 +1908,10 @@ out: pathrelse(&path) ; - journal_end(&th, inode->i_sb, jbegin_count) ; + if (trans_running) { + journal_end(&th, inode->i_sb, jbegin_count) ; + trans_running = 0; + } reiserfs_write_unlock(inode->i_sb); /* this is where we fill in holes in the file. */ @@ -1894,49 +1927,77 @@ } } kunmap(bh_result->b_page) ; + + if (!retval && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) { + /* we've copied data from the page into the direct item, so the + * buffer in the page is now clean, mark it to reflect that. + */ + lock_buffer(bh_result); + clear_buffer_dirty(bh_result); + unlock_buffer(bh_result); + } return retval ; } -/* helper func to get a buffer head ready for writepage to send to -** ll_rw_block -*/ -static inline void submit_bh_for_writepage(struct buffer_head **bhp, int nr) { - struct buffer_head *bh ; - int i; - for(i = 0 ; i < nr ; i++) { - bh = bhp[i] ; - lock_buffer(bh) ; - mark_buffer_async_write(bh) ; - /* submit_bh doesn't care if the buffer is dirty, but nobody - ** later on in the call chain will be cleaning it. So, we - ** clean the buffer here, it still gets written either way. - */ - clear_buffer_dirty(bh) ; - set_buffer_uptodate(bh) ; - submit_bh(WRITE, bh) ; +/* + * does the right thing for deciding when to lock a buffer and + * mark it for io during a writepage. make sure the buffer is + * dirty before sending it here though. + */ +static void lock_buffer_for_writepage(struct page *page, + struct writeback_control *wbc, + struct buffer_head *bh) +{ + if (wbc->sync_mode != WB_SYNC_NONE) { + lock_buffer(bh); + } else { + if (test_set_buffer_locked(bh)) { + __set_page_dirty_nobuffers(page); + return; + } + } + if (test_clear_buffer_dirty(bh)) { + if (!buffer_uptodate(bh)) + buffer_error(); + mark_buffer_async_write(bh); + } else { + unlock_buffer(bh); } } +/* + * mason@suse.com: updated in 2.5.54 to follow the same general io + * start/recovery path as __block_write_full_page, along with special + * code to handle reiserfs tails. + */ static int reiserfs_write_full_page(struct page *page, struct writeback_control *wbc) { struct inode *inode = page->mapping->host ; unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT ; - unsigned last_offset = PAGE_CACHE_SIZE; int error = 0; unsigned long block ; - unsigned cur_offset = 0 ; - struct buffer_head *head, *bh ; + struct buffer_head *head, *bh; int partial = 0 ; - struct buffer_head *arr[PAGE_CACHE_SIZE/512] ; - int nr = 0 ; + int nr = 0; - if (!page_has_buffers(page)) - block_prepare_write(page, 0, 0, NULL) ; + /* The page dirty bit is cleared before writepage is called, which + * means we have to tell create_empty_buffers to make dirty buffers + * The page really should be up to date at this point, so tossing + * in the BH_Uptodate is just a sanity check. + */ + if (!page_has_buffers(page)) { + if (!PageUptodate(page)) + buffer_error(); + create_empty_buffers(page, inode->i_sb->s_blocksize, + (1 << BH_Dirty) | (1 << BH_Uptodate)); + } + head = page_buffers(page) ; /* last page in the file, zero out any contents past the ** last byte in the file */ if (page->index >= end_index) { char *kaddr; + unsigned last_offset; last_offset = inode->i_size & (PAGE_CACHE_SIZE - 1) ; /* no file contents in this page */ @@ -1949,66 +2010,107 @@ flush_dcache_page(page) ; kunmap_atomic(kaddr, KM_USER0) ; } - head = page_buffers(page) ; bh = head ; block = page->index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits) ; do { - /* if this offset in the page is outside the file */ - if (cur_offset >= last_offset) { - if (!buffer_uptodate(bh)) - partial = 1 ; - } else { - /* fast path, buffer mapped to an unformatted node */ + get_bh(bh); + if (buffer_dirty(bh)) { if (buffer_mapped(bh) && bh->b_blocknr != 0) { - arr[nr++] = bh ; + /* buffer mapped to an unformatted node */ + lock_buffer_for_writepage(page, wbc, bh); } else { - /* buffer not mapped yet, or points to a direct item. - ** search and dirty or log - */ + /* not mapped yet, or it points to a direct item, search + * the btree for the mapping info, and log any direct + * items found + */ if ((error = map_block_for_writepage(inode, bh, block))) { goto fail ; } - /* map_block_for_writepage either found an unformatted node - ** and mapped it for us, or it found a direct item - ** and logged the changes. - */ - if (buffer_mapped(bh) && bh->b_blocknr != 0) { - arr[nr++] = bh ; - } + if (buffer_mapped(bh) && bh->b_blocknr != 0) { + lock_buffer_for_writepage(page, wbc, bh); + } } } - bh = bh->b_this_page ; - cur_offset += bh->b_size ; - block++ ; + bh = bh->b_this_page; + block++; } while(bh != head) ; - if (!partial) - SetPageUptodate(page) ; BUG_ON(PageWriteback(page)); SetPageWriteback(page); unlock_page(page); - /* if this page only had a direct item, it is very possible for - ** nr == 0 without there being any kind of error. - */ - if (nr) { - submit_bh_for_writepage(arr, nr) ; - } else { - end_page_writeback(page) ; + /* + * since any buffer might be the only dirty buffer on the page, + * the first submit_bh can bring the page out of writeback. + * be careful with the buffers. + */ + do { + struct buffer_head *next = bh->b_this_page; + if (buffer_async_write(bh)) { + submit_bh(WRITE, bh); + nr++; + } + put_bh(bh); + bh = next; + } while(bh != head); + + error = 0; +done: + if (nr == 0) { + /* + * if this page only had a direct item, it is very possible for + * no io to be required without there being an error. Or, + * someone else could have locked them and sent them down the + * pipe without locking the page + */ + do { + if (!buffer_uptodate(bh)) { + partial = 1; + break; + } + } while(bh != head); + if (!partial) + SetPageUptodate(page); + end_page_writeback(page); } - - return 0 ; + return error; fail: - if (nr) { - SetPageWriteback(page); - unlock_page(page); - submit_bh_for_writepage(arr, nr) ; - } else { - unlock_page(page) ; - } - ClearPageUptodate(page) ; - return error ; + /* catches various errors, we need to make sure any valid dirty blocks + * get to the media. The page is currently locked and not marked for + * writeback + */ + ClearPageUptodate(page); + bh = head; + do { + get_bh(bh); + if (buffer_mapped(bh) && buffer_dirty(bh) && bh->b_blocknr) { + lock_buffer(bh); + mark_buffer_async_write(bh); + } else { + /* + * clear any dirty bits that might have come from getting + * attached to a dirty page + */ + clear_buffer_dirty(bh); + } + bh = bh->b_this_page; + } while(bh != head); + SetPageError(page); + BUG_ON(PageWriteback(page)); + SetPageWriteback(page); + unlock_page(page); + do { + struct buffer_head *next = bh->b_this_page; + if (buffer_async_write(bh)) { + clear_buffer_dirty(bh); + submit_bh(WRITE, bh); + nr++; + } + put_bh(bh); + bh = next; + } while(bh != head); + goto done; } @@ -2115,6 +2217,7 @@ struct address_space_operations reiserfs_address_space_operations = { .writepage = reiserfs_writepage, .readpage = reiserfs_readpage, + .readpages = reiserfs_readpages, .releasepage = reiserfs_releasepage, .sync_page = block_sync_page, .prepare_write = reiserfs_prepare_write, diff -Nru a/fs/seq_file.c b/fs/seq_file.c --- a/fs/seq_file.c Sun Feb 9 21:13:34 2003 +++ b/fs/seq_file.c Sun Feb 9 21:13:34 2003 @@ -10,6 +10,7 @@ #include #include +#include /** * seq_open - initialize sequential file diff -Nru a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c --- a/fs/smbfs/smbiod.c Sun Feb 9 21:13:33 2003 +++ b/fs/smbfs/smbiod.c Sun Feb 9 21:13:33 2003 @@ -285,10 +285,10 @@ MOD_INC_USE_COUNT; daemonize(); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked, sigmask(SIGKILL)); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); strcpy(current->comm, "smbiod"); diff -Nru a/fs/stat.c b/fs/stat.c --- a/fs/stat.c Sun Feb 9 21:13:29 2003 +++ b/fs/stat.c Sun Feb 9 21:13:29 2003 @@ -316,3 +316,45 @@ } #endif /* LFS-64 */ + +void inode_add_bytes(struct inode *inode, loff_t bytes) +{ + spin_lock(&inode->i_lock); + inode->i_blocks += bytes >> 9; + bytes &= 511; + inode->i_bytes += bytes; + if (inode->i_bytes >= 512) { + inode->i_blocks++; + inode->i_bytes -= 512; + } + spin_unlock(&inode->i_lock); +} + +void inode_sub_bytes(struct inode *inode, loff_t bytes) +{ + spin_lock(&inode->i_lock); + inode->i_blocks -= bytes >> 9; + bytes &= 511; + if (inode->i_bytes < bytes) { + inode->i_blocks--; + inode->i_bytes += 512; + } + inode->i_bytes -= bytes; + spin_unlock(&inode->i_lock); +} + +loff_t inode_get_bytes(struct inode *inode) +{ + loff_t ret; + + spin_lock(&inode->i_lock); + ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; + spin_unlock(&inode->i_lock); + return ret; +} + +void inode_set_bytes(struct inode *inode, loff_t bytes) +{ + inode->i_blocks = bytes >> 9; + inode->i_bytes = bytes & 511; +} diff -Nru a/fs/super.c b/fs/super.c --- a/fs/super.c Sun Feb 9 21:13:31 2003 +++ b/fs/super.c Sun Feb 9 21:13:31 2003 @@ -71,7 +71,8 @@ atomic_set(&s->s_active, 1); sema_init(&s->s_vfs_rename_sem,1); sema_init(&s->s_dquot.dqio_sem, 1); - init_rwsem(&s->s_dquot.dqoff_sem); + sema_init(&s->s_dquot.dqonoff_sem, 1); + init_rwsem(&s->s_dquot.dqptr_sem); s->s_maxbytes = MAX_NON_LFS; s->dq_op = sb_dquot_ops; s->s_qcop = sb_quotactl_ops; @@ -310,7 +311,7 @@ spin_lock(&sb_lock); for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.next)) { - if (!sb->s_op->sync_fs); + if (!sb->s_op->sync_fs) continue; if (sb->s_flags & MS_RDONLY) continue; diff -Nru a/fs/sysfs/Makefile b/fs/sysfs/Makefile --- a/fs/sysfs/Makefile Sun Feb 9 21:13:28 2003 +++ b/fs/sysfs/Makefile Sun Feb 9 21:13:28 2003 @@ -2,6 +2,4 @@ # Makefile for the sysfs virtual filesystem # -export-objs := inode.o - obj-y := inode.o diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c --- a/fs/sysfs/inode.c Sun Feb 9 21:13:35 2003 +++ b/fs/sysfs/inode.c Sun Feb 9 21:13:35 2003 @@ -37,6 +37,7 @@ #include #include #include +#include #include /* Random magic number */ @@ -716,6 +717,46 @@ up(&dir->d_inode->i_sem); } +/** + * sysfs_update_file - update the modified timestamp on an object attribute. + * @kobj: object we're acting for. + * @attr: attribute descriptor. + * + * Also call dnotify for the dentry, which lots of userspace programs + * use. + */ +int sysfs_update_file(struct kobject * kobj, struct attribute * attr) +{ + struct dentry * dir = kobj->dentry; + struct dentry * victim; + int res = -ENOENT; + + down(&dir->d_inode->i_sem); + victim = get_dentry(dir, attr->name); + if (!IS_ERR(victim)) { + /* make sure dentry is really there */ + if (victim->d_inode && + (victim->d_parent->d_inode == dir->d_inode)) { + victim->d_inode->i_mtime = CURRENT_TIME; + dnotify_parent(victim, DN_MODIFY); + + /** + * Drop reference from initial get_dentry(). + */ + dput(victim); + res = 0; + } + + /** + * Drop the reference acquired from get_dentry() above. + */ + dput(victim); + } + up(&dir->d_inode->i_sem); + + return res; +} + /** * sysfs_remove_file - remove an object attribute. @@ -814,6 +855,7 @@ } EXPORT_SYMBOL(sysfs_create_file); +EXPORT_SYMBOL(sysfs_update_file); EXPORT_SYMBOL(sysfs_remove_file); EXPORT_SYMBOL(sysfs_create_link); EXPORT_SYMBOL(sysfs_remove_link); diff -Nru a/fs/vfat/Makefile b/fs/vfat/Makefile --- a/fs/vfat/Makefile Sun Feb 9 21:13:35 2003 +++ b/fs/vfat/Makefile Sun Feb 9 21:13:35 2003 @@ -2,8 +2,6 @@ # Makefile for the linux vfat-filesystem routines. # -export-objs := vfatfs_syms.o - obj-$(CONFIG_VFAT_FS) += vfat.o vfat-objs := namei.o vfatfs_syms.o diff -Nru a/fs/xfs/Makefile b/fs/xfs/Makefile --- a/fs/xfs/Makefile Sun Feb 9 21:13:34 2003 +++ b/fs/xfs/Makefile Sun Feb 9 21:13:34 2003 @@ -45,9 +45,6 @@ EXTRA_CFLAGS += -DPAGEBUF_TRACE endif -export-objs := pagebuf/page_buf.o support/ktrace.o \ - linux/xfs_globals.o - obj-$(CONFIG_XFS_FS) += xfs.o diff -Nru a/fs/xfs/linux/xfs_aops.c b/fs/xfs/linux/xfs_aops.c --- a/fs/xfs/linux/xfs_aops.c Sun Feb 9 21:13:36 2003 +++ b/fs/xfs/linux/xfs_aops.c Sun Feb 9 21:13:36 2003 @@ -50,7 +50,7 @@ if (((flags & (PBF_DIRECT|PBF_SYNC)) == PBF_DIRECT) && (offset >= inode->i_size)) - count = max(count, XFS_WRITE_IO_LOG); + count = max_t(ssize_t, count, XFS_WRITE_IO_LOG); retry: VOP_BMAP(vp, offset, count, flags, pbmapp, &nmaps, error); if (flags & PBF_WRITE) { diff -Nru a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c --- a/fs/xfs/pagebuf/page_buf.c Sun Feb 9 21:13:28 2003 +++ b/fs/xfs/pagebuf/page_buf.c Sun Feb 9 21:13:28 2003 @@ -1299,7 +1299,6 @@ int status = 0; int i, map_i, total_nr_pages, nr_pages; struct bio *bio; - struct bio_vec *bvec; int offset = pb->pb_offset; int size = pb->pb_count_desired; sector_t sector = pb->pb_bn; @@ -1335,13 +1334,8 @@ bio->bi_sector = sector - (offset >> BBSHIFT); bio->bi_end_io = bio_end_io_pagebuf; bio->bi_private = pb; - bio->bi_vcnt++; - bio->bi_size = PAGE_CACHE_SIZE; - bvec = bio->bi_io_vec; - bvec->bv_page = pb->pb_pages[0]; - bvec->bv_len = PAGE_CACHE_SIZE; - bvec->bv_offset = 0; + bio_add_page(bio, pb->pb_pages[0], PAGE_CACHE_SIZE, 0); atomic_inc(&pb->pb_io_remaining); submit_bio(READ, bio); @@ -1389,9 +1383,7 @@ bio->bi_end_io = bio_end_io_pagebuf; bio->bi_private = pb; - bvec = bio->bi_io_vec; - - for (; size && nr_pages; nr_pages--, bvec++, map_i++) { + for (; size && nr_pages; nr_pages--, map_i++) { int nbytes = PAGE_CACHE_SIZE - offset; if (nbytes > size) @@ -1589,10 +1581,10 @@ daemonize(); /* Avoid signals */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sigfillset(¤t->blocked); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); strcpy(current->comm, "pagebufd"); current->flags |= PF_MEMALLOC; diff -Nru a/fs/xfs/support/move.c b/fs/xfs/support/move.c --- a/fs/xfs/support/move.c Sun Feb 9 21:13:32 2003 +++ b/fs/xfs/support/move.c Sun Feb 9 21:13:32 2003 @@ -30,6 +30,7 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ +#include #include #include diff -Nru a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c --- a/fs/xfs/xfs_bmap.c Sun Feb 9 21:13:36 2003 +++ b/fs/xfs/xfs_bmap.c Sun Feb 9 21:13:36 2003 @@ -5522,7 +5522,7 @@ int prealloced; /* this is a file with * preallocated data space */ int sh_unwritten; /* true, if unwritten */ - /* extents listed seperately */ + /* extents listed separately */ int bmapi_flags; /* flags for xfs_bmapi */ __int32_t oflags; /* getbmapx bmv_oflags field */ diff -Nru a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c --- a/fs/xfs/xfs_buf_item.c Sun Feb 9 21:13:28 2003 +++ b/fs/xfs/xfs_buf_item.c Sun Feb 9 21:13:28 2003 @@ -379,7 +379,8 @@ */ void xfs_buf_item_unpin( - xfs_buf_log_item_t *bip) + xfs_buf_log_item_t *bip, + int stale) { xfs_mount_t *mp; xfs_buf_t *bp; @@ -396,7 +397,8 @@ freed = atomic_dec_and_test(&bip->bli_refcount); mp = bip->bli_item.li_mountp; xfs_bunpin(bp); - if (freed && (bip->bli_flags & XFS_BLI_STALE)) { + if (freed && stale) { + ASSERT(bip->bli_flags & XFS_BLI_STALE); ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); ASSERT(!(XFS_BUF_ISDELAYWRITE(bp))); ASSERT(XFS_BUF_ISSTALE(bp)); @@ -418,7 +420,6 @@ ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL); xfs_buf_relse(bp); } - } /* @@ -435,6 +436,7 @@ { xfs_buf_t *bp; xfs_log_item_desc_t *lidp; + int stale = 0; bp = bip->bli_buf; /* @@ -454,6 +456,7 @@ * will be able to bump up the refcount. */ lidp = xfs_trans_find_item(tp, (xfs_log_item_t *) bip); + stale = lidp->lid_flags & XFS_LID_BUF_STALE; xfs_trans_free_item(tp, lidp); /* * Since the transaction no longer refers to the buffer, @@ -462,7 +465,7 @@ XFS_BUF_SET_FSPRIVATE2(bp, NULL); } - xfs_buf_item_unpin(bip); + xfs_buf_item_unpin(bip, stale); return; } @@ -686,7 +689,7 @@ .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_buf_item_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_buf_item_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_buf_item_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_buf_item_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *)) xfs_buf_item_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_buf_item_trylock, diff -Nru a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c --- a/fs/xfs/xfs_dquot_item.c Sun Feb 9 21:13:29 2003 +++ b/fs/xfs/xfs_dquot_item.c Sun Feb 9 21:13:29 2003 @@ -93,9 +93,11 @@ * anyone in xfs_dqwait_unpin() if the count goes to 0. The * dquot must have been previously pinned with a call to xfs_dqpin(). */ +/* ARGSUSED */ STATIC void xfs_qm_dquot_logitem_unpin( - xfs_dq_logitem_t *logitem) + xfs_dq_logitem_t *logitem, + int stale) { unsigned long s; xfs_dquot_t *dqp; @@ -116,7 +118,7 @@ xfs_dq_logitem_t *logitem, xfs_trans_t *tp) { - xfs_qm_dquot_logitem_unpin(logitem); + xfs_qm_dquot_logitem_unpin(logitem, 0); } /* @@ -396,7 +398,8 @@ .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_qm_dquot_logitem_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int)) + xfs_qm_dquot_logitem_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*)) xfs_qm_dquot_logitem_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*)) @@ -492,7 +495,7 @@ */ /*ARGSUSED*/ STATIC void -xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf) +xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf, int stale) { return; } @@ -613,7 +616,8 @@ .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_qm_qoff_logitem_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unpin, + .iop_unpin = (void(*)(xfs_log_item_t* ,int)) + xfs_qm_qoff_logitem_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*)) xfs_qm_qoff_logitem_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock, @@ -635,7 +639,8 @@ .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_qm_qoff_logitem_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int)) + xfs_qm_qoff_logitem_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*)) xfs_qm_qoff_logitem_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock, diff -Nru a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c --- a/fs/xfs/xfs_extfree_item.c Sun Feb 9 21:13:35 2003 +++ b/fs/xfs/xfs_extfree_item.c Sun Feb 9 21:13:35 2003 @@ -105,7 +105,7 @@ */ /*ARGSUSED*/ STATIC void -xfs_efi_item_unpin(xfs_efi_log_item_t *efip) +xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale) { int nexts; int size; @@ -280,7 +280,7 @@ .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_efi_item_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_efi_item_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_efi_item_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_efi_item_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *)) xfs_efi_item_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_efi_item_trylock, @@ -474,7 +474,7 @@ */ /*ARGSUSED*/ STATIC void -xfs_efd_item_unpin(xfs_efd_log_item_t *efdp) +xfs_efd_item_unpin(xfs_efd_log_item_t *efdp, int stale) { return; } @@ -607,7 +607,7 @@ .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_efd_item_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_efd_item_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_efd_item_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_efd_item_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*)) xfs_efd_item_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_efd_item_trylock, diff -Nru a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c --- a/fs/xfs/xfs_inode_item.c Sun Feb 9 21:13:34 2003 +++ b/fs/xfs/xfs_inode_item.c Sun Feb 9 21:13:34 2003 @@ -534,9 +534,11 @@ * item which was previously pinned with a call to xfs_inode_item_pin(). * Just call xfs_iunpin() on the inode to do this. */ +/* ARGSUSED */ STATIC void xfs_inode_item_unpin( - xfs_inode_log_item_t *iip) + xfs_inode_log_item_t *iip, + int stale) { xfs_iunpin(iip->ili_inode); } @@ -880,7 +882,7 @@ .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) xfs_inode_item_format, .iop_pin = (void(*)(xfs_log_item_t*))xfs_inode_item_pin, - .iop_unpin = (void(*)(xfs_log_item_t*))xfs_inode_item_unpin, + .iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_inode_item_unpin, .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*)) xfs_inode_item_unpin_remove, .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_inode_item_trylock, diff -Nru a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c --- a/fs/xfs/xfs_log.c Sun Feb 9 21:13:37 2003 +++ b/fs/xfs/xfs_log.c Sun Feb 9 21:13:37 2003 @@ -45,7 +45,7 @@ /* Local miscellaneous function prototypes */ STATIC int xlog_bdstrat_cb(struct xfs_buf *); STATIC int xlog_commit_record(xfs_mount_t *mp, xlog_ticket_t *ticket, - xfs_lsn_t *); + xlog_in_core_t **, xfs_lsn_t *); STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp, dev_t log_dev, xfs_daddr_t blk_offset, @@ -55,7 +55,9 @@ STATIC void xlog_unalloc_log(xlog_t *log); STATIC int xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[], int nentries, xfs_log_ticket_t tic, - xfs_lsn_t *start_lsn, uint flags); + xfs_lsn_t *start_lsn, + xlog_in_core_t **commit_iclog, + uint flags); /* local state machine functions */ STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int); @@ -70,10 +72,6 @@ xlog_ticket_t *ticket, int *continued_write, int *logoffsetp); -STATIC int xlog_state_lsn_is_synced(xlog_t *log, - xfs_lsn_t lsn, - xfs_log_callback_t *cb, - int *abortflg); STATIC void xlog_state_put_ticket(xlog_t *log, xlog_ticket_t *tic); STATIC int xlog_state_release_iclog(xlog_t *log, @@ -254,6 +252,7 @@ xfs_lsn_t xfs_log_done(xfs_mount_t *mp, xfs_log_ticket_t xtic, + void **iclog, uint flags) { xlog_t *log = mp->m_log; @@ -271,7 +270,8 @@ * If we get an error, just continue and give back the log ticket. */ (((ticket->t_flags & XLOG_TIC_INITED) == 0) && - (xlog_commit_record(mp, ticket, &lsn)))) { + (xlog_commit_record(mp, ticket, + (xlog_in_core_t **)iclog, &lsn)))) { lsn = (xfs_lsn_t) -1; if (ticket->t_flags & XLOG_TIC_PERM_RESERV) { flags |= XFS_LOG_REL_PERM_RESERV; @@ -354,21 +354,39 @@ * been synced to disk, we add the callback to the callback list of the * in-core log. */ -void +int xfs_log_notify(xfs_mount_t *mp, /* mount of partition */ - xfs_lsn_t lsn, /* lsn looking for */ + void *iclog_hndl, /* iclog to hang callback off */ xfs_log_callback_t *cb) { xlog_t *log = mp->m_log; - int abortflg; + xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl; + int abortflg, spl; #if defined(DEBUG) || defined(XLOG_NOLOG) if (! xlog_debug && xlog_devt == log->l_dev) - return; + return 0; #endif cb->cb_next = 0; - if (xlog_state_lsn_is_synced(log, lsn, cb, &abortflg)) + spl = LOG_LOCK(log); + abortflg = (iclog->ic_state & XLOG_STATE_IOERROR); + if (!abortflg) { + ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) || + (iclog->ic_state == XLOG_STATE_WANT_SYNC)); + cb->cb_next = 0; + *(iclog->ic_callback_tail) = cb; + iclog->ic_callback_tail = &(cb->cb_next); + } + LOG_UNLOCK(log, spl); + if (!abortflg) { + if (xlog_state_release_iclog(log, iclog)) { + xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); + return EIO; + } + } else { cb->cb_func(cb->cb_arg, abortflg); + } + return 0; } /* xfs_log_notify */ @@ -611,7 +629,7 @@ /* remove inited flag */ ((xlog_ticket_t *)tic)->t_flags = 0; error = xlog_write(mp, reg, 1, tic, &lsn, - XLOG_UNMOUNT_TRANS); + NULL, XLOG_UNMOUNT_TRANS); /* * At this point, we're umounting anyway, * so there's no point in transitioning log state @@ -717,7 +735,7 @@ if (XLOG_FORCED_SHUTDOWN(log)) return XFS_ERROR(EIO); - if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, 0))) { + if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) { xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); } return (error); @@ -1259,6 +1277,7 @@ STATIC int xlog_commit_record(xfs_mount_t *mp, xlog_ticket_t *ticket, + xlog_in_core_t **iclog, xfs_lsn_t *commitlsnp) { int error; @@ -1267,8 +1286,9 @@ reg[0].i_addr = 0; reg[0].i_len = 0; + ASSERT_ALWAYS(iclog); if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp, - XLOG_COMMIT_TRANS))) { + iclog, XLOG_COMMIT_TRANS))) { xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); } return (error); @@ -1614,6 +1634,7 @@ int nentries, xfs_log_ticket_t tic, xfs_lsn_t *start_lsn, + xlog_in_core_t **commit_iclog, uint flags) { xlog_t *log = mp->m_log; @@ -1776,7 +1797,10 @@ if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) { xlog_state_want_sync(log, iclog); - if ((error = xlog_state_release_iclog(log, iclog))) + if (commit_iclog) { + ASSERT(flags & XLOG_COMMIT_TRANS); + *commit_iclog = iclog; + } else if ((error = xlog_state_release_iclog(log, iclog))) return (error); if (index == nentries) return 0; /* we are done */ @@ -1788,6 +1812,11 @@ } /* for (index = 0; index < nentries; ) */ ASSERT(len == 0); + if (commit_iclog) { + ASSERT(flags & XLOG_COMMIT_TRANS); + *commit_iclog = iclog; + return 0; + } return (xlog_state_release_iclog(log, iclog)); } /* xlog_write */ @@ -2060,6 +2089,12 @@ if (!(iclog->ic_state & XLOG_STATE_IOERROR)) iclog->ic_state = XLOG_STATE_DIRTY; + /* + * Transition from DIRTY to ACTIVE if applicable. + * NOP if STATE_IOERROR. + */ + xlog_state_clean_log(log); + /* wake up threads waiting in xfs_log_force() */ sv_broadcast(&iclog->ic_forcesema); @@ -2098,12 +2133,6 @@ } #endif - /* - * Transition from DIRTY to ACTIVE if applicable. NOP if - * STATE_IOERROR. - */ - xlog_state_clean_log(log); - if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) { flushcnt = log->l_flushcnt; log->l_flushcnt = 0; @@ -2652,52 +2681,6 @@ GRANT_UNLOCK(log, s); xfs_log_move_tail(log->l_mp, 1); } /* xlog_ungrant_log_space */ - - -/* - * If the lsn is not found or the iclog with the lsn is in the callback - * state, we need to call the function directly. This is done outside - * this function's scope. Otherwise, we insert the callback at the end - * of the iclog's callback list. - */ -int -xlog_state_lsn_is_synced(xlog_t *log, - xfs_lsn_t lsn, - xfs_log_callback_t *cb, - int *abortflg) -{ - xlog_in_core_t *iclog; - SPLDECL(s); - int lsn_is_synced = 1; - - *abortflg = 0; - s = LOG_LOCK(log); - - iclog = log->l_iclog; - do { - if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) != lsn) { - iclog = iclog->ic_next; - continue; - } else { - if (iclog->ic_state & XLOG_STATE_DIRTY) /* call it*/ - break; - - if (iclog->ic_state & XLOG_STATE_IOERROR) { - *abortflg = XFS_LI_ABORTED; - break; - } - /* insert callback onto end of list */ - cb->cb_next = 0; - *(iclog->ic_callback_tail) = cb; - iclog->ic_callback_tail = &(cb->cb_next); - lsn_is_synced = 0; - break; - } - } while (iclog != log->l_iclog); - - LOG_UNLOCK(log, s); - return lsn_is_synced; -} /* xlog_state_lsn_is_synced */ /* diff -Nru a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h --- a/fs/xfs/xfs_log.h Sun Feb 9 21:13:37 2003 +++ b/fs/xfs/xfs_log.h Sun Feb 9 21:13:37 2003 @@ -148,6 +148,7 @@ struct xfs_mount; xfs_lsn_t xfs_log_done(struct xfs_mount *mp, xfs_log_ticket_t ticket, + void **iclog, uint flags); int xfs_log_force(struct xfs_mount *mp, xfs_lsn_t lsn, @@ -160,8 +161,8 @@ int xfs_log_mount_finish(struct xfs_mount *mp, int); void xfs_log_move_tail(struct xfs_mount *mp, xfs_lsn_t tail_lsn); -void xfs_log_notify(struct xfs_mount *mp, - xfs_lsn_t lsn, +int xfs_log_notify(struct xfs_mount *mp, + void *iclog, xfs_log_callback_t *callback_entry); int xfs_log_reserve(struct xfs_mount *mp, int length, diff -Nru a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c --- a/fs/xfs/xfs_trans.c Sun Feb 9 21:13:32 2003 +++ b/fs/xfs/xfs_trans.c Sun Feb 9 21:13:32 2003 @@ -285,7 +285,7 @@ } else { log_flags = 0; } - xfs_log_done(tp->t_mountp, tp->t_ticket, log_flags); + xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags); tp->t_ticket = NULL; tp->t_log_res = 0; tp->t_flags &= ~XFS_TRANS_PERM_LOG_RES; @@ -669,6 +669,7 @@ #if defined(XLOG_NOLOG) || defined(DEBUG) static xfs_lsn_t trans_lsn = 1; #endif + void *commit_iclog; int shutdown; commit_lsn = -1; @@ -706,7 +707,8 @@ xfs_trans_unreserve_and_mod_dquots(tp); } if (tp->t_ticket) { - commit_lsn = xfs_log_done(mp, tp->t_ticket, log_flags); + commit_lsn = xfs_log_done(mp, tp->t_ticket, + NULL, log_flags); if (commit_lsn == -1 && !shutdown) shutdown = XFS_ERROR(EIO); } @@ -773,7 +775,7 @@ #if defined(XLOG_NOLOG) || defined(DEBUG) if (xlog_debug) { commit_lsn = xfs_log_done(mp, tp->t_ticket, - log_flags); + &commit_iclog, log_flags); } else { commit_lsn = 0; tp->t_lsn = trans_lsn++; @@ -785,7 +787,7 @@ * any time. However, all the items associated with the transaction * are still locked and pinned in memory. */ - commit_lsn = xfs_log_done(mp, tp->t_ticket, log_flags); + commit_lsn = xfs_log_done(mp, tp->t_ticket, &commit_iclog, log_flags); #endif tp->t_commit_lsn = commit_lsn; @@ -845,21 +847,28 @@ if (xlog_debug) { tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed; tp->t_logcb.cb_arg = tp; - xfs_log_notify(mp, commit_lsn, &(tp->t_logcb)); + error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb)); } else { xfs_trans_committed(tp, 0); } #else tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed; tp->t_logcb.cb_arg = tp; - xfs_log_notify(mp, commit_lsn, &(tp->t_logcb)); + + /* We need to pass the iclog buffer which was used for the + * transaction commit record into this function, attach + * the callback to it, and then release it. This will guarantee + * that we do callbacks on the transaction in the correct order. + */ + error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb)); #endif /* * If the transaction needs to be synchronous, then force the * log out now and wait for it. */ if (sync) { - error = xfs_log_force(mp, commit_lsn, + if (!error) + error = xfs_log_force(mp, commit_lsn, XFS_LOG_FORCE | XFS_LOG_SYNC); XFS_STATS_INC(xfsstats.xs_trans_sync); } else { @@ -1070,7 +1079,7 @@ } else { log_flags = 0; } - xfs_log_done(tp->t_mountp, tp->t_ticket, log_flags); + xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags); } xfs_trans_free_items(tp, flags); xfs_trans_free_busy(tp); @@ -1262,8 +1271,11 @@ /* * Now that we've repositioned the item in the AIL, - * unpin it so it can be flushed. + * unpin it so it can be flushed. Pass information + * about buffer stale state down from the log item + * flags, if anyone else stales the buffer we do not + * want to pay any attention to it. */ - IOP_UNPIN(lip); + IOP_UNPIN(lip, lidp->lid_flags & XFS_LID_BUF_STALE); } } diff -Nru a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h --- a/fs/xfs/xfs_trans.h Sun Feb 9 21:13:34 2003 +++ b/fs/xfs/xfs_trans.h Sun Feb 9 21:13:34 2003 @@ -170,7 +170,7 @@ uint (*iop_size)(xfs_log_item_t *); void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); void (*iop_pin)(xfs_log_item_t *); - void (*iop_unpin)(xfs_log_item_t *); + void (*iop_unpin)(xfs_log_item_t *, int); void (*iop_unpin_remove)(xfs_log_item_t *, struct xfs_trans *); uint (*iop_trylock)(xfs_log_item_t *); void (*iop_unlock)(xfs_log_item_t *); @@ -184,7 +184,7 @@ #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) #define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip) -#define IOP_UNPIN(ip) (*(ip)->li_ops->iop_unpin)(ip) +#define IOP_UNPIN(ip, flags) (*(ip)->li_ops->iop_unpin)(ip, flags) #define IOP_UNPIN_REMOVE(ip,tp) (*(ip)->li_ops->iop_unpin_remove)(ip, tp) #define IOP_TRYLOCK(ip) (*(ip)->li_ops->iop_trylock)(ip) #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) @@ -222,6 +222,7 @@ #define XFS_LID_DIRTY 0x1 #define XFS_LID_PINNED 0x2 #define XFS_LID_SYNC_UNLOCK 0x4 +#define XFS_LID_BUF_STALE 0x8 /* * This structure is used to maintain a chunk list of log_item_desc diff -Nru a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c --- a/fs/xfs/xfs_trans_buf.c Sun Feb 9 21:13:28 2003 +++ b/fs/xfs/xfs_trans_buf.c Sun Feb 9 21:13:28 2003 @@ -796,6 +796,7 @@ tp->t_flags |= XFS_TRANS_DIRTY; lidp->lid_flags |= XFS_LID_DIRTY; + lidp->lid_flags &= ~XFS_LID_BUF_STALE; bip->bli_flags |= XFS_BLI_LOGGED; xfs_buf_item_log(bip, first, last); xfs_buf_item_trace("BLOG", bip); @@ -882,7 +883,7 @@ bip->bli_format.blf_flags |= XFS_BLI_CANCEL; memset((char *)(bip->bli_format.blf_data_map), 0, (bip->bli_format.blf_map_size * sizeof(uint))); - lidp->lid_flags |= XFS_LID_DIRTY; + lidp->lid_flags |= XFS_LID_DIRTY|XFS_LID_BUF_STALE; tp->t_flags |= XFS_TRANS_DIRTY; xfs_buftrace("XFS_BINVAL", bp); xfs_buf_item_trace("BINVAL", bip); diff -Nru a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c --- a/fs/xfs/xfs_vfsops.c Sun Feb 9 21:13:29 2003 +++ b/fs/xfs/xfs_vfsops.c Sun Feb 9 21:13:29 2003 @@ -873,7 +873,6 @@ boolean_t mount_locked; boolean_t vnode_refed; int preempt; - int do_mmap_flush; xfs_dinode_t *dip; xfs_buf_log_item_t *bip; xfs_iptr_t *ipointer; @@ -944,8 +943,6 @@ fflag = XFS_B_DELWRI; if (flags & SYNC_WAIT) fflag = 0; /* synchronous overrides all */ - do_mmap_flush = (flags & (SYNC_DELWRI|SYNC_BDFLUSH)) != - (SYNC_DELWRI|SYNC_BDFLUSH); base_lock_flags = XFS_ILOCK_SHARED; if (flags & (SYNC_DELWRI | SYNC_CLOSE)) { @@ -1177,12 +1174,8 @@ * across calls to the buffer cache. */ xfs_iunlock(ip, XFS_ILOCK_SHARED); - if (do_mmap_flush) { - VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, - fflag, FI_NONE, error); - } else { - filemap_fdatawrite(LINVFS_GET_IP(vp)->i_mapping); - } + VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, + fflag, FI_NONE, error); xfs_ilock(ip, XFS_ILOCK_SHARED); } diff -Nru a/fs/xfs/xfsidbg.c b/fs/xfs/xfsidbg.c --- a/fs/xfs/xfsidbg.c Sun Feb 9 21:13:35 2003 +++ b/fs/xfs/xfsidbg.c Sun Feb 9 21:13:35 2003 @@ -5248,6 +5248,7 @@ "dirty", /* 0x1 */ "pinned", /* 0x2 */ "sync unlock", /* 0x4 */ + "buf stale", /* 0x8 */ 0 }; diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acconfig.h Sun Feb 9 21:13:34 2003 @@ -0,0 +1,188 @@ +/****************************************************************************** + * + * Name: acconfig.h - Global configuration constants + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef _ACCONFIG_H +#define _ACCONFIG_H + + +/****************************************************************************** + * + * Compile-time options + * + *****************************************************************************/ + +/* + * ACPI_DEBUG_OUTPUT - This switch enables all the debug facilities of the + * ACPI subsystem. This includes the DEBUG_PRINT output + * statements. When disabled, all DEBUG_PRINT + * statements are compiled out. + * + * ACPI_APPLICATION - Use this switch if the subsystem is going to be run + * at the application level. + * + */ + + +/****************************************************************************** + * + * Subsystem Constants + * + *****************************************************************************/ + + +/* Version string */ + +#define ACPI_CA_VERSION 0x20030122 + +/* Version of ACPI supported */ + +#define ACPI_CA_SUPPORT_LEVEL 2 + +/* Maximum objects in the various object caches */ + +#define ACPI_MAX_STATE_CACHE_DEPTH 64 /* State objects for stacks */ +#define ACPI_MAX_PARSE_CACHE_DEPTH 96 /* Parse tree objects */ +#define ACPI_MAX_EXTPARSE_CACHE_DEPTH 64 /* Parse tree objects */ +#define ACPI_MAX_OBJECT_CACHE_DEPTH 64 /* Interpreter operand objects */ +#define ACPI_MAX_WALK_CACHE_DEPTH 4 /* Objects for parse tree walks */ + +/* String size constants */ + +#define ACPI_MAX_STRING_LENGTH 512 +#define ACPI_PATHNAME_MAX 256 /* A full namespace pathname */ + +/* Maximum count for a semaphore object */ + +#define ACPI_MAX_SEMAPHORE_COUNT 256 + +/* Max reference count (for debug only) */ + +#define ACPI_MAX_REFERENCE_COUNT 0x400 + +/* Size of cached memory mapping for system memory operation region */ + +#define ACPI_SYSMEM_REGION_WINDOW_SIZE 4096 + + +/****************************************************************************** + * + * Configuration of subsystem behavior + * + *****************************************************************************/ + + +/* + * Should the subystem abort the loading of an ACPI table if the + * table checksum is incorrect? + */ +#define ACPI_CHECKSUM_ABORT FALSE + + +/****************************************************************************** + * + * ACPI Specification constants (Do not change unless the specification changes) + * + *****************************************************************************/ + +/* Number of distinct GPE register blocks and register width */ + +#define ACPI_MAX_GPE_BLOCKS 2 +#define ACPI_GPE_REGISTER_WIDTH 8 + +/* + * Method info (in WALK_STATE), containing local variables and argumetns + */ +#define ACPI_METHOD_NUM_LOCALS 8 +#define ACPI_METHOD_MAX_LOCAL 7 + +#define ACPI_METHOD_NUM_ARGS 7 +#define ACPI_METHOD_MAX_ARG 6 + +/* Maximum length of resulting string when converting from a buffer */ + +#define ACPI_MAX_STRING_CONVERSION 200 + +/* + * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG + */ +#define ACPI_OBJ_NUM_OPERANDS 8 +#define ACPI_OBJ_MAX_OPERAND 7 + +/* Names within the namespace are 4 bytes long */ + +#define ACPI_NAME_SIZE 4 +#define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */ +#define ACPI_PATH_SEPARATOR '.' + +/* Constants used in searching for the RSDP in low memory */ + +#define ACPI_LO_RSDP_WINDOW_BASE 0 /* Physical Address */ +#define ACPI_HI_RSDP_WINDOW_BASE 0xE0000 /* Physical Address */ +#define ACPI_LO_RSDP_WINDOW_SIZE 0x400 +#define ACPI_HI_RSDP_WINDOW_SIZE 0x20000 +#define ACPI_RSDP_SCAN_STEP 16 + +/* Operation regions */ + +#define ACPI_NUM_PREDEFINED_REGIONS 8 +#define ACPI_USER_REGION_BEGIN 0x80 + +/* Maximum space_ids for Operation Regions */ + +#define ACPI_MAX_ADDRESS_SPACE 255 + +/* Array sizes. Used for range checking also */ + +#define ACPI_NUM_ACCESS_TYPES 6 +#define ACPI_NUM_UPDATE_RULES 3 +#define ACPI_NUM_LOCK_RULES 2 +#define ACPI_NUM_MATCH_OPS 6 +#define ACPI_NUM_OPCODES 256 +#define ACPI_NUM_FIELD_NAMES 2 + +/* RSDP checksums */ + +#define ACPI_RSDP_CHECKSUM_LENGTH 20 +#define ACPI_RSDP_XCHECKSUM_LENGTH 36 + +/* SMBus bidirectional buffer size */ + +#define ACPI_SMBUS_BUFFER_SIZE 34 + + +/****************************************************************************** + * + * ACPI AML Debugger + * + *****************************************************************************/ + + +#define ACPI_DEBUGGER_MAX_ARGS 8 /* Must be max method args + 1 */ + +#define ACPI_DEBUGGER_COMMAND_PROMPT '-' +#define ACPI_DEBUGGER_EXECUTE_PROMPT '%' + + +#endif /* _ACCONFIG_H */ + diff -Nru a/include/acpi/acdebug.h b/include/acpi/acdebug.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acdebug.h Sun Feb 9 21:13:29 2003 @@ -0,0 +1,452 @@ +/****************************************************************************** + * + * Name: acdebug.h - ACPI/AML debugger + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACDEBUG_H__ +#define __ACDEBUG_H__ + + +#define ACPI_DEBUG_BUFFER_SIZE 4196 + +struct command_info +{ + char *name; /* Command Name */ + u8 min_args; /* Minimum arguments required */ +}; + + +struct argument_info +{ + char *name; /* Argument Name */ +}; + + +#define PARAM_LIST(pl) pl + +#define DBTEST_OUTPUT_LEVEL(lvl) if (acpi_gbl_db_opt_verbose) + +#define VERBOSE_PRINT(fp) DBTEST_OUTPUT_LEVEL(lvl) {\ + acpi_os_printf PARAM_LIST(fp);} + +#define EX_NO_SINGLE_STEP 1 +#define EX_SINGLE_STEP 2 + + +/* Prototypes */ + + +/* + * dbxface - external debugger interfaces + */ + +acpi_status +acpi_db_initialize ( + void); + +void +acpi_db_terminate ( + void); + +acpi_status +acpi_db_single_step ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + u32 op_type); + +acpi_status +acpi_db_start_command ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + +void +acpi_db_method_end ( + struct acpi_walk_state *walk_state); + + +/* + * dbcmds - debug commands and output routines + */ + +void +acpi_db_display_table_info ( + char *table_arg); + +void +acpi_db_unload_acpi_table ( + char *table_arg, + char *instance_arg); + +void +acpi_db_set_method_breakpoint ( + char *location, + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + +void +acpi_db_set_method_call_breakpoint ( + union acpi_parse_object *op); + +void +acpi_db_disassemble_aml ( + char *statements, + union acpi_parse_object *op); + +void +acpi_db_dump_namespace ( + char *start_arg, + char *depth_arg); + +void +acpi_db_dump_namespace_by_owner ( + char *owner_arg, + char *depth_arg); + +void +acpi_db_send_notify ( + char *name, + u32 value); + +void +acpi_db_set_method_data ( + char *type_arg, + char *index_arg, + char *value_arg); + +acpi_status +acpi_db_display_objects ( + char *obj_type_arg, + char *display_count_arg); + +acpi_status +acpi_db_find_name_in_namespace ( + char *name_arg); + +void +acpi_db_set_scope ( + char *name); + +void +acpi_db_find_references ( + char *object_arg); + +void +acpi_db_display_locks (void); + + +void +acpi_db_display_resources ( + char *object_arg); + +void +acpi_db_check_integrity ( + void); + +acpi_status +acpi_db_integrity_walk ( + acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value); + +acpi_status +acpi_db_walk_and_match_name ( + acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value); + +acpi_status +acpi_db_walk_for_references ( + acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value); + +acpi_status +acpi_db_walk_for_specific_objects ( + acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value); + + +/* + * dbdisply - debug display commands + */ + +void +acpi_db_display_method_info ( + union acpi_parse_object *op); + +void +acpi_db_decode_and_display_object ( + char *target, + char *output_type); + +void +acpi_db_decode_node ( + struct acpi_namespace_node *node); + +void +acpi_db_display_result_object ( + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_db_display_all_methods ( + char *display_count_arg); + +void +acpi_db_display_internal_object ( + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state); + +void +acpi_db_display_arguments ( + void); + +void +acpi_db_display_locals ( + void); + +void +acpi_db_display_results ( + void); + +void +acpi_db_display_calling_tree ( + void); + +void +acpi_db_display_argument_object ( + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state); + +void +acpi_db_dump_parser_descriptor ( + union acpi_parse_object *op); + +void * +acpi_db_get_pointer ( + void *target); + +void +acpi_db_decode_internal_object ( + union acpi_operand_object *obj_desc); + + +/* + * dbexec - debugger control method execution + */ + +void +acpi_db_execute ( + char *name, + char **args, + u32 flags); + +void +acpi_db_create_execution_threads ( + char *num_threads_arg, + char *num_loops_arg, + char *method_name_arg); + +acpi_status +acpi_db_execute_method ( + struct acpi_db_method_info *info, + struct acpi_buffer *return_obj); + +void +acpi_db_execute_setup ( + struct acpi_db_method_info *info); + +u32 +acpi_db_get_outstanding_allocations ( + void); + +void ACPI_SYSTEM_XFACE +acpi_db_method_thread ( + void *context); + +acpi_status +acpi_db_execution_walk ( + acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value); + + +/* + * dbfileio - Debugger file I/O commands + */ + +acpi_object_type +acpi_db_match_argument ( + char *user_argument, + struct argument_info *arguments); + +acpi_status +ae_local_load_table ( + struct acpi_table_header *table_ptr); + +void +acpi_db_close_debug_file ( + void); + +void +acpi_db_open_debug_file ( + char *name); + +acpi_status +acpi_db_load_acpi_table ( + char *filename); + +acpi_status +acpi_db_get_table_from_file ( + char *filename, + struct acpi_table_header **table); + +acpi_status +acpi_db_read_table_from_file ( + char *filename, + struct acpi_table_header **table); + +/* + * dbhistry - debugger HISTORY command + */ + +void +acpi_db_add_to_history ( + char *command_line); + +void +acpi_db_display_history (void); + +char * +acpi_db_get_from_history ( + char *command_num_arg); + + +/* + * dbinput - user front-end to the AML debugger + */ + +acpi_status +acpi_db_command_dispatch ( + char *input_buffer, + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + +void ACPI_SYSTEM_XFACE +acpi_db_execute_thread ( + void *context); + +acpi_status +acpi_db_user_commands ( + char prompt, + union acpi_parse_object *op); + +void +acpi_db_display_help ( + char *help_type); + +char * +acpi_db_get_next_token ( + char *string, + char **next); + +u32 +acpi_db_get_line ( + char *input_buffer); + +u32 +acpi_db_match_command ( + char *user_command); + +void +acpi_db_single_thread ( + void); + + +/* + * dbstats - Generation and display of ACPI table statistics + */ + +void +acpi_db_generate_statistics ( + union acpi_parse_object *root, + u8 is_method); + + +acpi_status +acpi_db_display_statistics ( + char *type_arg); + +acpi_status +acpi_db_classify_one_object ( + acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value); + +void +acpi_db_count_namespace_objects ( + void); + +void +acpi_db_enumerate_object ( + union acpi_operand_object *obj_desc); + + +/* + * dbutils - AML debugger utilities + */ + +void +acpi_db_set_output_destination ( + u32 where); + +void +acpi_db_dump_buffer ( + u32 address); + +void +acpi_db_dump_object ( + union acpi_object *obj_desc, + u32 level); + +void +acpi_db_prep_namestring ( + char *name); + + +acpi_status +acpi_db_second_pass_parse ( + union acpi_parse_object *root); + +struct acpi_namespace_node * +acpi_db_local_ns_lookup ( + char *name); + + +#endif /* __ACDEBUG_H__ */ diff -Nru a/include/acpi/acdispat.h b/include/acpi/acdispat.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acdispat.h Sun Feb 9 21:13:34 2003 @@ -0,0 +1,494 @@ +/****************************************************************************** + * + * Name: acdispat.h - dispatcher (parser to interpreter interface) + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + + +#ifndef _ACDISPAT_H_ +#define _ACDISPAT_H_ + + +#define NAMEOF_LOCAL_NTE "__L0" +#define NAMEOF_ARG_NTE "__A0" + + +/* Common interfaces */ + +acpi_status +acpi_ds_obj_stack_push ( + void *object, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_obj_stack_pop ( + u32 pop_count, + struct acpi_walk_state *walk_state); + +void * +acpi_ds_obj_stack_get_value ( + u32 index, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_obj_stack_pop_object ( + union acpi_operand_object **object, + struct acpi_walk_state *walk_state); + + +/* dsopcode - support for late evaluation */ + +acpi_status +acpi_ds_execute_arguments ( + struct acpi_namespace_node *node, + struct acpi_namespace_node *scope_node, + u32 aml_length, + u8 *aml_start); + +acpi_status +acpi_ds_get_buffer_field_arguments ( + union acpi_operand_object *obj_desc); + +acpi_status +acpi_ds_get_region_arguments ( + union acpi_operand_object *rgn_desc); + +acpi_status +acpi_ds_get_buffer_arguments ( + union acpi_operand_object *obj_desc); + +acpi_status +acpi_ds_get_package_arguments ( + union acpi_operand_object *obj_desc); + +acpi_status +acpi_ds_init_buffer_field ( + u16 aml_opcode, + union acpi_operand_object *obj_desc, + union acpi_operand_object *buffer_desc, + union acpi_operand_object *offset_desc, + union acpi_operand_object *length_desc, + union acpi_operand_object *result_desc); + +acpi_status +acpi_ds_eval_buffer_field_operands ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + +acpi_status +acpi_ds_eval_region_operands ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + +acpi_status +acpi_ds_eval_data_object_operands ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + union acpi_operand_object *obj_desc); + +acpi_status +acpi_ds_initialize_region ( + acpi_handle obj_handle); + + +/* dsctrl - Parser/Interpreter interface, control stack routines */ + + +acpi_status +acpi_ds_exec_begin_control_op ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + +acpi_status +acpi_ds_exec_end_control_op ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + + +/* dsexec - Parser/Interpreter interface, method execution callbacks */ + + +acpi_status +acpi_ds_get_predicate_value ( + struct acpi_walk_state *walk_state, + union acpi_operand_object *result_obj); + +acpi_status +acpi_ds_exec_begin_op ( + struct acpi_walk_state *walk_state, + union acpi_parse_object **out_op); + +acpi_status +acpi_ds_exec_end_op ( + struct acpi_walk_state *state); + + +/* dsfield - Parser/Interpreter interface for AML fields */ + +acpi_status +acpi_ds_get_field_names ( + struct acpi_create_field_info *info, + struct acpi_walk_state *walk_state, + union acpi_parse_object *arg); + +acpi_status +acpi_ds_create_field ( + union acpi_parse_object *op, + struct acpi_namespace_node *region_node, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_create_bank_field ( + union acpi_parse_object *op, + struct acpi_namespace_node *region_node, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_create_index_field ( + union acpi_parse_object *op, + struct acpi_namespace_node *region_node, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_create_buffer_field ( + union acpi_parse_object *op, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_init_field_objects ( + union acpi_parse_object *op, + struct acpi_walk_state *walk_state); + + +/* dsload - Parser/Interpreter interface, namespace load callbacks */ + +acpi_status +acpi_ds_load1_begin_op ( + struct acpi_walk_state *walk_state, + union acpi_parse_object **out_op); + +acpi_status +acpi_ds_load1_end_op ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_load2_begin_op ( + struct acpi_walk_state *walk_state, + union acpi_parse_object **out_op); + +acpi_status +acpi_ds_load2_end_op ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_init_callbacks ( + struct acpi_walk_state *walk_state, + u32 pass_number); + + +/* dsmthdat - method data (locals/args) */ + + +acpi_status +acpi_ds_store_object_to_local ( + u16 opcode, + u32 index, + union acpi_operand_object *src_desc, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_method_data_get_entry ( + u16 opcode, + u32 index, + struct acpi_walk_state *walk_state, + union acpi_operand_object ***node); + +void +acpi_ds_method_data_delete_all ( + struct acpi_walk_state *walk_state); + +u8 +acpi_ds_is_method_value ( + union acpi_operand_object *obj_desc); + +acpi_object_type +acpi_ds_method_data_get_type ( + u16 opcode, + u32 index, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_method_data_get_value ( + u16 opcode, + u32 index, + struct acpi_walk_state *walk_state, + union acpi_operand_object **dest_desc); + +void +acpi_ds_method_data_delete_value ( + u16 opcode, + u32 index, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_method_data_init_args ( + union acpi_operand_object **params, + u32 max_param_count, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_method_data_get_node ( + u16 opcode, + u32 index, + struct acpi_walk_state *walk_state, + struct acpi_namespace_node **node); + +void +acpi_ds_method_data_init ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_method_data_set_value ( + u16 opcode, + u32 index, + union acpi_operand_object *object, + struct acpi_walk_state *walk_state); + + +/* dsmethod - Parser/Interpreter interface - control method parsing */ + +acpi_status +acpi_ds_parse_method ( + acpi_handle obj_handle); + +acpi_status +acpi_ds_call_control_method ( + struct acpi_thread_state *thread, + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + +acpi_status +acpi_ds_restart_control_method ( + struct acpi_walk_state *walk_state, + union acpi_operand_object *return_desc); + +acpi_status +acpi_ds_terminate_control_method ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_begin_method_execution ( + struct acpi_namespace_node *method_node, + union acpi_operand_object *obj_desc, + struct acpi_namespace_node *calling_method_node); + + +/* dsobj - Parser/Interpreter interface - object initialization and conversion */ + +acpi_status +acpi_ds_init_one_object ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value); + +acpi_status +acpi_ds_initialize_objects ( + struct acpi_table_desc *table_desc, + struct acpi_namespace_node *start_node); + +acpi_status +acpi_ds_build_internal_buffer_obj ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + u32 buffer_length, + union acpi_operand_object **obj_desc_ptr); + +acpi_status +acpi_ds_build_internal_package_obj ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + u32 package_length, + union acpi_operand_object **obj_desc); + +acpi_status +acpi_ds_build_internal_object ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + union acpi_operand_object **obj_desc_ptr); + +acpi_status +acpi_ds_init_object_from_op ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + u16 opcode, + union acpi_operand_object **obj_desc); + +acpi_status +acpi_ds_create_node ( + struct acpi_walk_state *walk_state, + struct acpi_namespace_node *node, + union acpi_parse_object *op); + + +/* dsutils - Parser/Interpreter interface utility routines */ + +u8 +acpi_ds_is_result_used ( + union acpi_parse_object *op, + struct acpi_walk_state *walk_state); + +void +acpi_ds_delete_result_if_not_used ( + union acpi_parse_object *op, + union acpi_operand_object *result_obj, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_create_operand ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *arg, + u32 args_remaining); + +acpi_status +acpi_ds_create_operands ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *first_arg); + +acpi_status +acpi_ds_resolve_operands ( + struct acpi_walk_state *walk_state); + +void +acpi_ds_clear_operands ( + struct acpi_walk_state *walk_state); + + +/* + * dswscope - Scope Stack manipulation + */ + +acpi_status +acpi_ds_scope_stack_push ( + struct acpi_namespace_node *node, + acpi_object_type type, + struct acpi_walk_state *walk_state); + + +acpi_status +acpi_ds_scope_stack_pop ( + struct acpi_walk_state *walk_state); + +void +acpi_ds_scope_stack_clear ( + struct acpi_walk_state *walk_state); + + +/* dswstate - parser WALK_STATE management routines */ + +struct acpi_walk_state * +acpi_ds_create_walk_state ( + acpi_owner_id owner_id, + union acpi_parse_object *origin, + union acpi_operand_object *mth_desc, + struct acpi_thread_state *thread); + +acpi_status +acpi_ds_init_aml_walk ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + struct acpi_namespace_node *method_node, + u8 *aml_start, + u32 aml_length, + union acpi_operand_object **params, + union acpi_operand_object **return_obj_desc, + u32 pass_number); + +acpi_status +acpi_ds_obj_stack_delete_all ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_obj_stack_pop_and_delete ( + u32 pop_count, + struct acpi_walk_state *walk_state); + +void +acpi_ds_delete_walk_state ( + struct acpi_walk_state *walk_state); + +struct acpi_walk_state * +acpi_ds_pop_walk_state ( + struct acpi_thread_state *thread); + +void +acpi_ds_push_walk_state ( + struct acpi_walk_state *walk_state, + struct acpi_thread_state *thread); + +acpi_status +acpi_ds_result_stack_pop ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_result_stack_push ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_result_stack_clear ( + struct acpi_walk_state *walk_state); + +struct acpi_walk_state * +acpi_ds_get_current_walk_state ( + struct acpi_thread_state *thread); + +void +acpi_ds_delete_walk_state_cache ( + void); + +acpi_status +acpi_ds_result_insert ( + void *object, + u32 index, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_result_remove ( + union acpi_operand_object **object, + u32 index, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_result_pop ( + union acpi_operand_object **object, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_result_push ( + union acpi_operand_object *object, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ds_result_pop_from_bottom ( + union acpi_operand_object **object, + struct acpi_walk_state *walk_state); + +#endif /* _ACDISPAT_H_ */ diff -Nru a/include/acpi/acevents.h b/include/acpi/acevents.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acevents.h Sun Feb 9 21:13:33 2003 @@ -0,0 +1,221 @@ +/****************************************************************************** + * + * Name: acevents.h - Event subcomponent prototypes and defines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACEVENTS_H__ +#define __ACEVENTS_H__ + + +acpi_status +acpi_ev_initialize ( + void); + +acpi_status +acpi_ev_handler_initialize ( + void); + + +/* + * Evfixed - Fixed event handling + */ + +acpi_status +acpi_ev_fixed_event_initialize ( + void); + +u32 +acpi_ev_fixed_event_detect ( + void); + +u32 +acpi_ev_fixed_event_dispatch ( + u32 event); + + +/* + * Evmisc + */ + +u8 +acpi_ev_is_notify_object ( + struct acpi_namespace_node *node); + +acpi_status +acpi_ev_acquire_global_lock( + u16 timeout); + +acpi_status +acpi_ev_release_global_lock( + void); + +acpi_status +acpi_ev_init_global_lock_handler ( + void); + +u32 +acpi_ev_get_gpe_register_index ( + u32 gpe_number); + +u32 +acpi_ev_get_gpe_number_index ( + u32 gpe_number); + +acpi_status +acpi_ev_queue_notify_request ( + struct acpi_namespace_node *node, + u32 notify_value); + +void ACPI_SYSTEM_XFACE +acpi_ev_notify_dispatch ( + void *context); + + +/* + * Evgpe - GPE handling and dispatch + */ + +acpi_status +acpi_ev_gpe_initialize ( + void); + +acpi_status +acpi_ev_init_gpe_control_methods ( + void); + +u32 +acpi_ev_gpe_dispatch ( + u32 gpe_number); + +u32 +acpi_ev_gpe_detect ( + void); + +/* + * Evregion - Address Space handling + */ + +acpi_status +acpi_ev_init_address_spaces ( + void); + +acpi_status +acpi_ev_address_space_dispatch ( + union acpi_operand_object *region_obj, + u32 function, + acpi_physical_address address, + u32 bit_width, + void *value); + +acpi_status +acpi_ev_addr_handler_helper ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value); + +acpi_status +acpi_ev_attach_region ( + union acpi_operand_object *handler_obj, + union acpi_operand_object *region_obj, + u8 acpi_ns_is_locked); + +void +acpi_ev_detach_region ( + union acpi_operand_object *region_obj, + u8 acpi_ns_is_locked); + + +/* + * Evregini - Region initialization and setup + */ + +acpi_status +acpi_ev_system_memory_region_setup ( + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context); + +acpi_status +acpi_ev_io_space_region_setup ( + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context); + +acpi_status +acpi_ev_pci_config_region_setup ( + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context); + +acpi_status +acpi_ev_cmos_region_setup ( + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context); + +acpi_status +acpi_ev_pci_bar_region_setup ( + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context); + +acpi_status +acpi_ev_default_region_setup ( + acpi_handle handle, + u32 function, + void *handler_context, + void **region_context); + +acpi_status +acpi_ev_initialize_region ( + union acpi_operand_object *region_obj, + u8 acpi_ns_locked); + + +/* + * Evsci - SCI (System Control Interrupt) handling/dispatch + */ + +u32 +acpi_ev_install_sci_handler ( + void); + +acpi_status +acpi_ev_remove_sci_handler ( + void); + +u32 +acpi_ev_initialize_sCI ( + u32 program_sCI); + +void +acpi_ev_terminate ( + void); + + +#endif /* __ACEVENTS_H__ */ diff -Nru a/include/acpi/acexcep.h b/include/acpi/acexcep.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acexcep.h Sun Feb 9 21:13:28 2003 @@ -0,0 +1,283 @@ +/****************************************************************************** + * + * Name: acexcep.h - Exception codes returned by the ACPI subsystem + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACEXCEP_H__ +#define __ACEXCEP_H__ + + +/* + * Exceptions returned by external ACPI interfaces + */ + +#define AE_CODE_ENVIRONMENTAL 0x0000 +#define AE_CODE_PROGRAMMER 0x1000 +#define AE_CODE_ACPI_TABLES 0x2000 +#define AE_CODE_AML 0x3000 +#define AE_CODE_CONTROL 0x4000 +#define AE_CODE_MASK 0xF000 + + +#define ACPI_SUCCESS(a) (!(a)) +#define ACPI_FAILURE(a) (a) + + +#define AE_OK (acpi_status) 0x0000 + +/* + * Environmental exceptions + */ +#define AE_ERROR (acpi_status) (0x0001 | AE_CODE_ENVIRONMENTAL) +#define AE_NO_ACPI_TABLES (acpi_status) (0x0002 | AE_CODE_ENVIRONMENTAL) +#define AE_NO_NAMESPACE (acpi_status) (0x0003 | AE_CODE_ENVIRONMENTAL) +#define AE_NO_MEMORY (acpi_status) (0x0004 | AE_CODE_ENVIRONMENTAL) +#define AE_NOT_FOUND (acpi_status) (0x0005 | AE_CODE_ENVIRONMENTAL) +#define AE_NOT_EXIST (acpi_status) (0x0006 | AE_CODE_ENVIRONMENTAL) +#define AE_ALREADY_EXISTS (acpi_status) (0x0007 | AE_CODE_ENVIRONMENTAL) +#define AE_TYPE (acpi_status) (0x0008 | AE_CODE_ENVIRONMENTAL) +#define AE_NULL_OBJECT (acpi_status) (0x0009 | AE_CODE_ENVIRONMENTAL) +#define AE_NULL_ENTRY (acpi_status) (0x000A | AE_CODE_ENVIRONMENTAL) +#define AE_BUFFER_OVERFLOW (acpi_status) (0x000B | AE_CODE_ENVIRONMENTAL) +#define AE_STACK_OVERFLOW (acpi_status) (0x000C | AE_CODE_ENVIRONMENTAL) +#define AE_STACK_UNDERFLOW (acpi_status) (0x000D | AE_CODE_ENVIRONMENTAL) +#define AE_NOT_IMPLEMENTED (acpi_status) (0x000E | AE_CODE_ENVIRONMENTAL) +#define AE_VERSION_MISMATCH (acpi_status) (0x000F | AE_CODE_ENVIRONMENTAL) +#define AE_SUPPORT (acpi_status) (0x0010 | AE_CODE_ENVIRONMENTAL) +#define AE_SHARE (acpi_status) (0x0011 | AE_CODE_ENVIRONMENTAL) +#define AE_LIMIT (acpi_status) (0x0012 | AE_CODE_ENVIRONMENTAL) +#define AE_TIME (acpi_status) (0x0013 | AE_CODE_ENVIRONMENTAL) +#define AE_UNKNOWN_STATUS (acpi_status) (0x0014 | AE_CODE_ENVIRONMENTAL) +#define AE_ACQUIRE_DEADLOCK (acpi_status) (0x0015 | AE_CODE_ENVIRONMENTAL) +#define AE_RELEASE_DEADLOCK (acpi_status) (0x0016 | AE_CODE_ENVIRONMENTAL) +#define AE_NOT_ACQUIRED (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL) +#define AE_ALREADY_ACQUIRED (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL) +#define AE_NO_HARDWARE_RESPONSE (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL) +#define AE_NO_GLOBAL_LOCK (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL) +#define AE_LOGICAL_ADDRESS (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL) +#define AE_ABORT_METHOD (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL) + +#define AE_CODE_ENV_MAX 0x001C + +/* + * Programmer exceptions + */ +#define AE_BAD_PARAMETER (acpi_status) (0x0001 | AE_CODE_PROGRAMMER) +#define AE_BAD_CHARACTER (acpi_status) (0x0002 | AE_CODE_PROGRAMMER) +#define AE_BAD_PATHNAME (acpi_status) (0x0003 | AE_CODE_PROGRAMMER) +#define AE_BAD_DATA (acpi_status) (0x0004 | AE_CODE_PROGRAMMER) +#define AE_BAD_ADDRESS (acpi_status) (0x0005 | AE_CODE_PROGRAMMER) +#define AE_ALIGNMENT (acpi_status) (0x0006 | AE_CODE_PROGRAMMER) +#define AE_BAD_HEX_CONSTANT (acpi_status) (0x0007 | AE_CODE_PROGRAMMER) +#define AE_BAD_OCTAL_CONSTANT (acpi_status) (0x0008 | AE_CODE_PROGRAMMER) +#define AE_BAD_DECIMAL_CONSTANT (acpi_status) (0x0009 | AE_CODE_PROGRAMMER) + +#define AE_CODE_PGM_MAX 0x0009 + + +/* + * Acpi table exceptions + */ +#define AE_BAD_SIGNATURE (acpi_status) (0x0001 | AE_CODE_ACPI_TABLES) +#define AE_BAD_HEADER (acpi_status) (0x0002 | AE_CODE_ACPI_TABLES) +#define AE_BAD_CHECKSUM (acpi_status) (0x0003 | AE_CODE_ACPI_TABLES) +#define AE_BAD_VALUE (acpi_status) (0x0004 | AE_CODE_ACPI_TABLES) +#define AE_TABLE_NOT_SUPPORTED (acpi_status) (0x0005 | AE_CODE_ACPI_TABLES) +#define AE_INVALID_TABLE_LENGTH (acpi_status) (0x0006 | AE_CODE_ACPI_TABLES) + +#define AE_CODE_TBL_MAX 0x0006 + + +/* + * AML exceptions. These are caused by problems with + * the actual AML byte stream + */ +#define AE_AML_ERROR (acpi_status) (0x0001 | AE_CODE_AML) +#define AE_AML_PARSE (acpi_status) (0x0002 | AE_CODE_AML) +#define AE_AML_BAD_OPCODE (acpi_status) (0x0003 | AE_CODE_AML) +#define AE_AML_NO_OPERAND (acpi_status) (0x0004 | AE_CODE_AML) +#define AE_AML_OPERAND_TYPE (acpi_status) (0x0005 | AE_CODE_AML) +#define AE_AML_OPERAND_VALUE (acpi_status) (0x0006 | AE_CODE_AML) +#define AE_AML_UNINITIALIZED_LOCAL (acpi_status) (0x0007 | AE_CODE_AML) +#define AE_AML_UNINITIALIZED_ARG (acpi_status) (0x0008 | AE_CODE_AML) +#define AE_AML_UNINITIALIZED_ELEMENT (acpi_status) (0x0009 | AE_CODE_AML) +#define AE_AML_NUMERIC_OVERFLOW (acpi_status) (0x000A | AE_CODE_AML) +#define AE_AML_REGION_LIMIT (acpi_status) (0x000B | AE_CODE_AML) +#define AE_AML_BUFFER_LIMIT (acpi_status) (0x000C | AE_CODE_AML) +#define AE_AML_PACKAGE_LIMIT (acpi_status) (0x000D | AE_CODE_AML) +#define AE_AML_DIVIDE_BY_ZERO (acpi_status) (0x000E | AE_CODE_AML) +#define AE_AML_BAD_NAME (acpi_status) (0x000F | AE_CODE_AML) +#define AE_AML_NAME_NOT_FOUND (acpi_status) (0x0010 | AE_CODE_AML) +#define AE_AML_INTERNAL (acpi_status) (0x0011 | AE_CODE_AML) +#define AE_AML_INVALID_SPACE_ID (acpi_status) (0x0012 | AE_CODE_AML) +#define AE_AML_STRING_LIMIT (acpi_status) (0x0013 | AE_CODE_AML) +#define AE_AML_NO_RETURN_VALUE (acpi_status) (0x0014 | AE_CODE_AML) +#define AE_AML_METHOD_LIMIT (acpi_status) (0x0015 | AE_CODE_AML) +#define AE_AML_NOT_OWNER (acpi_status) (0x0016 | AE_CODE_AML) +#define AE_AML_MUTEX_ORDER (acpi_status) (0x0017 | AE_CODE_AML) +#define AE_AML_MUTEX_NOT_ACQUIRED (acpi_status) (0x0018 | AE_CODE_AML) +#define AE_AML_INVALID_RESOURCE_TYPE (acpi_status) (0x0019 | AE_CODE_AML) +#define AE_AML_INVALID_INDEX (acpi_status) (0x001A | AE_CODE_AML) +#define AE_AML_REGISTER_LIMIT (acpi_status) (0x001B | AE_CODE_AML) +#define AE_AML_NO_WHILE (acpi_status) (0x001C | AE_CODE_AML) +#define AE_AML_ALIGNMENT (acpi_status) (0x001D | AE_CODE_AML) +#define AE_AML_NO_RESOURCE_END_TAG (acpi_status) (0x001E | AE_CODE_AML) +#define AE_AML_BAD_RESOURCE_VALUE (acpi_status) (0x001F | AE_CODE_AML) +#define AE_AML_CIRCULAR_REFERENCE (acpi_status) (0x0020 | AE_CODE_AML) + +#define AE_CODE_AML_MAX 0x0020 + +/* + * Internal exceptions used for control + */ +#define AE_CTRL_RETURN_VALUE (acpi_status) (0x0001 | AE_CODE_CONTROL) +#define AE_CTRL_PENDING (acpi_status) (0x0002 | AE_CODE_CONTROL) +#define AE_CTRL_TERMINATE (acpi_status) (0x0003 | AE_CODE_CONTROL) +#define AE_CTRL_TRUE (acpi_status) (0x0004 | AE_CODE_CONTROL) +#define AE_CTRL_FALSE (acpi_status) (0x0005 | AE_CODE_CONTROL) +#define AE_CTRL_DEPTH (acpi_status) (0x0006 | AE_CODE_CONTROL) +#define AE_CTRL_END (acpi_status) (0x0007 | AE_CODE_CONTROL) +#define AE_CTRL_TRANSFER (acpi_status) (0x0008 | AE_CODE_CONTROL) +#define AE_CTRL_BREAK (acpi_status) (0x0009 | AE_CODE_CONTROL) +#define AE_CTRL_CONTINUE (acpi_status) (0x000A | AE_CODE_CONTROL) +#define AE_CTRL_SKIP (acpi_status) (0x000B | AE_CODE_CONTROL) + +#define AE_CODE_CTRL_MAX 0x000B + + +#ifdef DEFINE_ACPI_GLOBALS + +/* + * String versions of the exception codes above + * These strings must match the corresponding defines exactly + */ +char const *acpi_gbl_exception_names_env[] = +{ + "AE_OK", + "AE_ERROR", + "AE_NO_ACPI_TABLES", + "AE_NO_NAMESPACE", + "AE_NO_MEMORY", + "AE_NOT_FOUND", + "AE_NOT_EXIST", + "AE_ALREADY_EXISTS", + "AE_TYPE", + "AE_NULL_OBJECT", + "AE_NULL_ENTRY", + "AE_BUFFER_OVERFLOW", + "AE_STACK_OVERFLOW", + "AE_STACK_UNDERFLOW", + "AE_NOT_IMPLEMENTED", + "AE_VERSION_MISMATCH", + "AE_SUPPORT", + "AE_SHARE", + "AE_LIMIT", + "AE_TIME", + "AE_UNKNOWN_STATUS", + "AE_ACQUIRE_DEADLOCK", + "AE_RELEASE_DEADLOCK", + "AE_NOT_ACQUIRED", + "AE_ALREADY_ACQUIRED", + "AE_NO_HARDWARE_RESPONSE", + "AE_NO_GLOBAL_LOCK", + "AE_LOGICAL_ADDRESS", + "AE_ABORT_METHOD" +}; + +char const *acpi_gbl_exception_names_pgm[] = +{ + "AE_BAD_PARAMETER", + "AE_BAD_CHARACTER", + "AE_BAD_PATHNAME", + "AE_BAD_DATA", + "AE_BAD_ADDRESS", + "AE_ALIGNMENT", + "AE_BAD_HEX_CONSTANT", + "AE_BAD_OCTAL_CONSTANT", + "AE_BAD_DECIMAL_CONSTANT" +}; + +char const *acpi_gbl_exception_names_tbl[] = +{ + "AE_BAD_SIGNATURE", + "AE_BAD_HEADER", + "AE_BAD_CHECKSUM", + "AE_BAD_VALUE", + "AE_TABLE_NOT_SUPPORTED", + "AE_INVALID_TABLE_LENGTH" +}; + +char const *acpi_gbl_exception_names_aml[] = +{ + "AE_AML_ERROR", + "AE_AML_PARSE", + "AE_AML_BAD_OPCODE", + "AE_AML_NO_OPERAND", + "AE_AML_OPERAND_TYPE", + "AE_AML_OPERAND_VALUE", + "AE_AML_UNINITIALIZED_LOCAL", + "AE_AML_UNINITIALIZED_ARG", + "AE_AML_UNINITIALIZED_ELEMENT", + "AE_AML_NUMERIC_OVERFLOW", + "AE_AML_REGION_LIMIT", + "AE_AML_BUFFER_LIMIT", + "AE_AML_PACKAGE_LIMIT", + "AE_AML_DIVIDE_BY_ZERO", + "AE_AML_BAD_NAME", + "AE_AML_NAME_NOT_FOUND", + "AE_AML_INTERNAL", + "AE_AML_INVALID_SPACE_ID", + "AE_AML_STRING_LIMIT", + "AE_AML_NO_RETURN_VALUE", + "AE_AML_METHOD_LIMIT", + "AE_AML_NOT_OWNER", + "AE_AML_MUTEX_ORDER", + "AE_AML_MUTEX_NOT_ACQUIRED", + "AE_AML_INVALID_RESOURCE_TYPE", + "AE_AML_INVALID_INDEX", + "AE_AML_REGISTER_LIMIT", + "AE_AML_NO_WHILE", + "AE_AML_ALIGNMENT", + "AE_AML_NO_RESOURCE_END_TAG", + "AE_AML_BAD_RESOURCE_VALUE", + "AE_AML_CIRCULAR_REFERENCE" +}; + +char const *acpi_gbl_exception_names_ctrl[] = +{ + "AE_CTRL_RETURN_VALUE", + "AE_CTRL_PENDING", + "AE_CTRL_TERMINATE", + "AE_CTRL_TRUE", + "AE_CTRL_FALSE", + "AE_CTRL_DEPTH", + "AE_CTRL_END", + "AE_CTRL_TRANSFER", + "AE_CTRL_BREAK", + "AE_CTRL_CONTINUE", + "AE_CTRL_SKIP" +}; + +#endif /* ACPI GLOBALS */ + + +#endif /* __ACEXCEP_H__ */ diff -Nru a/include/acpi/acglobal.h b/include/acpi/acglobal.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acglobal.h Sun Feb 9 21:13:28 2003 @@ -0,0 +1,298 @@ +/****************************************************************************** + * + * Name: acglobal.h - Declarations for global variables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACGLOBAL_H__ +#define __ACGLOBAL_H__ + + +/* + * Ensure that the globals are actually defined only once. + * + * The use of these defines allows a single list of globals (here) in order + * to simplify maintenance of the code. + */ +#ifdef DEFINE_ACPI_GLOBALS +#define ACPI_EXTERN +#else +#define ACPI_EXTERN extern +#endif + + +/***************************************************************************** + * + * Debug support + * + ****************************************************************************/ + +/* Runtime configuration of debug print levels */ + +extern u32 acpi_dbg_level; +extern u32 acpi_dbg_layer; + +/* Procedure nesting level for debug output */ + +extern u32 acpi_gbl_nesting_level; + + +/***************************************************************************** + * + * ACPI Table globals + * + ****************************************************************************/ + +/* + * Table pointers. + * Although these pointers are somewhat redundant with the global acpi_table, + * they are convenient because they are typed pointers. + * + * These tables are single-table only; meaning that there can be at most one + * of each in the system. Each global points to the actual table. + * + */ +ACPI_EXTERN u32 acpi_gbl_table_flags; +ACPI_EXTERN u32 acpi_gbl_rsdt_table_count; +ACPI_EXTERN struct rsdp_descriptor *acpi_gbl_RSDP; +ACPI_EXTERN XSDT_DESCRIPTOR *acpi_gbl_XSDT; +ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT; +ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT; +ACPI_EXTERN FACS_DESCRIPTOR *acpi_gbl_FACS; +ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS; + +/* + * Handle both ACPI 1.0 and ACPI 2.0 Integer widths + * If we are running a method that exists in a 32-bit ACPI table. + * Use only 32 bits of the Integer for conversion. + */ +ACPI_EXTERN u8 acpi_gbl_integer_bit_width; +ACPI_EXTERN u8 acpi_gbl_integer_byte_width; + +/* + * Since there may be multiple SSDTs and PSDTS, a single pointer is not + * sufficient; Therefore, there isn't one! + */ + + +/* + * ACPI Table info arrays + */ +extern struct acpi_table_desc acpi_gbl_acpi_tables[NUM_ACPI_TABLES]; +extern struct acpi_table_support acpi_gbl_acpi_table_data[NUM_ACPI_TABLES]; + +/* + * Predefined mutex objects. This array contains the + * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs. + * (The table maps local handles to the real OS handles) + */ +ACPI_EXTERN struct acpi_mutex_info acpi_gbl_acpi_mutex_info [NUM_MTX]; + + +/***************************************************************************** + * + * Miscellaneous globals + * + ****************************************************************************/ + + +ACPI_EXTERN struct acpi_memory_list acpi_gbl_memory_lists[ACPI_NUM_MEM_LISTS]; +ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_drv_notify; +ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_sys_notify; +ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; +ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; +ACPI_EXTERN acpi_handle acpi_gbl_global_lock_semaphore; + +ACPI_EXTERN u32 acpi_gbl_global_lock_thread_count; +ACPI_EXTERN u32 acpi_gbl_original_mode; +ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; +ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; +ACPI_EXTERN u32 acpi_gbl_ps_find_count; +ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; +ACPI_EXTERN u16 acpi_gbl_next_table_owner_id; +ACPI_EXTERN u16 acpi_gbl_next_method_owner_id; +ACPI_EXTERN u16 acpi_gbl_global_lock_handle; +ACPI_EXTERN u8 acpi_gbl_debugger_configuration; +ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; +ACPI_EXTERN u8 acpi_gbl_step_to_next_call; +ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; +ACPI_EXTERN u8 acpi_gbl_global_lock_present; +ACPI_EXTERN u8 acpi_gbl_events_initialized; + +extern u8 acpi_gbl_shutdown; +extern u32 acpi_gbl_startup_flags; +extern const u8 acpi_gbl_decode_to8bit[8]; +extern const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT]; +extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; +extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; + + +/***************************************************************************** + * + * Namespace globals + * + ****************************************************************************/ + +#define NUM_NS_TYPES ACPI_TYPE_INVALID+1 + +#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) +#define NUM_PREDEFINED_NAMES 10 +#else +#define NUM_PREDEFINED_NAMES 9 +#endif + +ACPI_EXTERN struct acpi_namespace_node acpi_gbl_root_node_struct; +ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node; + +extern const u8 acpi_gbl_ns_properties[NUM_NS_TYPES]; +extern const struct acpi_predefined_names acpi_gbl_pre_defined_names [NUM_PREDEFINED_NAMES]; + +#ifdef ACPI_DEBUG_OUTPUT +ACPI_EXTERN u32 acpi_gbl_current_node_count; +ACPI_EXTERN u32 acpi_gbl_current_node_size; +ACPI_EXTERN u32 acpi_gbl_max_concurrent_node_count; +ACPI_EXTERN acpi_size acpi_gbl_entry_stack_pointer; +ACPI_EXTERN acpi_size acpi_gbl_lowest_stack_pointer; +ACPI_EXTERN u32 acpi_gbl_deepest_nesting; +#endif + +/***************************************************************************** + * + * Interpreter globals + * + ****************************************************************************/ + + +ACPI_EXTERN struct acpi_thread_state *acpi_gbl_current_walk_list; + +/* Control method single step flag */ + +ACPI_EXTERN u8 acpi_gbl_cm_single_step; + + +/***************************************************************************** + * + * Parser globals + * + ****************************************************************************/ + +ACPI_EXTERN union acpi_parse_object *acpi_gbl_parsed_namespace_root; + +/***************************************************************************** + * + * Hardware globals + * + ****************************************************************************/ + +extern struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG]; +ACPI_EXTERN u8 acpi_gbl_sleep_type_a; +ACPI_EXTERN u8 acpi_gbl_sleep_type_b; + + +/***************************************************************************** + * + * Event and GPE globals + * + ****************************************************************************/ + +extern struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS]; +ACPI_EXTERN struct acpi_fixed_event_handler acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS]; + +ACPI_EXTERN acpi_handle acpi_gbl_gpe_obj_handle; +ACPI_EXTERN u32 acpi_gbl_gpe_register_count; +ACPI_EXTERN u32 acpi_gbl_gpe_number_max; +ACPI_EXTERN struct acpi_gpe_register_info *acpi_gbl_gpe_register_info; +ACPI_EXTERN struct acpi_gpe_number_info *acpi_gbl_gpe_number_info; +ACPI_EXTERN struct acpi_gpe_block_info acpi_gbl_gpe_block_info[ACPI_MAX_GPE_BLOCKS]; + +/* + * GPE translation table + * Indexed by the GPE number, returns a valid index into the global GPE tables. + * + * This table is needed because the GPE numbers supported by block 1 do not + * have to be contiguous with the GPE numbers supported by block 0. + */ +ACPI_EXTERN struct acpi_gpe_index_info *acpi_gbl_gpe_number_to_index; + + +/***************************************************************************** + * + * Debugger globals + * + ****************************************************************************/ + + +ACPI_EXTERN u8 acpi_gbl_db_output_flags; + +#ifdef ACPI_DISASSEMBLER + +ACPI_EXTERN u8 acpi_gbl_db_opt_disasm; +ACPI_EXTERN u8 acpi_gbl_db_opt_verbose; +#endif + + +#ifdef ACPI_DEBUGGER + +extern u8 acpi_gbl_method_executing; +extern u8 acpi_gbl_abort_method; +extern u8 acpi_gbl_db_terminate_threads; + +ACPI_EXTERN int optind; +ACPI_EXTERN char *optarg; + +ACPI_EXTERN u8 acpi_gbl_db_opt_tables; +ACPI_EXTERN u8 acpi_gbl_db_opt_stats; +ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; + + +ACPI_EXTERN char *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]; +ACPI_EXTERN char acpi_gbl_db_line_buf[80]; +ACPI_EXTERN char acpi_gbl_db_parsed_buf[80]; +ACPI_EXTERN char acpi_gbl_db_scope_buf[40]; +ACPI_EXTERN char acpi_gbl_db_debug_filename[40]; +ACPI_EXTERN u8 acpi_gbl_db_output_to_file; +ACPI_EXTERN char *acpi_gbl_db_buffer; +ACPI_EXTERN char *acpi_gbl_db_filename; +ACPI_EXTERN u32 acpi_gbl_db_debug_level; +ACPI_EXTERN u32 acpi_gbl_db_console_debug_level; +ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr; +ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node; + +/* + * Statistic globals + */ +ACPI_EXTERN u16 acpi_gbl_obj_type_count[ACPI_TYPE_NS_NODE_MAX+1]; +ACPI_EXTERN u16 acpi_gbl_node_type_count[ACPI_TYPE_NS_NODE_MAX+1]; +ACPI_EXTERN u16 acpi_gbl_obj_type_count_misc; +ACPI_EXTERN u16 acpi_gbl_node_type_count_misc; +ACPI_EXTERN u32 acpi_gbl_num_nodes; +ACPI_EXTERN u32 acpi_gbl_num_objects; + + +ACPI_EXTERN u32 acpi_gbl_size_of_parse_tree; +ACPI_EXTERN u32 acpi_gbl_size_of_method_trees; +ACPI_EXTERN u32 acpi_gbl_size_of_node_entries; +ACPI_EXTERN u32 acpi_gbl_size_of_acpi_objects; + +#endif /* ACPI_DEBUGGER */ + + +#endif /* __ACGLOBAL_H__ */ diff -Nru a/include/acpi/achware.h b/include/acpi/achware.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/achware.h Sun Feb 9 21:13:33 2003 @@ -0,0 +1,154 @@ +/****************************************************************************** + * + * Name: achware.h -- hardware specific interfaces + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACHWARE_H__ +#define __ACHWARE_H__ + + +/* PM Timer ticks per second (HZ) */ +#define PM_TIMER_FREQUENCY 3579545 + + +/* Prototypes */ + + +acpi_status +acpi_hw_initialize ( + void); + +acpi_status +acpi_hw_shutdown ( + void); + +acpi_status +acpi_hw_initialize_system_info ( + void); + +acpi_status +acpi_hw_set_mode ( + u32 mode); + +u32 +acpi_hw_get_mode ( + void); + +u32 +acpi_hw_get_mode_capabilities ( + void); + +/* Register I/O Prototypes */ + +struct acpi_bit_register_info * +acpi_hw_get_bit_register_info ( + u32 register_id); + +acpi_status +acpi_hw_register_read ( + u8 use_lock, + u32 register_id, + u32 *return_value); + +acpi_status +acpi_hw_register_write ( + u8 use_lock, + u32 register_id, + u32 value); + +acpi_status +acpi_hw_low_level_read ( + u32 width, + u32 *value, + struct acpi_generic_address *reg, + u32 offset); + +acpi_status +acpi_hw_low_level_write ( + u32 width, + u32 value, + struct acpi_generic_address *reg, + u32 offset); + +acpi_status +acpi_hw_clear_acpi_status ( + void); + + +/* GPE support */ + +u8 +acpi_hw_get_gpe_bit_mask ( + u32 gpe_number); + +acpi_status +acpi_hw_enable_gpe ( + u32 gpe_number); + +void +acpi_hw_enable_gpe_for_wakeup ( + u32 gpe_number); + +acpi_status +acpi_hw_disable_gpe ( + u32 gpe_number); + +void +acpi_hw_disable_gpe_for_wakeup ( + u32 gpe_number); + +acpi_status +acpi_hw_clear_gpe ( + u32 gpe_number); + +acpi_status +acpi_hw_get_gpe_status ( + u32 gpe_number, + acpi_event_status *event_status); + +acpi_status +acpi_hw_disable_non_wakeup_gpes ( + void); + +acpi_status +acpi_hw_enable_non_wakeup_gpes ( + void); + + +/* ACPI Timer prototypes */ + +acpi_status +acpi_get_timer_resolution ( + u32 *resolution); + +acpi_status +acpi_get_timer ( + u32 *ticks); + +acpi_status +acpi_get_timer_duration ( + u32 start_ticks, + u32 end_ticks, + u32 *time_elapsed); + + +#endif /* __ACHWARE_H__ */ diff -Nru a/include/acpi/acinterp.h b/include/acpi/acinterp.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acinterp.h Sun Feb 9 21:13:35 2003 @@ -0,0 +1,717 @@ +/****************************************************************************** + * + * Name: acinterp.h - Interpreter subcomponent prototypes and defines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACINTERP_H__ +#define __ACINTERP_H__ + + +#define ACPI_WALK_OPERANDS (&(walk_state->operands [walk_state->num_operands -1])) + + +acpi_status +acpi_ex_resolve_operands ( + u16 opcode, + union acpi_operand_object **stack_ptr, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_check_object_type ( + acpi_object_type type_needed, + acpi_object_type this_type, + void *object); + +/* + * exxface - External interpreter interfaces + */ + +acpi_status +acpi_ex_load_table ( + acpi_table_type table_id); + +acpi_status +acpi_ex_execute_method ( + struct acpi_namespace_node *method_node, + union acpi_operand_object **params, + union acpi_operand_object **return_obj_desc); + + +/* + * exconvrt - object conversion + */ + +acpi_status +acpi_ex_convert_to_integer ( + union acpi_operand_object *obj_desc, + union acpi_operand_object **result_desc, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_convert_to_buffer ( + union acpi_operand_object *obj_desc, + union acpi_operand_object **result_desc, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_convert_to_string ( + union acpi_operand_object *obj_desc, + union acpi_operand_object **result_desc, + u32 base, + u32 max_length, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_convert_to_target_type ( + acpi_object_type destination_type, + union acpi_operand_object *source_desc, + union acpi_operand_object **result_desc, + struct acpi_walk_state *walk_state); + +u32 +acpi_ex_convert_to_ascii ( + acpi_integer integer, + u32 base, + u8 *string, + u8 max_length); + +/* + * exfield - ACPI AML (p-code) execution - field manipulation + */ + +acpi_status +acpi_ex_extract_from_field ( + union acpi_operand_object *obj_desc, + void *buffer, + u32 buffer_length); + +acpi_status +acpi_ex_insert_into_field ( + union acpi_operand_object *obj_desc, + void *buffer, + u32 buffer_length); + +acpi_status +acpi_ex_setup_region ( + union acpi_operand_object *obj_desc, + u32 field_datum_byte_offset); + +acpi_status +acpi_ex_access_region ( + union acpi_operand_object *obj_desc, + u32 field_datum_byte_offset, + acpi_integer *value, + u32 read_write); + +u8 +acpi_ex_register_overflow ( + union acpi_operand_object *obj_desc, + acpi_integer value); + +acpi_status +acpi_ex_field_datum_io ( + union acpi_operand_object *obj_desc, + u32 field_datum_byte_offset, + acpi_integer *value, + u32 read_write); + +acpi_status +acpi_ex_write_with_update_rule ( + union acpi_operand_object *obj_desc, + acpi_integer mask, + acpi_integer field_value, + u32 field_datum_byte_offset); + +void +acpi_ex_get_buffer_datum( + acpi_integer *datum, + void *buffer, + u32 byte_granularity, + u32 offset); + +void +acpi_ex_set_buffer_datum ( + acpi_integer merged_datum, + void *buffer, + u32 byte_granularity, + u32 offset); + +acpi_status +acpi_ex_read_data_from_field ( + struct acpi_walk_state *walk_state, + union acpi_operand_object *obj_desc, + union acpi_operand_object **ret_buffer_desc); + +acpi_status +acpi_ex_write_data_to_field ( + union acpi_operand_object *source_desc, + union acpi_operand_object *obj_desc, + union acpi_operand_object **result_desc); + +/* + * exmisc - ACPI AML (p-code) execution - specific opcodes + */ + +acpi_status +acpi_ex_opcode_3A_0T_0R ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_opcode_3A_1T_1R ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_opcode_6A_0T_1R ( + struct acpi_walk_state *walk_state); + +u8 +acpi_ex_do_match ( + u32 match_op, + acpi_integer package_value, + acpi_integer match_value); + +acpi_status +acpi_ex_get_object_reference ( + union acpi_operand_object *obj_desc, + union acpi_operand_object **return_desc, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_resolve_multiple ( + struct acpi_walk_state *walk_state, + union acpi_operand_object *operand, + acpi_object_type *return_type, + union acpi_operand_object **return_desc); + +acpi_status +acpi_ex_concat_template ( + union acpi_operand_object *obj_desc, + union acpi_operand_object *obj_desc2, + union acpi_operand_object **actual_return_desc, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_do_concatenate ( + union acpi_operand_object *obj_desc, + union acpi_operand_object *obj_desc2, + union acpi_operand_object **actual_return_desc, + struct acpi_walk_state *walk_state); + +u8 +acpi_ex_do_logical_op ( + u16 opcode, + acpi_integer operand0, + acpi_integer operand1); + +acpi_integer +acpi_ex_do_math_op ( + u16 opcode, + acpi_integer operand0, + acpi_integer operand1); + +acpi_status +acpi_ex_create_mutex ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_create_processor ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_create_power_resource ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_create_region ( + u8 *aml_start, + u32 aml_length, + u8 region_space, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_create_table_region ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_create_event ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_create_alias ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_create_method ( + u8 *aml_start, + u32 aml_length, + struct acpi_walk_state *walk_state); + + +/* + * exconfig - dynamic table load/unload + */ + +acpi_status +acpi_ex_add_table ( + struct acpi_table_header *table, + struct acpi_namespace_node *parent_node, + union acpi_operand_object **ddb_handle); + +acpi_status +acpi_ex_load_op ( + union acpi_operand_object *obj_desc, + union acpi_operand_object *target, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_load_table_op ( + struct acpi_walk_state *walk_state, + union acpi_operand_object **return_desc); + +acpi_status +acpi_ex_unload_table ( + union acpi_operand_object *ddb_handle); + + +/* + * exmutex - mutex support + */ + +acpi_status +acpi_ex_acquire_mutex ( + union acpi_operand_object *time_desc, + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_release_mutex ( + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state); + +void +acpi_ex_release_all_mutexes ( + struct acpi_thread_state *thread); + +void +acpi_ex_unlink_mutex ( + union acpi_operand_object *obj_desc); + +void +acpi_ex_link_mutex ( + union acpi_operand_object *obj_desc, + struct acpi_thread_state *thread); + +/* + * exprep - ACPI AML (p-code) execution - prep utilities + */ + +acpi_status +acpi_ex_prep_common_field_object ( + union acpi_operand_object *obj_desc, + u8 field_flags, + u8 field_attribute, + u32 field_bit_position, + u32 field_bit_length); + +acpi_status +acpi_ex_prep_field_value ( + struct acpi_create_field_info *info); + +/* + * exsystem - Interface to OS services + */ + +acpi_status +acpi_ex_system_do_notify_op ( + union acpi_operand_object *value, + union acpi_operand_object *obj_desc); + +acpi_status +acpi_ex_system_do_suspend( + u32 time); + +acpi_status +acpi_ex_system_do_stall ( + u32 time); + +acpi_status +acpi_ex_system_acquire_mutex( + union acpi_operand_object *time, + union acpi_operand_object *obj_desc); + +acpi_status +acpi_ex_system_release_mutex( + union acpi_operand_object *obj_desc); + +acpi_status +acpi_ex_system_signal_event( + union acpi_operand_object *obj_desc); + +acpi_status +acpi_ex_system_wait_event( + union acpi_operand_object *time, + union acpi_operand_object *obj_desc); + +acpi_status +acpi_ex_system_reset_event( + union acpi_operand_object *obj_desc); + +acpi_status +acpi_ex_system_wait_semaphore ( + acpi_handle semaphore, + u16 timeout); + + +/* + * exmonadic - ACPI AML (p-code) execution, monadic operators + */ + +acpi_status +acpi_ex_opcode_1A_0T_0R ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_opcode_1A_0T_1R ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_opcode_1A_1T_1R ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_opcode_1A_1T_0R ( + struct acpi_walk_state *walk_state); + +/* + * exdyadic - ACPI AML (p-code) execution, dyadic operators + */ + +acpi_status +acpi_ex_opcode_2A_0T_0R ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_opcode_2A_0T_1R ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_opcode_2A_1T_1R ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_opcode_2A_2T_1R ( + struct acpi_walk_state *walk_state); + + +/* + * exresolv - Object resolution and get value functions + */ + +acpi_status +acpi_ex_resolve_to_value ( + union acpi_operand_object **stack_ptr, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_resolve_node_to_value ( + struct acpi_namespace_node **stack_ptr, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_resolve_object_to_value ( + union acpi_operand_object **stack_ptr, + struct acpi_walk_state *walk_state); + + +/* + * exdump - Scanner debug output routines + */ + +void +acpi_ex_dump_operand ( + union acpi_operand_object *entry_desc); + +void +acpi_ex_dump_operands ( + union acpi_operand_object **operands, + acpi_interpreter_mode interpreter_mode, + char *ident, + u32 num_levels, + char *note, + char *module_name, + u32 line_number); + +void +acpi_ex_dump_object_descriptor ( + union acpi_operand_object *object, + u32 flags); + +void +acpi_ex_dump_node ( + struct acpi_namespace_node *node, + u32 flags); + +void +acpi_ex_out_string ( + char *title, + char *value); + +void +acpi_ex_out_pointer ( + char *title, + void *value); + +void +acpi_ex_out_integer ( + char *title, + u32 value); + +void +acpi_ex_out_address ( + char *title, + acpi_physical_address value); + + +/* + * exnames - interpreter/scanner name load/execute + */ + +char * +acpi_ex_allocate_name_string ( + u32 prefix_count, + u32 num_name_segs); + +u32 +acpi_ex_good_char ( + u32 character); + +acpi_status +acpi_ex_name_segment ( + u8 **in_aml_address, + char *name_string); + +acpi_status +acpi_ex_get_name_string ( + acpi_object_type data_type, + u8 *in_aml_address, + char **out_name_string, + u32 *out_name_length); + +acpi_status +acpi_ex_do_name ( + acpi_object_type data_type, + acpi_interpreter_mode load_exec_mode); + + +/* + * exstore - Object store support + */ + +acpi_status +acpi_ex_store ( + union acpi_operand_object *val_desc, + union acpi_operand_object *dest_desc, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_store_object_to_index ( + union acpi_operand_object *val_desc, + union acpi_operand_object *dest_desc, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_store_object_to_node ( + union acpi_operand_object *source_desc, + struct acpi_namespace_node *node, + struct acpi_walk_state *walk_state); + + +/* + * exstoren + */ + +acpi_status +acpi_ex_resolve_object ( + union acpi_operand_object **source_desc_ptr, + acpi_object_type target_type, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ex_store_object_to_object ( + union acpi_operand_object *source_desc, + union acpi_operand_object *dest_desc, + union acpi_operand_object **new_desc, + struct acpi_walk_state *walk_state); + + +/* + * excopy - object copy + */ + +acpi_status +acpi_ex_store_buffer_to_buffer ( + union acpi_operand_object *source_desc, + union acpi_operand_object *target_desc); + +acpi_status +acpi_ex_store_string_to_string ( + union acpi_operand_object *source_desc, + union acpi_operand_object *target_desc); + +acpi_status +acpi_ex_copy_integer_to_index_field ( + union acpi_operand_object *source_desc, + union acpi_operand_object *target_desc); + +acpi_status +acpi_ex_copy_integer_to_bank_field ( + union acpi_operand_object *source_desc, + union acpi_operand_object *target_desc); + +acpi_status +acpi_ex_copy_data_to_named_field ( + union acpi_operand_object *source_desc, + struct acpi_namespace_node *node); + +acpi_status +acpi_ex_copy_integer_to_buffer_field ( + union acpi_operand_object *source_desc, + union acpi_operand_object *target_desc); + +/* + * exutils - interpreter/scanner utilities + */ + +acpi_status +acpi_ex_enter_interpreter ( + void); + +void +acpi_ex_exit_interpreter ( + void); + +void +acpi_ex_truncate_for32bit_table ( + union acpi_operand_object *obj_desc); + +u8 +acpi_ex_acquire_global_lock ( + u32 rule); + +void +acpi_ex_release_global_lock ( + u8 locked); + +u32 +acpi_ex_digits_needed ( + acpi_integer value, + u32 base); + +void +acpi_ex_eisa_id_to_string ( + u32 numeric_id, + char *out_string); + +void +acpi_ex_unsigned_integer_to_string ( + acpi_integer value, + char *out_string); + + +/* + * exregion - default op_region handlers + */ + +acpi_status +acpi_ex_system_memory_space_handler ( + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context); + +acpi_status +acpi_ex_system_io_space_handler ( + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context); + +acpi_status +acpi_ex_pci_config_space_handler ( + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context); + +acpi_status +acpi_ex_cmos_space_handler ( + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context); + +acpi_status +acpi_ex_pci_bar_space_handler ( + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context); + +acpi_status +acpi_ex_embedded_controller_space_handler ( + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context); + +acpi_status +acpi_ex_sm_bus_space_handler ( + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context); + + +acpi_status +acpi_ex_data_table_space_handler ( + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context); + +#endif /* __INTERP_H__ */ diff -Nru a/include/acpi/aclocal.h b/include/acpi/aclocal.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/aclocal.h Sun Feb 9 21:13:33 2003 @@ -0,0 +1,953 @@ +/****************************************************************************** + * + * Name: aclocal.h - Internal data types used across the ACPI subsystem + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACLOCAL_H__ +#define __ACLOCAL_H__ + + +#define ACPI_WAIT_FOREVER 0xFFFF /* u16, as per ACPI spec */ + +typedef void * acpi_mutex; +typedef u32 acpi_mutex_handle; + + +/* Total number of aml opcodes defined */ + +#define AML_NUM_OPCODES 0x7E + + +/***************************************************************************** + * + * Mutex typedefs and structs + * + ****************************************************************************/ + + +/* + * Predefined handles for the mutex objects used within the subsystem + * All mutex objects are automatically created by acpi_ut_mutex_initialize. + * + * The acquire/release ordering protocol is implied via this list. Mutexes + * with a lower value must be acquired before mutexes with a higher value. + * + * NOTE: any changes here must be reflected in the acpi_gbl_mutex_names table also! + */ + +#define ACPI_MTX_EXECUTE 0 +#define ACPI_MTX_INTERPRETER 1 +#define ACPI_MTX_PARSER 2 +#define ACPI_MTX_DISPATCHER 3 +#define ACPI_MTX_TABLES 4 +#define ACPI_MTX_OP_REGIONS 5 +#define ACPI_MTX_NAMESPACE 6 +#define ACPI_MTX_EVENTS 7 +#define ACPI_MTX_HARDWARE 8 +#define ACPI_MTX_CACHES 9 +#define ACPI_MTX_MEMORY 10 +#define ACPI_MTX_DEBUG_CMD_COMPLETE 11 +#define ACPI_MTX_DEBUG_CMD_READY 12 + +#define MAX_MTX 12 +#define NUM_MTX MAX_MTX+1 + + +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) +#ifdef DEFINE_ACPI_GLOBALS + +/* Names for the mutexes used in the subsystem */ + +static char *acpi_gbl_mutex_names[] = +{ + "ACPI_MTX_Execute", + "ACPI_MTX_Interpreter", + "ACPI_MTX_Parser", + "ACPI_MTX_Dispatcher", + "ACPI_MTX_Tables", + "ACPI_MTX_op_regions", + "ACPI_MTX_Namespace", + "ACPI_MTX_Events", + "ACPI_MTX_Hardware", + "ACPI_MTX_Caches", + "ACPI_MTX_Memory", + "ACPI_MTX_debug_cmd_complete", + "ACPI_MTX_debug_cmd_ready", +}; + +#endif +#endif + + +/* Table for the global mutexes */ + +struct acpi_mutex_info +{ + acpi_mutex mutex; + u32 use_count; + u32 owner_id; +}; + +/* This owner ID means that the mutex is not in use (unlocked) */ + +#define ACPI_MUTEX_NOT_ACQUIRED (u32) (-1) + + +/* Lock flag parameter for various interfaces */ + +#define ACPI_MTX_DO_NOT_LOCK 0 +#define ACPI_MTX_LOCK 1 + + +typedef u16 acpi_owner_id; +#define ACPI_OWNER_TYPE_TABLE 0x0 +#define ACPI_OWNER_TYPE_METHOD 0x1 +#define ACPI_FIRST_METHOD_ID 0x0000 +#define ACPI_FIRST_TABLE_ID 0x8000 + +/* TBD: [Restructure] get rid of the need for this! */ + +#define TABLE_ID_DSDT (acpi_owner_id) 0x8000 + + +/* Field access granularities */ + +#define ACPI_FIELD_BYTE_GRANULARITY 1 +#define ACPI_FIELD_WORD_GRANULARITY 2 +#define ACPI_FIELD_DWORD_GRANULARITY 4 +#define ACPI_FIELD_QWORD_GRANULARITY 8 + +/***************************************************************************** + * + * Namespace typedefs and structs + * + ****************************************************************************/ + + +/* Operational modes of the AML interpreter/scanner */ + +typedef enum +{ + ACPI_IMODE_LOAD_PASS1 = 0x01, + ACPI_IMODE_LOAD_PASS2 = 0x02, + ACPI_IMODE_EXECUTE = 0x0E + +} acpi_interpreter_mode; + + +/* + * The Node describes a named object that appears in the AML + * An acpi_node is used to store Nodes. + * + * data_type is used to differentiate between internal descriptors, and MUST + * be the first byte in this structure. + */ + +union acpi_name_union +{ + u32 integer; + char ascii[4]; +}; + +struct acpi_namespace_node +{ + u8 descriptor; /* Used to differentiate object descriptor types */ + u8 type; /* Type associated with this name */ + u16 owner_id; + union acpi_name_union name; /* ACPI Name, always 4 chars per ACPI spec */ + + + union acpi_operand_object *object; /* Pointer to attached ACPI object (optional) */ + struct acpi_namespace_node *child; /* first child */ + struct acpi_namespace_node *peer; /* Next peer*/ + u16 reference_count; /* Current count of references and children */ + u8 flags; +}; + + +#define ACPI_ENTRY_NOT_FOUND NULL + + +/* Node flags */ + +#define ANOBJ_RESERVED 0x01 +#define ANOBJ_END_OF_PEER_LIST 0x02 +#define ANOBJ_DATA_WIDTH_32 0x04 /* Parent table is 64-bits */ +#define ANOBJ_METHOD_ARG 0x08 +#define ANOBJ_METHOD_LOCAL 0x10 +#define ANOBJ_METHOD_NO_RETVAL 0x20 +#define ANOBJ_METHOD_SOME_NO_RETVAL 0x40 + +#define ANOBJ_IS_BIT_OFFSET 0x80 + + +/* + * ACPI Table Descriptor. One per ACPI table + */ +struct acpi_table_desc +{ + struct acpi_table_desc *prev; + struct acpi_table_desc *next; + struct acpi_table_desc *installed_desc; + struct acpi_table_header *pointer; + u8 *aml_start; + u64 physical_address; + u32 aml_length; + acpi_size length; + u32 count; + acpi_owner_id table_id; + u8 type; + u8 allocation; + u8 loaded_into_namespace; +}; + + +struct acpi_find_context +{ + char *search_for; + acpi_handle *list; + u32 *count; +}; + + +struct acpi_ns_search_data +{ + struct acpi_namespace_node *node; +}; + + +/* + * Predefined Namespace items + */ +struct acpi_predefined_names +{ + char *name; + u8 type; + char *val; +}; + + +/* Object types used during package copies */ + + +#define ACPI_COPY_TYPE_SIMPLE 0 +#define ACPI_COPY_TYPE_PACKAGE 1 + +/* Info structure used to convert external<->internal namestrings */ + +struct acpi_namestring_info +{ + char *external_name; + char *next_external_char; + char *internal_name; + u32 length; + u32 num_segments; + u32 num_carats; + u8 fully_qualified; +}; + + +/* Field creation info */ + +struct acpi_create_field_info +{ + struct acpi_namespace_node *region_node; + struct acpi_namespace_node *field_node; + struct acpi_namespace_node *register_node; + struct acpi_namespace_node *data_register_node; + u32 bank_value; + u32 field_bit_position; + u32 field_bit_length; + u8 field_flags; + u8 attribute; + u8 field_type; +}; + + +/***************************************************************************** + * + * Event typedefs and structs + * + ****************************************************************************/ + +/* Information about each GPE register block */ + +struct acpi_gpe_block_info +{ + struct acpi_generic_address *block_address; + u16 register_count; + u8 block_base_number; +}; + +/* Information about a particular GPE register pair */ + +struct acpi_gpe_register_info +{ + struct acpi_generic_address status_address; /* Address of status reg */ + struct acpi_generic_address enable_address; /* Address of enable reg */ + u8 status; /* Current value of status reg */ + u8 enable; /* Current value of enable reg */ + u8 wake_enable; /* Mask of bits to keep enabled when sleeping */ + u8 base_gpe_number; /* Base GPE number for this register */ +}; + + +#define ACPI_GPE_LEVEL_TRIGGERED 1 +#define ACPI_GPE_EDGE_TRIGGERED 2 + + +/* Information about each particular GPE level */ + +struct acpi_gpe_number_info +{ + struct acpi_namespace_node *method_node; /* Method node for this GPE level */ + acpi_gpe_handler handler; /* Address of handler, if any */ + void *context; /* Context to be passed to handler */ + u8 type; /* Level or Edge */ + u8 bit_mask; +}; + + +struct acpi_gpe_index_info +{ + u8 number_index; +}; + +/* Information about each particular fixed event */ + +struct acpi_fixed_event_handler +{ + acpi_event_handler handler; /* Address of handler. */ + void *context; /* Context to be passed to handler */ +}; + + +struct acpi_fixed_event_info +{ + u8 status_register_id; + u8 enable_register_id; + u16 status_bit_mask; + u16 enable_bit_mask; +}; + +/* Information used during field processing */ + +struct acpi_field_info +{ + u8 skip_field; + u8 field_flag; + u32 pkg_length; +}; + + +/***************************************************************************** + * + * Generic "state" object for stacks + * + ****************************************************************************/ + + +#define ACPI_CONTROL_NORMAL 0xC0 +#define ACPI_CONTROL_CONDITIONAL_EXECUTING 0xC1 +#define ACPI_CONTROL_PREDICATE_EXECUTING 0xC2 +#define ACPI_CONTROL_PREDICATE_FALSE 0xC3 +#define ACPI_CONTROL_PREDICATE_TRUE 0xC4 + + +/* Forward declarations */ +struct acpi_walk_state ; +struct acpi_obj_mutex; +union acpi_parse_object ; + + +#define ACPI_STATE_COMMON /* Two 32-bit fields and a pointer */\ + u8 data_type; /* To differentiate various internal objs */\ + u8 flags; \ + u16 value; \ + u16 state; \ + u16 reserved; \ + void *next; \ + +struct acpi_common_state +{ + ACPI_STATE_COMMON +}; + + +/* + * Update state - used to traverse complex objects such as packages + */ +struct acpi_update_state +{ + ACPI_STATE_COMMON + union acpi_operand_object *object; +}; + + +/* + * Pkg state - used to traverse nested package structures + */ +struct acpi_pkg_state +{ + ACPI_STATE_COMMON + union acpi_operand_object *source_object; + union acpi_operand_object *dest_object; + struct acpi_walk_state *walk_state; + void *this_target_obj; + u32 num_packages; + u16 index; +}; + + +/* + * Control state - one per if/else and while constructs. + * Allows nesting of these constructs + */ +struct acpi_control_state +{ + ACPI_STATE_COMMON + union acpi_parse_object *predicate_op; + u8 *aml_predicate_start; /* Start of if/while predicate */ + u8 *package_end; /* End of if/while block */ + u16 opcode; +}; + + +/* + * Scope state - current scope during namespace lookups + */ +struct acpi_scope_state +{ + ACPI_STATE_COMMON + struct acpi_namespace_node *node; +}; + + +struct acpi_pscope_state +{ + ACPI_STATE_COMMON + union acpi_parse_object *op; /* current op being parsed */ + u8 *arg_end; /* current argument end */ + u8 *pkg_end; /* current package end */ + u32 arg_list; /* next argument to parse */ + u32 arg_count; /* Number of fixed arguments */ +}; + + +/* + * Thread state - one per thread across multiple walk states. Multiple walk + * states are created when there are nested control methods executing. + */ +struct acpi_thread_state +{ + ACPI_STATE_COMMON + struct acpi_walk_state *walk_state_list; /* Head of list of walk_states for this thread */ + union acpi_operand_object *acquired_mutex_list; /* List of all currently acquired mutexes */ + u32 thread_id; /* Running thread ID */ + u16 current_sync_level; /* Mutex Sync (nested acquire) level */ +}; + + +/* + * Result values - used to accumulate the results of nested + * AML arguments + */ +struct acpi_result_values +{ + ACPI_STATE_COMMON + union acpi_operand_object *obj_desc [ACPI_OBJ_NUM_OPERANDS]; + u8 num_results; + u8 last_insert; +}; + + +typedef +acpi_status (*acpi_parse_downwards) ( + struct acpi_walk_state *walk_state, + union acpi_parse_object **out_op); + +typedef +acpi_status (*acpi_parse_upwards) ( + struct acpi_walk_state *walk_state); + + +/* + * Notify info - used to pass info to the deferred notify + * handler/dispatcher. + */ +struct acpi_notify_info +{ + ACPI_STATE_COMMON + struct acpi_namespace_node *node; + union acpi_operand_object *handler_obj; +}; + + +/* Generic state is union of structs above */ + +union acpi_generic_state +{ + struct acpi_common_state common; + struct acpi_control_state control; + struct acpi_update_state update; + struct acpi_scope_state scope; + struct acpi_pscope_state parse_scope; + struct acpi_pkg_state pkg; + struct acpi_thread_state thread; + struct acpi_result_values results; + struct acpi_notify_info notify; +}; + + +/***************************************************************************** + * + * Interpreter typedefs and structs + * + ****************************************************************************/ + +typedef +acpi_status (*ACPI_EXECUTE_OP) ( + struct acpi_walk_state *walk_state); + + +/***************************************************************************** + * + * Parser typedefs and structs + * + ****************************************************************************/ + +/* + * AML opcode, name, and argument layout + */ +struct acpi_opcode_info +{ +#if defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUG_OUTPUT) + char *name; /* Opcode name (disassembler/debug only) */ +#endif + u32 parse_args; /* Grammar/Parse time arguments */ + u32 runtime_args; /* Interpret time arguments */ + u32 flags; /* Misc flags */ + u8 object_type; /* Corresponding internal object type */ + u8 class; /* Opcode class */ + u8 type; /* Opcode type */ +}; + + +union acpi_parse_value +{ + acpi_integer integer; /* integer constant (Up to 64 bits) */ + struct uint64_struct integer64; /* Structure overlay for 2 32-bit Dwords */ + u32 integer32; /* integer constant, 32 bits only */ + u16 integer16; /* integer constant, 16 bits only */ + u8 integer8; /* integer constant, 8 bits only */ + u32 size; /* bytelist or field size */ + char *string; /* NULL terminated string */ + u8 *buffer; /* buffer or string */ + char *name; /* NULL terminated string */ + union acpi_parse_object *arg; /* arguments and contained ops */ +}; + + +#define ACPI_PARSE_COMMON \ + u8 data_type; /* To differentiate various internal objs */\ + u8 flags; /* Type of Op */\ + u16 aml_opcode; /* AML opcode */\ + u32 aml_offset; /* offset of declaration in AML */\ + union acpi_parse_object *parent; /* parent op */\ + union acpi_parse_object *next; /* next op */\ + ACPI_DISASM_ONLY_MEMBERS (\ + u8 disasm_flags; /* Used during AML disassembly */\ + u8 disasm_opcode; /* Subtype used for disassembly */\ + char aml_op_name[16]) /* op name (debug only) */\ + /* NON-DEBUG members below: */\ + struct acpi_namespace_node *node; /* for use by interpreter */\ + union acpi_parse_value value; /* Value or args associated with the opcode */\ + + +#define ACPI_DASM_BUFFER 0x00 +#define ACPI_DASM_RESOURCE 0x01 +#define ACPI_DASM_STRING 0x02 +#define ACPI_DASM_UNICODE 0x03 +#define ACPI_DASM_EISAID 0x04 +#define ACPI_DASM_MATCHOP 0x05 + +/* + * generic operation (for example: If, While, Store) + */ +struct acpi_parse_obj_common +{ + ACPI_PARSE_COMMON +}; + + +/* + * Extended Op for named ops (Scope, Method, etc.), deferred ops (Methods and op_regions), + * and bytelists. + */ +struct acpi_parse_obj_named +{ + ACPI_PARSE_COMMON + u8 *path; + u8 *data; /* AML body or bytelist data */ + u32 length; /* AML length */ + u32 name; /* 4-byte name or zero if no name */ +}; + + +/* The parse node is the fundamental element of the parse tree */ + +struct acpi_parse_obj_asl +{ + ACPI_PARSE_COMMON + union acpi_parse_object *child; + union acpi_parse_object *parent_method; + char *filename; + char *external_name; + char *namepath; + char name_seg[4]; + u32 extra_value; + u32 column; + u32 line_number; + u32 logical_line_number; + u32 logical_byte_offset; + u32 end_line; + u32 end_logical_line; + u32 acpi_btype; + u32 aml_length; + u32 aml_subtree_length; + u32 final_aml_length; + u32 final_aml_offset; + u32 compile_flags; + u16 parse_opcode; + u8 aml_opcode_length; + u8 aml_pkg_len_bytes; + u8 extra; + char parse_op_name[12]; +}; + + +union acpi_parse_object +{ + struct acpi_parse_obj_common common; + struct acpi_parse_obj_named named; + struct acpi_parse_obj_asl asl; +}; + + +/* + * Parse state - one state per parser invocation and each control + * method. + */ +struct acpi_parse_state +{ + u32 aml_size; + u8 *aml_start; /* first AML byte */ + u8 *aml; /* next AML byte */ + u8 *aml_end; /* (last + 1) AML byte */ + u8 *pkg_start; /* current package begin */ + u8 *pkg_end; /* current package end */ + union acpi_parse_object *start_op; /* root of parse tree */ + struct acpi_namespace_node *start_node; + union acpi_generic_state *scope; /* current scope */ + union acpi_parse_object *start_scope; +}; + + +/* Parse object flags */ + +#define ACPI_PARSEOP_GENERIC 0x01 +#define ACPI_PARSEOP_NAMED 0x02 +#define ACPI_PARSEOP_DEFERRED 0x04 +#define ACPI_PARSEOP_BYTELIST 0x08 +#define ACPI_PARSEOP_IN_CACHE 0x80 + +/* Parse object disasm_flags */ + +#define ACPI_PARSEOP_IGNORE 0x01 +#define ACPI_PARSEOP_PARAMLIST 0x02 +#define ACPI_PARSEOP_EMPTY_TERMLIST 0x04 +#define ACPI_PARSEOP_SPECIAL 0x10 + + +/***************************************************************************** + * + * Hardware (ACPI registers) and PNP + * + ****************************************************************************/ + +#define PCI_ROOT_HID_STRING "PNP0A03" + +struct acpi_bit_register_info +{ + u8 parent_register; + u8 bit_position; + u16 access_bit_mask; +}; + + +/* + * Register IDs + * These are the full ACPI registers + */ +#define ACPI_REGISTER_PM1_STATUS 0x01 +#define ACPI_REGISTER_PM1_ENABLE 0x02 +#define ACPI_REGISTER_PM1_CONTROL 0x03 +#define ACPI_REGISTER_PM1A_CONTROL 0x04 +#define ACPI_REGISTER_PM1B_CONTROL 0x05 +#define ACPI_REGISTER_PM2_CONTROL 0x06 +#define ACPI_REGISTER_PM_TIMER 0x07 +#define ACPI_REGISTER_PROCESSOR_BLOCK 0x08 +#define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x09 + + +/* Masks used to access the bit_registers */ + +#define ACPI_BITMASK_TIMER_STATUS 0x0001 +#define ACPI_BITMASK_BUS_MASTER_STATUS 0x0010 +#define ACPI_BITMASK_GLOBAL_LOCK_STATUS 0x0020 +#define ACPI_BITMASK_POWER_BUTTON_STATUS 0x0100 +#define ACPI_BITMASK_SLEEP_BUTTON_STATUS 0x0200 +#define ACPI_BITMASK_RT_CLOCK_STATUS 0x0400 +#define ACPI_BITMASK_WAKE_STATUS 0x8000 + +#define ACPI_BITMASK_ALL_FIXED_STATUS (ACPI_BITMASK_TIMER_STATUS | \ + ACPI_BITMASK_BUS_MASTER_STATUS | \ + ACPI_BITMASK_GLOBAL_LOCK_STATUS | \ + ACPI_BITMASK_POWER_BUTTON_STATUS | \ + ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ + ACPI_BITMASK_RT_CLOCK_STATUS | \ + ACPI_BITMASK_WAKE_STATUS) + +#define ACPI_BITMASK_TIMER_ENABLE 0x0001 +#define ACPI_BITMASK_GLOBAL_LOCK_ENABLE 0x0020 +#define ACPI_BITMASK_POWER_BUTTON_ENABLE 0x0100 +#define ACPI_BITMASK_SLEEP_BUTTON_ENABLE 0x0200 +#define ACPI_BITMASK_RT_CLOCK_ENABLE 0x0400 + +#define ACPI_BITMASK_SCI_ENABLE 0x0001 +#define ACPI_BITMASK_BUS_MASTER_RLD 0x0002 +#define ACPI_BITMASK_GLOBAL_LOCK_RELEASE 0x0004 +#define ACPI_BITMASK_SLEEP_TYPE_X 0x1C00 +#define ACPI_BITMASK_SLEEP_ENABLE 0x2000 + +#define ACPI_BITMASK_ARB_DISABLE 0x0001 + + +/* Raw bit position of each bit_register */ + +#define ACPI_BITPOSITION_TIMER_STATUS 0x00 +#define ACPI_BITPOSITION_BUS_MASTER_STATUS 0x04 +#define ACPI_BITPOSITION_GLOBAL_LOCK_STATUS 0x05 +#define ACPI_BITPOSITION_POWER_BUTTON_STATUS 0x08 +#define ACPI_BITPOSITION_SLEEP_BUTTON_STATUS 0x09 +#define ACPI_BITPOSITION_RT_CLOCK_STATUS 0x0A +#define ACPI_BITPOSITION_WAKE_STATUS 0x0F + +#define ACPI_BITPOSITION_TIMER_ENABLE 0x00 +#define ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE 0x05 +#define ACPI_BITPOSITION_POWER_BUTTON_ENABLE 0x08 +#define ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE 0x09 +#define ACPI_BITPOSITION_RT_CLOCK_ENABLE 0x0A + +#define ACPI_BITPOSITION_SCI_ENABLE 0x00 +#define ACPI_BITPOSITION_BUS_MASTER_RLD 0x01 +#define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE 0x02 +#define ACPI_BITPOSITION_SLEEP_TYPE_X 0x0A +#define ACPI_BITPOSITION_SLEEP_ENABLE 0x0D + +#define ACPI_BITPOSITION_ARB_DISABLE 0x00 + + +/***************************************************************************** + * + * Resource descriptors + * + ****************************************************************************/ + + +/* resource_type values */ + +#define ACPI_RESOURCE_TYPE_MEMORY_RANGE 0 +#define ACPI_RESOURCE_TYPE_IO_RANGE 1 +#define ACPI_RESOURCE_TYPE_BUS_NUMBER_RANGE 2 + +/* Resource descriptor types and masks */ + +#define ACPI_RDESC_TYPE_LARGE 0x80 +#define ACPI_RDESC_TYPE_SMALL 0x00 + +#define ACPI_RDESC_TYPE_MASK 0x80 +#define ACPI_RDESC_SMALL_MASK 0x78 /* Only bits 6:3 contain the type */ + + +/* + * Small resource descriptor types + * Note: The 3 length bits (2:0) must be zero + */ +#define ACPI_RDESC_TYPE_IRQ_FORMAT 0x20 +#define ACPI_RDESC_TYPE_DMA_FORMAT 0x28 +#define ACPI_RDESC_TYPE_START_DEPENDENT 0x30 +#define ACPI_RDESC_TYPE_END_DEPENDENT 0x38 +#define ACPI_RDESC_TYPE_IO_PORT 0x40 +#define ACPI_RDESC_TYPE_FIXED_IO_PORT 0x48 +#define ACPI_RDESC_TYPE_SMALL_VENDOR 0x70 +#define ACPI_RDESC_TYPE_END_TAG 0x78 + +/* + * Large resource descriptor types + */ + +#define ACPI_RDESC_TYPE_MEMORY_24 0x81 +#define ACPI_RDESC_TYPE_GENERAL_REGISTER 0x82 +#define ACPI_RDESC_TYPE_LARGE_VENDOR 0x84 +#define ACPI_RDESC_TYPE_MEMORY_32 0x85 +#define ACPI_RDESC_TYPE_FIXED_MEMORY_32 0x86 +#define ACPI_RDESC_TYPE_DWORD_ADDRESS_SPACE 0x87 +#define ACPI_RDESC_TYPE_WORD_ADDRESS_SPACE 0x88 +#define ACPI_RDESC_TYPE_EXTENDED_XRUPT 0x89 +#define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE 0x8A + + +/* String version of device HIDs and UIDs */ + +#define ACPI_DEVICE_ID_LENGTH 0x09 + +struct acpi_device_id +{ + char buffer[ACPI_DEVICE_ID_LENGTH]; +}; + + +/***************************************************************************** + * + * Miscellaneous + * + ****************************************************************************/ + +#define ACPI_ASCII_ZERO 0x30 + + +/***************************************************************************** + * + * Debugger + * + ****************************************************************************/ + +struct acpi_db_method_info +{ + acpi_handle thread_gate; + char *name; + char **args; + u32 flags; + u32 num_loops; + char pathname[128]; +}; + +struct acpi_integrity_info +{ + u32 nodes; + u32 objects; +}; + + +#define ACPI_DB_REDIRECTABLE_OUTPUT 0x01 +#define ACPI_DB_CONSOLE_OUTPUT 0x02 +#define ACPI_DB_DUPLICATE_OUTPUT 0x03 + + +/***************************************************************************** + * + * Debug + * + ****************************************************************************/ + +struct acpi_debug_print_info +{ + u32 component_id; + char *proc_name; + char *module_name; +}; + + +/* Entry for a memory allocation (debug only) */ + +#define ACPI_MEM_MALLOC 0 +#define ACPI_MEM_CALLOC 1 +#define ACPI_MAX_MODULE_NAME 16 + +#define ACPI_COMMON_DEBUG_MEM_HEADER \ + struct acpi_debug_mem_block *previous; \ + struct acpi_debug_mem_block *next; \ + u32 size; \ + u32 component; \ + u32 line; \ + char module[ACPI_MAX_MODULE_NAME]; \ + u8 alloc_type; + +struct acpi_debug_mem_header +{ + ACPI_COMMON_DEBUG_MEM_HEADER +}; + +struct acpi_debug_mem_block +{ + ACPI_COMMON_DEBUG_MEM_HEADER + u64 user_space; +}; + + +#define ACPI_MEM_LIST_GLOBAL 0 +#define ACPI_MEM_LIST_NSNODE 1 + +#define ACPI_MEM_LIST_FIRST_CACHE_LIST 2 +#define ACPI_MEM_LIST_STATE 2 +#define ACPI_MEM_LIST_PSNODE 3 +#define ACPI_MEM_LIST_PSNODE_EXT 4 +#define ACPI_MEM_LIST_OPERAND 5 +#define ACPI_MEM_LIST_WALK 6 +#define ACPI_MEM_LIST_MAX 6 +#define ACPI_NUM_MEM_LISTS 7 + + +struct acpi_memory_list +{ + void *list_head; + u16 link_offset; + u16 max_cache_depth; + u16 cache_depth; + u16 object_size; + +#ifdef ACPI_DBG_TRACK_ALLOCATIONS + + /* Statistics for debug memory tracking only */ + + u32 total_allocated; + u32 total_freed; + u32 current_total_size; + u32 cache_requests; + u32 cache_hits; + char *list_name; +#endif +}; + + +#endif /* __ACLOCAL_H__ */ diff -Nru a/include/acpi/acmacros.h b/include/acpi/acmacros.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acmacros.h Sun Feb 9 21:13:32 2003 @@ -0,0 +1,578 @@ +/****************************************************************************** + * + * Name: acmacros.h - C macros for the entire subsystem. + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACMACROS_H__ +#define __ACMACROS_H__ + + +/* + * Data manipulation macros + */ + +#define ACPI_LOWORD(l) ((u16)(u32)(l)) +#define ACPI_HIWORD(l) ((u16)((((u32)(l)) >> 16) & 0xFFFF)) +#define ACPI_LOBYTE(l) ((u8)(u16)(l)) +#define ACPI_HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF)) + + +#if ACPI_MACHINE_WIDTH == 16 + +/* + * For 16-bit addresses, we have to assume that the upper 32 bits + * are zero. + */ +#define ACPI_LODWORD(l) ((u32)(l)) +#define ACPI_HIDWORD(l) ((u32)(0)) + +#define ACPI_GET_ADDRESS(a) ((a).lo) +#define ACPI_STORE_ADDRESS(a,b) {(a).hi=0;(a).lo=(u32)(b);} +#define ACPI_VALID_ADDRESS(a) ((a).hi | (a).lo) + +#else +#ifdef ACPI_NO_INTEGER64_SUPPORT +/* + * acpi_integer is 32-bits, no 64-bit support on this platform + */ +#define ACPI_LODWORD(l) ((u32)(l)) +#define ACPI_HIDWORD(l) ((u32)(0)) + +#define ACPI_GET_ADDRESS(a) (a) +#define ACPI_STORE_ADDRESS(a,b) ((a)=(b)) +#define ACPI_VALID_ADDRESS(a) (a) + +#else + +/* + * Full 64-bit address/integer on both 32-bit and 64-bit platforms + */ +#define ACPI_LODWORD(l) ((u32)(u64)(l)) +#define ACPI_HIDWORD(l) ((u32)(((*(struct uint64_struct *)(void *)(&l))).hi)) + +#define ACPI_GET_ADDRESS(a) (a) +#define ACPI_STORE_ADDRESS(a,b) ((a)=(acpi_physical_address)(b)) +#define ACPI_VALID_ADDRESS(a) (a) +#endif +#endif + + /* + * Extract a byte of data using a pointer. Any more than a byte and we + * get into potential aligment issues -- see the STORE macros below + */ +#define ACPI_GET8(addr) (*(u8*)(addr)) + +/* Pointer arithmetic */ + +#define ACPI_PTR_ADD(t,a,b) (t *) (void *)((char *)(a) + (acpi_native_uint)(b)) +#define ACPI_PTR_DIFF(a,b) (acpi_native_uint) ((char *)(a) - (char *)(b)) + +/* Pointer/Integer type conversions */ + +#define ACPI_TO_POINTER(i) ACPI_PTR_ADD (void, (void *) NULL,(acpi_native_uint)i) +#define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p,(void *) NULL) +#define ACPI_OFFSET(d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL) +#define ACPI_FADT_OFFSET(f) ACPI_OFFSET (FADT_DESCRIPTOR, f) + +#define ACPI_CAST_PTR(t, p) ((t *)(void *)(p)) +#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **)(void *)(p)) + +#if ACPI_MACHINE_WIDTH == 16 +#define ACPI_STORE_POINTER(d,s) ACPI_MOVE_UNALIGNED32_TO_32(d,s) +#define ACPI_PHYSADDR_TO_PTR(i) (void *)(i) +#define ACPI_PTR_TO_PHYSADDR(i) (u32) (char *)(i) +#else +#define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i) +#define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i) +#endif + +/* + * Macros for moving data around to/from buffers that are possibly unaligned. + * If the hardware supports the transfer of unaligned data, just do the store. + * Otherwise, we have to move one byte at a time. + */ + +#ifdef _HW_ALIGNMENT_SUPPORT + +/* The hardware supports unaligned transfers, just do the move */ + +#define ACPI_MOVE_UNALIGNED16_TO_16(d,s) *(u16 *)(void *)(d) = *(u16 *)(void *)(s) +#define ACPI_MOVE_UNALIGNED32_TO_32(d,s) *(u32 *)(void *)(d) = *(u32 *)(void *)(s) +#define ACPI_MOVE_UNALIGNED16_TO_32(d,s) *(u32 *)(void *)(d) = *(u16 *)(void *)(s) +#define ACPI_MOVE_UNALIGNED64_TO_64(d,s) *(u64 *)(void *)(d) = *(u64 *)(void *)(s) + +#else +/* + * The hardware does not support unaligned transfers. We must move the + * data one byte at a time. These macros work whether the source or + * the destination (or both) is/are unaligned. + */ + +#define ACPI_MOVE_UNALIGNED16_TO_16(d,s) {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ + ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];} + +#define ACPI_MOVE_UNALIGNED32_TO_32(d,s) {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ + ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\ + ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\ + ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];} + +#define ACPI_MOVE_UNALIGNED16_TO_32(d,s) {(*(u32*)(void *)(d)) = 0; ACPI_MOVE_UNALIGNED16_TO_16(d,s);} + +#define ACPI_MOVE_UNALIGNED64_TO_64(d,s) {((u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ + ((u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\ + ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\ + ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];\ + ((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[4];\ + ((u8 *)(void *)(d))[5] = ((u8 *)(void *)(s))[5];\ + ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[6];\ + ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[7];} + +#endif + + +/* + * Fast power-of-two math macros for non-optimized compilers + */ + +#define _ACPI_DIV(value,power_of2) ((u32) ((value) >> (power_of2))) +#define _ACPI_MUL(value,power_of2) ((u32) ((value) << (power_of2))) +#define _ACPI_MOD(value,divisor) ((u32) ((value) & ((divisor) -1))) + +#define ACPI_DIV_2(a) _ACPI_DIV(a,1) +#define ACPI_MUL_2(a) _ACPI_MUL(a,1) +#define ACPI_MOD_2(a) _ACPI_MOD(a,2) + +#define ACPI_DIV_4(a) _ACPI_DIV(a,2) +#define ACPI_MUL_4(a) _ACPI_MUL(a,2) +#define ACPI_MOD_4(a) _ACPI_MOD(a,4) + +#define ACPI_DIV_8(a) _ACPI_DIV(a,3) +#define ACPI_MUL_8(a) _ACPI_MUL(a,3) +#define ACPI_MOD_8(a) _ACPI_MOD(a,8) + +#define ACPI_DIV_16(a) _ACPI_DIV(a,4) +#define ACPI_MUL_16(a) _ACPI_MUL(a,4) +#define ACPI_MOD_16(a) _ACPI_MOD(a,16) + + +/* + * Rounding macros (Power of two boundaries only) + */ +#define ACPI_ROUND_DOWN(value,boundary) (((acpi_native_uint)(value)) & (~(((acpi_native_uint) boundary)-1))) +#define ACPI_ROUND_UP(value,boundary) ((((acpi_native_uint)(value)) + (((acpi_native_uint) boundary)-1)) & (~(((acpi_native_uint) boundary)-1))) + +#define ACPI_ROUND_DOWN_TO_32_BITS(a) ACPI_ROUND_DOWN(a,4) +#define ACPI_ROUND_DOWN_TO_64_BITS(a) ACPI_ROUND_DOWN(a,8) +#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a) ACPI_ROUND_DOWN(a,ALIGNED_ADDRESS_BOUNDARY) + +#define ACPI_ROUND_UP_to_32_bITS(a) ACPI_ROUND_UP(a,4) +#define ACPI_ROUND_UP_to_64_bITS(a) ACPI_ROUND_UP(a,8) +#define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY) + + +#define ACPI_ROUND_BITS_UP_TO_BYTES(a) ACPI_DIV_8((a) + 7) +#define ACPI_ROUND_BITS_DOWN_TO_BYTES(a) ACPI_DIV_8((a)) + +#define ACPI_ROUND_UP_TO_1K(a) (((a) + 1023) >> 10) + +/* Generic (non-power-of-two) rounding */ + +#define ACPI_ROUND_UP_TO(value,boundary) (((value) + ((boundary)-1)) / (boundary)) + +/* + * Bitmask creation + * Bit positions start at zero. + * MASK_BITS_ABOVE creates a mask starting AT the position and above + * MASK_BITS_BELOW creates a mask starting one bit BELOW the position + */ +#define ACPI_MASK_BITS_ABOVE(position) (~((ACPI_INTEGER_MAX) << ((u32) (position)))) +#define ACPI_MASK_BITS_BELOW(position) ((ACPI_INTEGER_MAX) << ((u32) (position))) + +#define ACPI_IS_OCTAL_DIGIT(d) (((char)(d) >= '0') && ((char)(d) <= '7')) + +/* Macros for GAS addressing */ + +#if ACPI_MACHINE_WIDTH != 16 + +#define ACPI_PCI_DEVICE_MASK (u64) 0x0000FFFF00000000 +#define ACPI_PCI_FUNCTION_MASK (u64) 0x00000000FFFF0000 +#define ACPI_PCI_REGISTER_MASK (u64) 0x000000000000FFFF + +/* + * Obsolete + */ + +/* +#define ACPI_PCI_FUNCTION(a) (u16) ((((u64)((u64)(a) & ACPI_PCI_FUNCTION_MASK)) >> 16)) +#define ACPI_PCI_DEVICE(a) (u16) ((((u64)((u64)(a) & ACPI_PCI_DEVICE_MASK)) >> 32)) +#define ACPI_PCI_REGISTER(a) (u16) (((u64)((u64)(a) & ACPI_PCI_REGISTER_MASK))) +*/ + + +#define ACPI_PCI_DEVICE(a) (u16) ((ACPI_HIDWORD ((a))) & 0x0000FFFF) +#define ACPI_PCI_FUNCTION(a) (u16) ((ACPI_LODWORD ((a))) >> 16) +#define ACPI_PCI_REGISTER(a) (u16) ((ACPI_LODWORD ((a))) & 0x0000FFFF) + +#else + +/* No support for GAS and PCI IDs in 16-bit mode */ + +#define ACPI_PCI_FUNCTION(a) (u16) ((a) & 0xFFFF0000) +#define ACPI_PCI_DEVICE(a) (u16) ((a) & 0x0000FFFF) +#define ACPI_PCI_REGISTER(a) (u16) ((a) & 0x0000FFFF) + +#endif + + +/* Bitfields within ACPI registers */ + +#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) ((val << pos) & mask) +#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask) + +/* + * An struct acpi_namespace_node * can appear in some contexts, + * where a pointer to an union acpi_operand_object can also + * appear. This macro is used to distinguish them. + * + * The "Descriptor" field is the first field in both structures. + */ +#define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->descriptor_id) +#define ACPI_SET_DESCRIPTOR_TYPE(d,t) (((union acpi_descriptor *)(void *)(d))->descriptor_id = t) + + +/* Macro to test the object type */ + +#define ACPI_GET_OBJECT_TYPE(d) (((union acpi_operand_object *)(void *)(d))->common.type) + +/* Macro to check the table flags for SINGLE or MULTIPLE tables are allowed */ + +#define ACPI_IS_SINGLE_TABLE(x) (((x) & 0x01) == ACPI_TABLE_SINGLE ? 1 : 0) + +/* + * Macros for the master AML opcode table + */ +#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUG_OUTPUT) +#define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags) {name,(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type} +#else +#define ACPI_OP(name,Pargs,Iargs,obj_type,class,type,flags) {(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type} +#endif + +#ifdef ACPI_DISASSEMBLER +#define ACPI_DISASM_ONLY_MEMBERS(a) a; +#else +#define ACPI_DISASM_ONLY_MEMBERS(a) +#endif + +#define ARG_TYPE_WIDTH 5 +#define ARG_1(x) ((u32)(x)) +#define ARG_2(x) ((u32)(x) << (1 * ARG_TYPE_WIDTH)) +#define ARG_3(x) ((u32)(x) << (2 * ARG_TYPE_WIDTH)) +#define ARG_4(x) ((u32)(x) << (3 * ARG_TYPE_WIDTH)) +#define ARG_5(x) ((u32)(x) << (4 * ARG_TYPE_WIDTH)) +#define ARG_6(x) ((u32)(x) << (5 * ARG_TYPE_WIDTH)) + +#define ARGI_LIST1(a) (ARG_1(a)) +#define ARGI_LIST2(a,b) (ARG_1(b)|ARG_2(a)) +#define ARGI_LIST3(a,b,c) (ARG_1(c)|ARG_2(b)|ARG_3(a)) +#define ARGI_LIST4(a,b,c,d) (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a)) +#define ARGI_LIST5(a,b,c,d,e) (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a)) +#define ARGI_LIST6(a,b,c,d,e,f) (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a)) + +#define ARGP_LIST1(a) (ARG_1(a)) +#define ARGP_LIST2(a,b) (ARG_1(a)|ARG_2(b)) +#define ARGP_LIST3(a,b,c) (ARG_1(a)|ARG_2(b)|ARG_3(c)) +#define ARGP_LIST4(a,b,c,d) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)) +#define ARGP_LIST5(a,b,c,d,e) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)) +#define ARGP_LIST6(a,b,c,d,e,f) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f)) + +#define GET_CURRENT_ARG_TYPE(list) (list & ((u32) 0x1F)) +#define INCREMENT_ARG_LIST(list) (list >>= ((u32) ARG_TYPE_WIDTH)) + + +/* + * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions) + * + * 1) Address space + * 2) Length in bytes -- convert to length in bits + * 3) Bit offset is zero + * 4) Reserved field is zero + * 5) Expand address to 64 bits + */ +#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d) do {a.address_space_id = (u8) d;\ + a.register_bit_width = (u8) ACPI_MUL_8 (b);\ + a.register_bit_offset = 0;\ + a.reserved = 0;\ + ACPI_STORE_ADDRESS (a.address,(acpi_physical_address) c);} while (0) + +/* ACPI V1.0 entries -- address space is always I/O */ + +#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c) ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ACPI_ADR_SPACE_SYSTEM_IO) + + +/* + * Reporting macros that are never compiled out + */ + +#define ACPI_PARAM_LIST(pl) pl + +/* + * Error reporting. These versions add callers module and line#. Since + * _THIS_MODULE gets compiled out when ACPI_DEBUG_OUTPUT isn't defined, only + * use it in debug mode. + */ + +#ifdef ACPI_DEBUG_OUTPUT + +#define ACPI_REPORT_INFO(fp) {acpi_ut_report_info(_THIS_MODULE,__LINE__,_COMPONENT); \ + acpi_os_printf ACPI_PARAM_LIST(fp);} +#define ACPI_REPORT_ERROR(fp) {acpi_ut_report_error(_THIS_MODULE,__LINE__,_COMPONENT); \ + acpi_os_printf ACPI_PARAM_LIST(fp);} +#define ACPI_REPORT_WARNING(fp) {acpi_ut_report_warning(_THIS_MODULE,__LINE__,_COMPONENT); \ + acpi_os_printf ACPI_PARAM_LIST(fp);} +#define ACPI_REPORT_NSERROR(s,e) acpi_ns_report_error(_THIS_MODULE,__LINE__,_COMPONENT, s, e); + +#define ACPI_REPORT_METHOD_ERROR(s,n,p,e) acpi_ns_report_method_error(_THIS_MODULE,__LINE__,_COMPONENT, s, n, p, e); + +#else + +#define ACPI_REPORT_INFO(fp) {acpi_ut_report_info("ACPI",__LINE__,_COMPONENT); \ + acpi_os_printf ACPI_PARAM_LIST(fp);} +#define ACPI_REPORT_ERROR(fp) {acpi_ut_report_error("ACPI",__LINE__,_COMPONENT); \ + acpi_os_printf ACPI_PARAM_LIST(fp);} +#define ACPI_REPORT_WARNING(fp) {acpi_ut_report_warning("ACPI",__LINE__,_COMPONENT); \ + acpi_os_printf ACPI_PARAM_LIST(fp);} +#define ACPI_REPORT_NSERROR(s,e) acpi_ns_report_error("ACPI",__LINE__,_COMPONENT, s, e); + +#define ACPI_REPORT_METHOD_ERROR(s,n,p,e) acpi_ns_report_method_error("ACPI",__LINE__,_COMPONENT, s, n, p, e); + +#endif + +/* Error reporting. These versions pass thru the module and line# */ + +#define _ACPI_REPORT_INFO(a,b,c,fp) {acpi_ut_report_info(a,b,c); \ + acpi_os_printf ACPI_PARAM_LIST(fp);} +#define _ACPI_REPORT_ERROR(a,b,c,fp) {acpi_ut_report_error(a,b,c); \ + acpi_os_printf ACPI_PARAM_LIST(fp);} +#define _ACPI_REPORT_WARNING(a,b,c,fp) {acpi_ut_report_warning(a,b,c); \ + acpi_os_printf ACPI_PARAM_LIST(fp);} + +/* + * Debug macros that are conditionally compiled + */ + +#ifdef ACPI_DEBUG_OUTPUT + +#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR *_THIS_MODULE = name; + +/* + * Function entry tracing. + * The first parameter should be the procedure name as a quoted string. This is declared + * as a local string ("_proc_name) so that it can be also used by the function exit macros below. + */ + +#define ACPI_FUNCTION_NAME(a) struct acpi_debug_print_info _dbg; \ + _dbg.component_id = _COMPONENT; \ + _dbg.proc_name = a; \ + _dbg.module_name = _THIS_MODULE; + +#define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a)\ + acpi_ut_trace(__LINE__,&_dbg) +#define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a)\ + acpi_ut_trace_ptr(__LINE__,&_dbg,(void *)b) +#define ACPI_FUNCTION_TRACE_U32(a,b) ACPI_FUNCTION_NAME(a)\ + acpi_ut_trace_u32(__LINE__,&_dbg,(u32)b) +#define ACPI_FUNCTION_TRACE_STR(a,b) ACPI_FUNCTION_NAME(a)\ + acpi_ut_trace_str(__LINE__,&_dbg,(char *)b) + +#define ACPI_FUNCTION_ENTRY() acpi_ut_track_stack_ptr() + +/* + * Function exit tracing. + * WARNING: These macros include a return statement. This is usually considered + * bad form, but having a separate exit macro is very ugly and difficult to maintain. + * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros + * so that "_proc_name" is defined. + */ +#ifdef ACPI_USE_DO_WHILE_0 +#define ACPI_DO_WHILE0(a) do a while(0) +#else +#define ACPI_DO_WHILE0(a) a +#endif + +#define return_VOID ACPI_DO_WHILE0 ({acpi_ut_exit(__LINE__,&_dbg);return;}) +#define return_ACPI_STATUS(s) ACPI_DO_WHILE0 ({acpi_ut_status_exit(__LINE__,&_dbg,(s));return((s));}) +#define return_VALUE(s) ACPI_DO_WHILE0 ({acpi_ut_value_exit(__LINE__,&_dbg,(acpi_integer)(s));return((s));}) +#define return_PTR(s) ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(__LINE__,&_dbg,(u8 *)(s));return((s));}) + +/* Conditional execution */ + +#define ACPI_DEBUG_EXEC(a) a +#define ACPI_NORMAL_EXEC(a) + +#define ACPI_DEBUG_DEFINE(a) a; +#define ACPI_DEBUG_ONLY_MEMBERS(a) a; +#define _VERBOSE_STRUCTURES + + +/* Stack and buffer dumping */ + +#define ACPI_DUMP_STACK_ENTRY(a) acpi_ex_dump_operand(a) +#define ACPI_DUMP_OPERANDS(a,b,c,d,e) acpi_ex_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__) + + +#define ACPI_DUMP_ENTRY(a,b) acpi_ns_dump_entry (a,b) +#define ACPI_DUMP_TABLES(a,b) acpi_ns_dump_tables(a,b) +#define ACPI_DUMP_PATHNAME(a,b,c,d) acpi_ns_dump_pathname(a,b,c,d) +#define ACPI_DUMP_RESOURCE_LIST(a) acpi_rs_dump_resource_list(a) +#define ACPI_DUMP_BUFFER(a,b) acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT) +#define ACPI_BREAK_MSG(a) acpi_os_signal (ACPI_SIGNAL_BREAKPOINT,(a)) + + +/* + * Generate INT3 on ACPI_ERROR (Debug only!) + */ + +#define ACPI_ERROR_BREAK +#ifdef ACPI_ERROR_BREAK +#define ACPI_BREAK_ON_ERROR(lvl) if ((lvl)&ACPI_ERROR) \ + acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,"Fatal error encountered\n") +#else +#define ACPI_BREAK_ON_ERROR(lvl) +#endif + +/* + * Master debug print macros + * Print iff: + * 1) Debug print for the current component is enabled + * 2) Debug error level or trace level for the print statement is enabled + */ + +#define ACPI_DEBUG_PRINT(pl) acpi_ut_debug_print ACPI_PARAM_LIST(pl) +#define ACPI_DEBUG_PRINT_RAW(pl) acpi_ut_debug_print_raw ACPI_PARAM_LIST(pl) + + +#else +/* + * This is the non-debug case -- make everything go away, + * leaving no executable debug code! + */ + +#define ACPI_MODULE_NAME(name) +#define _THIS_MODULE "" + +#define ACPI_DEBUG_EXEC(a) +#define ACPI_NORMAL_EXEC(a) a; + +#define ACPI_DEBUG_DEFINE(a) +#define ACPI_DEBUG_ONLY_MEMBERS(a) +#define ACPI_FUNCTION_NAME(a) +#define ACPI_FUNCTION_TRACE(a) +#define ACPI_FUNCTION_TRACE_PTR(a,b) +#define ACPI_FUNCTION_TRACE_U32(a,b) +#define ACPI_FUNCTION_TRACE_STR(a,b) +#define ACPI_FUNCTION_EXIT +#define ACPI_FUNCTION_STATUS_EXIT(s) +#define ACPI_FUNCTION_VALUE_EXIT(s) +#define ACPI_FUNCTION_ENTRY() +#define ACPI_DUMP_STACK_ENTRY(a) +#define ACPI_DUMP_OPERANDS(a,b,c,d,e) +#define ACPI_DUMP_ENTRY(a,b) +#define ACPI_DUMP_TABLES(a,b) +#define ACPI_DUMP_PATHNAME(a,b,c,d) +#define ACPI_DUMP_RESOURCE_LIST(a) +#define ACPI_DUMP_BUFFER(a,b) +#define ACPI_DEBUG_PRINT(pl) +#define ACPI_DEBUG_PRINT_RAW(pl) +#define ACPI_BREAK_MSG(a) + +#define return_VOID return +#define return_ACPI_STATUS(s) return(s) +#define return_VALUE(s) return(s) +#define return_PTR(s) return(s) + +#endif + +/* + * Some code only gets executed when the debugger is built in. + * Note that this is entirely independent of whether the + * DEBUG_PRINT stuff (set by ACPI_DEBUG_OUTPUT) is on, or not. + */ +#ifdef ACPI_DEBUGGER +#define ACPI_DEBUGGER_EXEC(a) a +#else +#define ACPI_DEBUGGER_EXEC(a) +#endif + + +/* + * For 16-bit code, we want to shrink some things even though + * we are using ACPI_DEBUG_OUTPUT to get the debug output + */ +#if ACPI_MACHINE_WIDTH == 16 +#undef ACPI_DEBUG_ONLY_MEMBERS +#undef _VERBOSE_STRUCTURES +#define ACPI_DEBUG_ONLY_MEMBERS(a) +#endif + + +#ifdef ACPI_DEBUG_OUTPUT +/* + * 1) Set name to blanks + * 2) Copy the object name + */ +#define ACPI_ADD_OBJECT_NAME(a,b) ACPI_MEMSET (a->common.name, ' ', sizeof (a->common.name));\ + ACPI_STRNCPY (a->common.name, acpi_gbl_ns_type_names[b], sizeof (a->common.name)) +#else + +#define ACPI_ADD_OBJECT_NAME(a,b) +#endif + + +/* + * Memory allocation tracking (DEBUG ONLY) + */ + +#ifndef ACPI_DBG_TRACK_ALLOCATIONS + +/* Memory allocation */ + +#define ACPI_MEM_ALLOCATE(a) acpi_ut_allocate((acpi_size)(a),_COMPONENT,_THIS_MODULE,__LINE__) +#define ACPI_MEM_CALLOCATE(a) acpi_ut_callocate((acpi_size)(a), _COMPONENT,_THIS_MODULE,__LINE__) +#define ACPI_MEM_FREE(a) acpi_os_free(a) +#define ACPI_MEM_TRACKING(a) + + +#else + +/* Memory allocation */ + +#define ACPI_MEM_ALLOCATE(a) acpi_ut_allocate_and_track((acpi_size)(a),_COMPONENT,_THIS_MODULE,__LINE__) +#define ACPI_MEM_CALLOCATE(a) acpi_ut_callocate_and_track((acpi_size)(a), _COMPONENT,_THIS_MODULE,__LINE__) +#define ACPI_MEM_FREE(a) acpi_ut_free_and_track(a,_COMPONENT,_THIS_MODULE,__LINE__) +#define ACPI_MEM_TRACKING(a) a + +#endif /* ACPI_DBG_TRACK_ALLOCATIONS */ + + +#define ACPI_GET_STACK_POINTER _asm {mov eax, ebx} + +#endif /* ACMACROS_H */ diff -Nru a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acnamesp.h Sun Feb 9 21:13:29 2003 @@ -0,0 +1,489 @@ +/****************************************************************************** + * + * Name: acnamesp.h - Namespace subcomponent prototypes and defines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACNAMESP_H__ +#define __ACNAMESP_H__ + + +/* To search the entire name space, pass this as search_base */ + +#define ACPI_NS_ALL ((acpi_handle)0) + +/* + * Elements of acpi_ns_properties are bit significant + * and should be one-to-one with values of acpi_object_type + */ +#define ACPI_NS_NORMAL 0 +#define ACPI_NS_NEWSCOPE 1 /* a definition of this type opens a name scope */ +#define ACPI_NS_LOCAL 2 /* suppress search of enclosing scopes */ + + +/* Definitions of the predefined namespace names */ + +#define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */ +#define ACPI_ROOT_NAME (u32) 0x5F5F5F5C /* Root name is "\___" */ +#define ACPI_SYS_BUS_NAME (u32) 0x5F53425F /* Sys bus name is "_SB_" */ + +#define ACPI_NS_ROOT_PATH "\\" +#define ACPI_NS_SYSTEM_BUS "_SB_" + + +/* Flags for acpi_ns_lookup, acpi_ns_search_and_enter */ + +#define ACPI_NS_NO_UPSEARCH 0 +#define ACPI_NS_SEARCH_PARENT 0x01 +#define ACPI_NS_DONT_OPEN_SCOPE 0x02 +#define ACPI_NS_NO_PEER_SEARCH 0x04 +#define ACPI_NS_ERROR_IF_FOUND 0x08 + +#define ACPI_NS_WALK_UNLOCK TRUE +#define ACPI_NS_WALK_NO_UNLOCK FALSE + + +acpi_status +acpi_ns_load_namespace ( + void); + +acpi_status +acpi_ns_initialize_objects ( + void); + +acpi_status +acpi_ns_initialize_devices ( + void); + + +/* Namespace init - nsxfinit */ + +acpi_status +acpi_ns_init_one_device ( + acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value); + +acpi_status +acpi_ns_init_one_object ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value); + + +acpi_status +acpi_ns_walk_namespace ( + acpi_object_type type, + acpi_handle start_object, + u32 max_depth, + u8 unlock_before_callback, + acpi_walk_callback user_function, + void *context, + void **return_value); + +struct acpi_namespace_node * +acpi_ns_get_next_node ( + acpi_object_type type, + struct acpi_namespace_node *parent, + struct acpi_namespace_node *child); + +void +acpi_ns_delete_namespace_by_owner ( + u16 table_id); + + +/* Namespace loading - nsload */ + +acpi_status +acpi_ns_one_complete_parse ( + u32 pass_number, + struct acpi_table_desc *table_desc); + +acpi_status +acpi_ns_parse_table ( + struct acpi_table_desc *table_desc, + struct acpi_namespace_node *scope); + +acpi_status +acpi_ns_load_table ( + struct acpi_table_desc *table_desc, + struct acpi_namespace_node *node); + +acpi_status +acpi_ns_load_table_by_type ( + acpi_table_type table_type); + + +/* + * Top-level namespace access - nsaccess + */ + +acpi_status +acpi_ns_root_initialize ( + void); + +acpi_status +acpi_ns_lookup ( + union acpi_generic_state *scope_info, + char *name, + acpi_object_type type, + acpi_interpreter_mode interpreter_mode, + u32 flags, + struct acpi_walk_state *walk_state, + struct acpi_namespace_node **ret_node); + + +/* + * Named object allocation/deallocation - nsalloc + */ + +struct acpi_namespace_node * +acpi_ns_create_node ( + u32 name); + +void +acpi_ns_delete_node ( + struct acpi_namespace_node *node); + +void +acpi_ns_delete_namespace_subtree ( + struct acpi_namespace_node *parent_handle); + +void +acpi_ns_detach_object ( + struct acpi_namespace_node *node); + +void +acpi_ns_delete_children ( + struct acpi_namespace_node *parent); + +int +acpi_ns_compare_names ( + char *name1, + char *name2); + +/* + * Namespace modification - nsmodify + */ + +acpi_status +acpi_ns_unload_namespace ( + acpi_handle handle); + +acpi_status +acpi_ns_delete_subtree ( + acpi_handle start_handle); + + +/* + * Namespace dump/print utilities - nsdump + */ + +void +acpi_ns_dump_tables ( + acpi_handle search_base, + u32 max_depth); + +void +acpi_ns_dump_entry ( + acpi_handle handle, + u32 debug_level); + +void +acpi_ns_dump_pathname ( + acpi_handle handle, + char *msg, + u32 level, + u32 component); + +void +acpi_ns_print_pathname ( + u32 num_segments, + char *pathname); + +acpi_status +acpi_ns_dump_one_device ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value); + +void +acpi_ns_dump_root_devices ( + void); + +acpi_status +acpi_ns_dump_one_object ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value); + +void +acpi_ns_dump_objects ( + acpi_object_type type, + u8 display_type, + u32 max_depth, + u32 ownder_id, + acpi_handle start_handle); + + +/* + * Namespace evaluation functions - nseval + */ + +acpi_status +acpi_ns_evaluate_by_handle ( + struct acpi_namespace_node *prefix_node, + union acpi_operand_object **params, + union acpi_operand_object **return_object); + +acpi_status +acpi_ns_evaluate_by_name ( + char *pathname, + union acpi_operand_object **params, + union acpi_operand_object **return_object); + +acpi_status +acpi_ns_evaluate_relative ( + struct acpi_namespace_node *prefix_node, + char *pathname, + union acpi_operand_object **params, + union acpi_operand_object **return_object); + +acpi_status +acpi_ns_execute_control_method ( + struct acpi_namespace_node *method_node, + union acpi_operand_object **params, + union acpi_operand_object **return_obj_desc); + +acpi_status +acpi_ns_get_object_value ( + struct acpi_namespace_node *object_node, + union acpi_operand_object **return_obj_desc); + + +/* + * Parent/Child/Peer utility functions + */ + +acpi_name +acpi_ns_find_parent_name ( + struct acpi_namespace_node *node_to_search); + + +/* + * Name and Scope manipulation - nsnames + */ + +u32 +acpi_ns_opens_scope ( + acpi_object_type type); + +void +acpi_ns_build_external_path ( + struct acpi_namespace_node *node, + acpi_size size, + char *name_buffer); + +char * +acpi_ns_get_external_pathname ( + struct acpi_namespace_node *node); + +char * +acpi_ns_name_of_current_scope ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ns_handle_to_pathname ( + acpi_handle target_handle, + struct acpi_buffer *buffer); + +u8 +acpi_ns_pattern_match ( + struct acpi_namespace_node *obj_node, + char *search_for); + +acpi_status +acpi_ns_get_node_by_path ( + char *external_pathname, + struct acpi_namespace_node *in_prefix_node, + u32 flags, + struct acpi_namespace_node **out_node); + +acpi_size +acpi_ns_get_pathname_length ( + struct acpi_namespace_node *node); + + +/* + * Object management for namespace nodes - nsobject + */ + +acpi_status +acpi_ns_attach_object ( + struct acpi_namespace_node *node, + union acpi_operand_object *object, + acpi_object_type type); + +union acpi_operand_object * +acpi_ns_get_attached_object ( + struct acpi_namespace_node *node); + +union acpi_operand_object * +acpi_ns_get_secondary_object ( + union acpi_operand_object *obj_desc); + +acpi_status +acpi_ns_attach_data ( + struct acpi_namespace_node *node, + acpi_object_handler handler, + void *data); + +acpi_status +acpi_ns_detach_data ( + struct acpi_namespace_node *node, + acpi_object_handler handler); + +acpi_status +acpi_ns_get_attached_data ( + struct acpi_namespace_node *node, + acpi_object_handler handler, + void **data); + + +/* + * Namespace searching and entry - nssearch + */ + +acpi_status +acpi_ns_search_and_enter ( + u32 entry_name, + struct acpi_walk_state *walk_state, + struct acpi_namespace_node *node, + acpi_interpreter_mode interpreter_mode, + acpi_object_type type, + u32 flags, + struct acpi_namespace_node **ret_node); + +acpi_status +acpi_ns_search_node ( + u32 entry_name, + struct acpi_namespace_node *node, + acpi_object_type type, + struct acpi_namespace_node **ret_node); + +void +acpi_ns_install_node ( + struct acpi_walk_state *walk_state, + struct acpi_namespace_node *parent_node, + struct acpi_namespace_node *node, + acpi_object_type type); + + +/* + * Utility functions - nsutils + */ + +u8 +acpi_ns_valid_root_prefix ( + char prefix); + +u8 +acpi_ns_valid_path_separator ( + char sep); + +acpi_object_type +acpi_ns_get_type ( + struct acpi_namespace_node *node); + +u32 +acpi_ns_local ( + acpi_object_type type); + +void +acpi_ns_report_error ( + char *module_name, + u32 line_number, + u32 component_id, + char *internal_name, + acpi_status lookup_status); + +void +acpi_ns_report_method_error ( + char *module_name, + u32 line_number, + u32 component_id, + char *message, + struct acpi_namespace_node *node, + char *path, + acpi_status lookup_status); + +void +acpi_ns_print_node_pathname ( + struct acpi_namespace_node *node, + char *msg); + +acpi_status +acpi_ns_build_internal_name ( + struct acpi_namestring_info *info); + +void +acpi_ns_get_internal_name_length ( + struct acpi_namestring_info *info); + +acpi_status +acpi_ns_internalize_name ( + char *dotted_name, + char **converted_name); + +acpi_status +acpi_ns_externalize_name ( + u32 internal_name_length, + char *internal_name, + u32 *converted_name_length, + char **converted_name); + +struct acpi_namespace_node * +acpi_ns_map_handle_to_node ( + acpi_handle handle); + +acpi_handle +acpi_ns_convert_entry_to_handle( + struct acpi_namespace_node *node); + +void +acpi_ns_terminate ( + void); + +struct acpi_namespace_node * +acpi_ns_get_parent_node ( + struct acpi_namespace_node *node); + + +struct acpi_namespace_node * +acpi_ns_get_next_valid_node ( + struct acpi_namespace_node *node); + + +#endif /* __ACNAMESP_H__ */ diff -Nru a/include/acpi/acobject.h b/include/acpi/acobject.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acobject.h Sun Feb 9 21:13:29 2003 @@ -0,0 +1,473 @@ + +/****************************************************************************** + * + * Name: acobject.h - Definition of union acpi_operand_object (Internal object only) + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef _ACOBJECT_H +#define _ACOBJECT_H + + +/* + * The union acpi_operand_object is used to pass AML operands from the dispatcher + * to the interpreter, and to keep track of the various handlers such as + * address space handlers and notify handlers. The object is a constant + * size in order to allow it to be cached and reused. + */ + +/******************************************************************************* + * + * Common Descriptors + * + ******************************************************************************/ + +/* + * Common area for all objects. + * + * data_type is used to differentiate between internal descriptors, and MUST + * be the first byte in this structure. + */ +#define ACPI_OBJECT_COMMON_HEADER /* SIZE/ALIGNMENT: 32 bits, one ptr plus trailing 8-bit flag */\ + u8 descriptor; /* To differentiate various internal objs */\ + u8 type; /* acpi_object_type */\ + u16 reference_count; /* For object deletion management */\ + union acpi_operand_object *next_object; /* Objects linked to parent NS node */\ + u8 flags; \ + +/* Values for flag byte above */ + +#define AOPOBJ_AML_CONSTANT 0x01 +#define AOPOBJ_STATIC_POINTER 0x02 +#define AOPOBJ_DATA_VALID 0x04 +#define AOPOBJ_OBJECT_INITIALIZED 0x08 +#define AOPOBJ_SETUP_COMPLETE 0x10 +#define AOPOBJ_SINGLE_DATUM 0x20 + + +/* + * Common bitfield for the field objects + * "Field Datum" -- a datum from the actual field object + * "Buffer Datum" -- a datum from a user buffer, read from or to be written to the field + */ +#define ACPI_COMMON_FIELD_INFO /* SIZE/ALIGNMENT: 24 bits + three 32-bit values */\ + u8 field_flags; /* Access, update, and lock bits */\ + u8 attribute; /* From access_as keyword */\ + u8 access_byte_width; /* Read/Write size in bytes */\ + u32 bit_length; /* Length of field in bits */\ + u32 base_byte_offset; /* Byte offset within containing object */\ + u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\ + u8 datum_valid_bits; /* Valid bit in first "Field datum" */\ + u8 end_field_valid_bits; /* Valid bits in the last "field datum" */\ + u8 end_buffer_valid_bits; /* Valid bits in the last "buffer datum" */\ + u32 value; /* Value to store into the Bank or Index register */\ + struct acpi_namespace_node *node; /* Link back to parent node */ + + +/* + * Fields common to both Strings and Buffers + */ +#define ACPI_COMMON_BUFFER_INFO \ + u32 length; + + +/* + * Common fields for objects that support ASL notifications + */ +#define ACPI_COMMON_NOTIFY_INFO \ + union acpi_operand_object *sys_handler; /* Handler for system notifies */\ + union acpi_operand_object *drv_handler; /* Handler for driver notifies */\ + union acpi_operand_object *addr_handler; /* Handler for Address space */ + + +/****************************************************************************** + * + * Basic data types + * + *****************************************************************************/ + +struct acpi_object_common +{ + ACPI_OBJECT_COMMON_HEADER +}; + + +struct acpi_object_integer +{ + ACPI_OBJECT_COMMON_HEADER + acpi_integer value; +}; + + +struct acpi_object_string /* Null terminated, ASCII characters only */ +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_BUFFER_INFO + char *pointer; /* String in AML stream or allocated string */ +}; + + +struct acpi_object_buffer +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_BUFFER_INFO + u8 *pointer; /* Buffer in AML stream or allocated buffer */ + struct acpi_namespace_node *node; /* Link back to parent node */ + u8 *aml_start; + u32 aml_length; +}; + + +struct acpi_object_package +{ + ACPI_OBJECT_COMMON_HEADER + + u32 count; /* # of elements in package */ + u32 aml_length; + u8 *aml_start; + struct acpi_namespace_node *node; /* Link back to parent node */ + union acpi_operand_object **elements; /* Array of pointers to acpi_objects */ +}; + + +/****************************************************************************** + * + * Complex data types + * + *****************************************************************************/ + +struct acpi_object_event +{ + ACPI_OBJECT_COMMON_HEADER + void *semaphore; +}; + + +#define INFINITE_CONCURRENCY 0xFF + +struct acpi_object_method +{ + ACPI_OBJECT_COMMON_HEADER + u8 method_flags; + u8 param_count; + u32 aml_length; + void *semaphore; + u8 *aml_start; + u8 concurrency; + u8 thread_count; + acpi_owner_id owning_id; +}; + + +struct acpi_object_mutex +{ + ACPI_OBJECT_COMMON_HEADER + u16 sync_level; + u16 acquisition_depth; + struct acpi_thread_state *owner_thread; + void *semaphore; + union acpi_operand_object *prev; /* Link for list of acquired mutexes */ + union acpi_operand_object *next; /* Link for list of acquired mutexes */ + struct acpi_namespace_node *node; /* containing object */ +}; + + +struct acpi_object_region +{ + ACPI_OBJECT_COMMON_HEADER + + u8 space_id; + union acpi_operand_object *addr_handler; /* Handler for system notifies */ + struct acpi_namespace_node *node; /* containing object */ + union acpi_operand_object *next; + u32 length; + acpi_physical_address address; +}; + + +/****************************************************************************** + * + * Objects that can be notified. All share a common notify_info area. + * + *****************************************************************************/ + +struct acpi_object_notify_common /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */ +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_NOTIFY_INFO +}; + + +struct acpi_object_device +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_NOTIFY_INFO +}; + + +struct acpi_object_power_resource +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_NOTIFY_INFO + u32 system_level; + u32 resource_order; +}; + + +struct acpi_object_processor +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_NOTIFY_INFO + u32 proc_id; + u32 length; + acpi_io_address address; +}; + + +struct acpi_object_thermal_zone +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_NOTIFY_INFO +}; + + +/****************************************************************************** + * + * Fields. All share a common header/info field. + * + *****************************************************************************/ + +struct acpi_object_field_common /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */ +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_FIELD_INFO + union acpi_operand_object *region_obj; /* Containing Operation Region object */ + /* (REGION/BANK fields only) */ +}; + + +struct acpi_object_region_field +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_FIELD_INFO + union acpi_operand_object *region_obj; /* Containing op_region object */ +}; + + +struct acpi_object_bank_field +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_FIELD_INFO + union acpi_operand_object *region_obj; /* Containing op_region object */ + union acpi_operand_object *bank_obj; /* bank_select Register object */ +}; + + +struct acpi_object_index_field +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_FIELD_INFO + + /* + * No "region_obj" pointer needed since the Index and Data registers + * are each field definitions unto themselves. + */ + union acpi_operand_object *index_obj; /* Index register */ + union acpi_operand_object *data_obj; /* Data register */ +}; + + +/* The buffer_field is different in that it is part of a Buffer, not an op_region */ + +struct acpi_object_buffer_field +{ + ACPI_OBJECT_COMMON_HEADER + ACPI_COMMON_FIELD_INFO + union acpi_operand_object *buffer_obj; /* Containing Buffer object */ +}; + + +/****************************************************************************** + * + * Objects for handlers + * + *****************************************************************************/ + +struct acpi_object_notify_handler +{ + ACPI_OBJECT_COMMON_HEADER + struct acpi_namespace_node *node; /* Parent device */ + acpi_notify_handler handler; + void *context; +}; + + +/* Flags for address handler */ + +#define ACPI_ADDR_HANDLER_DEFAULT_INSTALLED 0x1 + + +struct acpi_object_addr_handler +{ + ACPI_OBJECT_COMMON_HEADER + u8 space_id; + u16 hflags; + acpi_adr_space_handler handler; + struct acpi_namespace_node *node; /* Parent device */ + void *context; + acpi_adr_space_setup setup; + union acpi_operand_object *region_list; /* regions using this handler */ + union acpi_operand_object *next; +}; + + +/****************************************************************************** + * + * Special internal objects + * + *****************************************************************************/ + +/* + * The Reference object type is used for these opcodes: + * Arg[0-6], Local[0-7], index_op, name_op, zero_op, one_op, ones_op, debug_op + */ +struct acpi_object_reference +{ + ACPI_OBJECT_COMMON_HEADER + u8 target_type; /* Used for index_op */ + u16 opcode; + u32 offset; /* Used for arg_op, local_op, and index_op */ + void *object; /* name_op=>HANDLE to obj, index_op=>union acpi_operand_object */ + struct acpi_namespace_node *node; + union acpi_operand_object **where; +}; + + +/* + * Extra object is used as additional storage for types that + * have AML code in their declarations (term_args) that must be + * evaluated at run time. + * + * Currently: Region and field_unit types + */ +struct acpi_object_extra +{ + ACPI_OBJECT_COMMON_HEADER + u8 byte_fill1; + u16 word_fill1; + u32 aml_length; + u8 *aml_start; + struct acpi_namespace_node *method_REG; /* _REG method for this region (if any) */ + void *region_context; /* Region-specific data */ +}; + + +/* Additional data that can be attached to namespace nodes */ + +struct acpi_object_data +{ + ACPI_OBJECT_COMMON_HEADER + acpi_object_handler handler; + void *pointer; +}; + + +/* Structure used when objects are cached for reuse */ + +struct acpi_object_cache_list +{ + ACPI_OBJECT_COMMON_HEADER + union acpi_operand_object *next; /* Link for object cache and internal lists*/ +}; + + +/****************************************************************************** + * + * union acpi_operand_object Descriptor - a giant union of all of the above + * + *****************************************************************************/ + +union acpi_operand_object +{ + struct acpi_object_common common; + struct acpi_object_integer integer; + struct acpi_object_string string; + struct acpi_object_buffer buffer; + struct acpi_object_package package; + struct acpi_object_event event; + struct acpi_object_method method; + struct acpi_object_mutex mutex; + struct acpi_object_region region; + struct acpi_object_notify_common common_notify; + struct acpi_object_device device; + struct acpi_object_power_resource power_resource; + struct acpi_object_processor processor; + struct acpi_object_thermal_zone thermal_zone; + struct acpi_object_field_common common_field; + struct acpi_object_region_field field; + struct acpi_object_buffer_field buffer_field; + struct acpi_object_bank_field bank_field; + struct acpi_object_index_field index_field; + struct acpi_object_notify_handler notify_handler; + struct acpi_object_addr_handler addr_handler; + struct acpi_object_reference reference; + struct acpi_object_extra extra; + struct acpi_object_data data; + struct acpi_object_cache_list cache; +}; + + +/****************************************************************************** + * + * union acpi_descriptor - objects that share a common descriptor identifier + * + *****************************************************************************/ + + +/* Object descriptor types */ + +#define ACPI_DESC_TYPE_CACHED 0x11 /* Used only when object is cached */ +#define ACPI_DESC_TYPE_STATE 0x20 +#define ACPI_DESC_TYPE_STATE_UPDATE 0x21 +#define ACPI_DESC_TYPE_STATE_PACKAGE 0x22 +#define ACPI_DESC_TYPE_STATE_CONTROL 0x23 +#define ACPI_DESC_TYPE_STATE_RPSCOPE 0x24 +#define ACPI_DESC_TYPE_STATE_PSCOPE 0x25 +#define ACPI_DESC_TYPE_STATE_WSCOPE 0x26 +#define ACPI_DESC_TYPE_STATE_RESULT 0x27 +#define ACPI_DESC_TYPE_STATE_NOTIFY 0x28 +#define ACPI_DESC_TYPE_STATE_THREAD 0x29 +#define ACPI_DESC_TYPE_WALK 0x44 +#define ACPI_DESC_TYPE_PARSER 0x66 +#define ACPI_DESC_TYPE_OPERAND 0x88 +#define ACPI_DESC_TYPE_NAMED 0xAA + + +union acpi_descriptor +{ + u8 descriptor_id; /* To differentiate various internal objs */\ + union acpi_operand_object object; + struct acpi_namespace_node node; + union acpi_parse_object op; +}; + + +#endif /* _ACOBJECT_H */ diff -Nru a/include/acpi/acoutput.h b/include/acpi/acoutput.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acoutput.h Sun Feb 9 21:13:31 2003 @@ -0,0 +1,166 @@ +/****************************************************************************** + * + * Name: acoutput.h -- debug output + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACOUTPUT_H__ +#define __ACOUTPUT_H__ + +/* + * Debug levels and component IDs. These are used to control the + * granularity of the output of the DEBUG_PRINT macro -- on a per- + * component basis and a per-exception-type basis. + */ + +/* Component IDs are used in the global "debug_layer" */ + +#define ACPI_UTILITIES 0x00000001 +#define ACPI_HARDWARE 0x00000002 +#define ACPI_EVENTS 0x00000004 +#define ACPI_TABLES 0x00000008 +#define ACPI_NAMESPACE 0x00000010 +#define ACPI_PARSER 0x00000020 +#define ACPI_DISPATCHER 0x00000040 +#define ACPI_EXECUTER 0x00000080 +#define ACPI_RESOURCES 0x00000100 +#define ACPI_CA_DEBUGGER 0x00000200 +#define ACPI_OS_SERVICES 0x00000400 +#define ACPI_CA_DISASSEMBLER 0x00000800 + +/* Component IDs for ACPI tools and utilities */ + +#define ACPI_COMPILER 0x00001000 +#define ACPI_TOOLS 0x00002000 + +#define ACPI_ALL_COMPONENTS 0x00003FFF +#define ACPI_COMPONENT_DEFAULT (ACPI_ALL_COMPONENTS) + + +/* Component IDs reserved for ACPI drivers */ + +#define ACPI_ALL_DRIVERS 0xFFFF0000 + + +/* + * Raw debug output levels, do not use these in the DEBUG_PRINT macros + */ +#define ACPI_LV_ERROR 0x00000001 +#define ACPI_LV_WARN 0x00000002 +#define ACPI_LV_INIT 0x00000004 +#define ACPI_LV_DEBUG_OBJECT 0x00000008 +#define ACPI_LV_INFO 0x00000010 +#define ACPI_LV_ALL_EXCEPTIONS 0x0000001F + +/* Trace verbosity level 1 [Standard Trace Level] */ + +#define ACPI_LV_INIT_NAMES 0x00000020 +#define ACPI_LV_PARSE 0x00000040 +#define ACPI_LV_LOAD 0x00000080 +#define ACPI_LV_DISPATCH 0x00000100 +#define ACPI_LV_EXEC 0x00000200 +#define ACPI_LV_NAMES 0x00000400 +#define ACPI_LV_OPREGION 0x00000800 +#define ACPI_LV_BFIELD 0x00001000 +#define ACPI_LV_TABLES 0x00002000 +#define ACPI_LV_VALUES 0x00004000 +#define ACPI_LV_OBJECTS 0x00008000 +#define ACPI_LV_RESOURCES 0x00010000 +#define ACPI_LV_USER_REQUESTS 0x00020000 +#define ACPI_LV_PACKAGE 0x00040000 +#define ACPI_LV_VERBOSITY1 0x0007FF40 | ACPI_LV_ALL_EXCEPTIONS + +/* Trace verbosity level 2 [Function tracing and memory allocation] */ + +#define ACPI_LV_ALLOCATIONS 0x00100000 +#define ACPI_LV_FUNCTIONS 0x00200000 +#define ACPI_LV_OPTIMIZATIONS 0x00400000 +#define ACPI_LV_VERBOSITY2 0x00700000 | ACPI_LV_VERBOSITY1 +#define ACPI_LV_ALL ACPI_LV_VERBOSITY2 + +/* Trace verbosity level 3 [Threading, I/O, and Interrupts] */ + +#define ACPI_LV_MUTEX 0x01000000 +#define ACPI_LV_THREADS 0x02000000 +#define ACPI_LV_IO 0x04000000 +#define ACPI_LV_INTERRUPTS 0x08000000 +#define ACPI_LV_VERBOSITY3 0x0F000000 | ACPI_LV_VERBOSITY2 + +/* Exceptionally verbose output -- also used in the global "debug_level" */ + +#define ACPI_LV_AML_DISASSEMBLE 0x10000000 +#define ACPI_LV_VERBOSE_INFO 0x20000000 +#define ACPI_LV_FULL_TABLES 0x40000000 +#define ACPI_LV_EVENTS 0x80000000 + +#define ACPI_LV_VERBOSE 0xF0000000 + + +/* + * Debug level macros that are used in the DEBUG_PRINT macros + */ +#define ACPI_DEBUG_LEVEL(dl) (u32) dl,__LINE__,&_dbg + +/* Exception level -- used in the global "debug_level" */ + +#define ACPI_DB_ERROR ACPI_DEBUG_LEVEL (ACPI_LV_ERROR) +#define ACPI_DB_WARN ACPI_DEBUG_LEVEL (ACPI_LV_WARN) +#define ACPI_DB_INIT ACPI_DEBUG_LEVEL (ACPI_LV_INIT) +#define ACPI_DB_DEBUG_OBJECT ACPI_DEBUG_LEVEL (ACPI_LV_DEBUG_OBJECT) +#define ACPI_DB_INFO ACPI_DEBUG_LEVEL (ACPI_LV_INFO) +#define ACPI_DB_ALL_EXCEPTIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALL_EXCEPTIONS) + + +/* Trace level -- also used in the global "debug_level" */ + +#define ACPI_DB_INIT_NAMES ACPI_DEBUG_LEVEL (ACPI_LV_INIT_NAMES) +#define ACPI_DB_THREADS ACPI_DEBUG_LEVEL (ACPI_LV_THREADS) +#define ACPI_DB_PARSE ACPI_DEBUG_LEVEL (ACPI_LV_PARSE) +#define ACPI_DB_DISPATCH ACPI_DEBUG_LEVEL (ACPI_LV_DISPATCH) +#define ACPI_DB_LOAD ACPI_DEBUG_LEVEL (ACPI_LV_LOAD) +#define ACPI_DB_EXEC ACPI_DEBUG_LEVEL (ACPI_LV_EXEC) +#define ACPI_DB_NAMES ACPI_DEBUG_LEVEL (ACPI_LV_NAMES) +#define ACPI_DB_OPREGION ACPI_DEBUG_LEVEL (ACPI_LV_OPREGION) +#define ACPI_DB_BFIELD ACPI_DEBUG_LEVEL (ACPI_LV_BFIELD) +#define ACPI_DB_TABLES ACPI_DEBUG_LEVEL (ACPI_LV_TABLES) +#define ACPI_DB_FUNCTIONS ACPI_DEBUG_LEVEL (ACPI_LV_FUNCTIONS) +#define ACPI_DB_OPTIMIZATIONS ACPI_DEBUG_LEVEL (ACPI_LV_OPTIMIZATIONS) +#define ACPI_DB_VALUES ACPI_DEBUG_LEVEL (ACPI_LV_VALUES) +#define ACPI_DB_OBJECTS ACPI_DEBUG_LEVEL (ACPI_LV_OBJECTS) +#define ACPI_DB_ALLOCATIONS ACPI_DEBUG_LEVEL (ACPI_LV_ALLOCATIONS) +#define ACPI_DB_RESOURCES ACPI_DEBUG_LEVEL (ACPI_LV_RESOURCES) +#define ACPI_DB_IO ACPI_DEBUG_LEVEL (ACPI_LV_IO) +#define ACPI_DB_INTERRUPTS ACPI_DEBUG_LEVEL (ACPI_LV_INTERRUPTS) +#define ACPI_DB_USER_REQUESTS ACPI_DEBUG_LEVEL (ACPI_LV_USER_REQUESTS) +#define ACPI_DB_PACKAGE ACPI_DEBUG_LEVEL (ACPI_LV_PACKAGE) +#define ACPI_DB_MUTEX ACPI_DEBUG_LEVEL (ACPI_LV_MUTEX) + +#define ACPI_DB_ALL ACPI_DEBUG_LEVEL (ACPI_LV_ALL) + + +/* Defaults for debug_level, debug and normal */ + +#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) +#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) +#define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) + + +#endif /* __ACOUTPUT_H__ */ diff -Nru a/include/acpi/acparser.h b/include/acpi/acparser.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acparser.h Sun Feb 9 21:13:33 2003 @@ -0,0 +1,328 @@ +/****************************************************************************** + * + * Module Name: acparser.h - AML Parser subcomponent prototypes and defines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + + +#ifndef __ACPARSER_H__ +#define __ACPARSER_H__ + + +#define OP_HAS_RETURN_VALUE 1 + +/* variable # arguments */ + +#define ACPI_VAR_ARGS ACPI_UINT32_MAX + + +#define ACPI_PARSE_DELETE_TREE 0x0001 +#define ACPI_PARSE_NO_TREE_DELETE 0x0000 +#define ACPI_PARSE_TREE_MASK 0x0001 + +#define ACPI_PARSE_LOAD_PASS1 0x0010 +#define ACPI_PARSE_LOAD_PASS2 0x0020 +#define ACPI_PARSE_EXECUTE 0x0030 +#define ACPI_PARSE_MODE_MASK 0x0030 + +#define ACPI_PARSE_DEFERRED_OP 0x0100 + +/* Parser external interfaces */ + +acpi_status +acpi_psx_load_table ( + u8 *pcode_addr, + u32 pcode_length); + +acpi_status +acpi_psx_execute ( + struct acpi_namespace_node *method_node, + union acpi_operand_object **params, + union acpi_operand_object **return_obj_desc); + + +/****************************************************************************** + * + * Parser interfaces + * + *****************************************************************************/ + + +/* psargs - Parse AML opcode arguments */ + +u8 * +acpi_ps_get_next_package_end ( + struct acpi_parse_state *parser_state); + +u32 +acpi_ps_get_next_package_length ( + struct acpi_parse_state *parser_state); + +char * +acpi_ps_get_next_namestring ( + struct acpi_parse_state *parser_state); + +void +acpi_ps_get_next_simple_arg ( + struct acpi_parse_state *parser_state, + u32 arg_type, + union acpi_parse_object *arg); + +acpi_status +acpi_ps_get_next_namepath ( + struct acpi_walk_state *walk_state, + struct acpi_parse_state *parser_state, + union acpi_parse_object *arg, + u8 method_call); + +union acpi_parse_object * +acpi_ps_get_next_field ( + struct acpi_parse_state *parser_state); + +acpi_status +acpi_ps_get_next_arg ( + struct acpi_walk_state *walk_state, + struct acpi_parse_state *parser_state, + u32 arg_type, + union acpi_parse_object **return_arg); + + +/* psfind */ + +union acpi_parse_object * +acpi_ps_find_name ( + union acpi_parse_object *scope, + u32 name, + u32 opcode); + +union acpi_parse_object* +acpi_ps_get_parent ( + union acpi_parse_object *op); + + +/* psopcode - AML Opcode information */ + +const struct acpi_opcode_info * +acpi_ps_get_opcode_info ( + u16 opcode); + +char * +acpi_ps_get_opcode_name ( + u16 opcode); + + +/* psparse - top level parsing routines */ + +u32 +acpi_ps_get_opcode_size ( + u32 opcode); + +void +acpi_ps_complete_this_op ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + +acpi_status +acpi_ps_next_parse_state ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + acpi_status callback_status); + +acpi_status +acpi_ps_find_object ( + struct acpi_walk_state *walk_state, + union acpi_parse_object **out_op); + +void +acpi_ps_delete_parse_tree ( + union acpi_parse_object *root); + +acpi_status +acpi_ps_parse_loop ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ps_parse_aml ( + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ps_parse_table ( + u8 *aml, + u32 aml_size, + acpi_parse_downwards descending_callback, + acpi_parse_upwards ascending_callback, + union acpi_parse_object **root_object); + +u16 +acpi_ps_peek_opcode ( + struct acpi_parse_state *state); + + +/* psscope - Scope stack management routines */ + + +acpi_status +acpi_ps_init_scope ( + struct acpi_parse_state *parser_state, + union acpi_parse_object *root); + +union acpi_parse_object * +acpi_ps_get_parent_scope ( + struct acpi_parse_state *state); + +u8 +acpi_ps_has_completed_scope ( + struct acpi_parse_state *parser_state); + +void +acpi_ps_pop_scope ( + struct acpi_parse_state *parser_state, + union acpi_parse_object **op, + u32 *arg_list, + u32 *arg_count); + +acpi_status +acpi_ps_push_scope ( + struct acpi_parse_state *parser_state, + union acpi_parse_object *op, + u32 remaining_args, + u32 arg_count); + +void +acpi_ps_cleanup_scope ( + struct acpi_parse_state *state); + + +/* pstree - parse tree manipulation routines */ + +void +acpi_ps_append_arg( + union acpi_parse_object *op, + union acpi_parse_object *arg); + +union acpi_parse_object* +acpi_ps_find ( + union acpi_parse_object *scope, + char *path, + u16 opcode, + u32 create); + +union acpi_parse_object * +acpi_ps_get_arg( + union acpi_parse_object *op, + u32 argn); + +union acpi_parse_object * +acpi_ps_get_child ( + union acpi_parse_object *op); + +union acpi_parse_object * +acpi_ps_get_depth_next ( + union acpi_parse_object *origin, + union acpi_parse_object *op); + + +/* pswalk - parse tree walk routines */ + +acpi_status +acpi_ps_walk_parsed_aml ( + union acpi_parse_object *start_op, + union acpi_parse_object *end_op, + union acpi_operand_object *mth_desc, + struct acpi_namespace_node *start_node, + union acpi_operand_object **params, + union acpi_operand_object **caller_return_desc, + acpi_owner_id owner_id, + acpi_parse_downwards descending_callback, + acpi_parse_upwards ascending_callback); + +acpi_status +acpi_ps_get_next_walk_op ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op, + acpi_parse_upwards ascending_callback); + +acpi_status +acpi_ps_delete_completed_op ( + struct acpi_walk_state *walk_state); + + +/* psutils - parser utilities */ + +union acpi_parse_object * +acpi_ps_create_scope_op ( + void); + +void +acpi_ps_init_op ( + union acpi_parse_object *op, + u16 opcode); + +union acpi_parse_object * +acpi_ps_alloc_op ( + u16 opcode); + +void +acpi_ps_free_op ( + union acpi_parse_object *op); + +void +acpi_ps_delete_parse_cache ( + void); + +u8 +acpi_ps_is_leading_char ( + u32 c); + +u8 +acpi_ps_is_prefix_char ( + u32 c); + +u32 +acpi_ps_get_name( + union acpi_parse_object *op); + +void +acpi_ps_set_name( + union acpi_parse_object *op, + u32 name); + + +/* psdump - display parser tree */ + +u32 +acpi_ps_sprint_path ( + char *buffer_start, + u32 buffer_size, + union acpi_parse_object *op); + +u32 +acpi_ps_sprint_op ( + char *buffer_start, + u32 buffer_size, + union acpi_parse_object *op); + +void +acpi_ps_show ( + union acpi_parse_object *op); + + +#endif /* __ACPARSER_H__ */ diff -Nru a/include/acpi/acpi.h b/include/acpi/acpi.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acpi.h Sun Feb 9 21:13:32 2003 @@ -0,0 +1,50 @@ +/****************************************************************************** + * + * Name: acpi.h - Master include file, Publics and external data. + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACPI_H__ +#define __ACPI_H__ + +/* + * Common includes for all ACPI driver files + * 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 */ + + +#endif /* __ACPI_H__ */ diff -Nru a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acpi_bus.h Sun Feb 9 21:13:31 2003 @@ -0,0 +1,312 @@ +/* + * acpi_bus.h - ACPI Bus Driver ($Revision: 22 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#ifndef __ACPI_BUS_H__ +#define __ACPI_BUS_H__ + +#include +#include + +#include + +#define PREFIX "ACPI: " + +extern int acpi_disabled; + +/* TBD: Make dynamic */ +#define ACPI_MAX_HANDLES 10 +struct acpi_handle_list { + u32 count; + acpi_handle handles[ACPI_MAX_HANDLES]; +}; + + +/* acpi_utils.h */ +acpi_status +acpi_extract_package ( + union acpi_object *package, + struct acpi_buffer *format, + struct acpi_buffer *buffer); +acpi_status +acpi_evaluate_integer ( + acpi_handle handle, + acpi_string pathname, + struct acpi_object_list *arguments, + unsigned long *data); +acpi_status +acpi_evaluate_reference ( + acpi_handle handle, + acpi_string pathname, + struct acpi_object_list *arguments, + struct acpi_handle_list *list); + + +#ifdef CONFIG_ACPI_BUS + +#include + +#define ACPI_BUS_FILE_ROOT "acpi" +extern struct proc_dir_entry *acpi_root_dir; +extern FADT_DESCRIPTOR acpi_fadt; + +enum acpi_bus_removal_type { + ACPI_BUS_REMOVAL_NORMAL = 0, + ACPI_BUS_REMOVAL_EJECT, + ACPI_BUS_REMOVAL_SUPRISE, + ACPI_BUS_REMOVAL_TYPE_COUNT +}; + +enum acpi_bus_device_type { + ACPI_BUS_TYPE_DEVICE = 0, + ACPI_BUS_TYPE_POWER, + ACPI_BUS_TYPE_PROCESSOR, + ACPI_BUS_TYPE_THERMAL, + ACPI_BUS_TYPE_SYSTEM, + ACPI_BUS_TYPE_POWER_BUTTON, + ACPI_BUS_TYPE_SLEEP_BUTTON, + ACPI_BUS_DEVICE_TYPE_COUNT +}; + +struct acpi_driver; +struct acpi_device; + + +/* + * ACPI Driver + * ----------- + */ + +typedef int (*acpi_op_add) (struct acpi_device *device); +typedef int (*acpi_op_remove) (struct acpi_device *device, int type); +typedef int (*acpi_op_lock) (struct acpi_device *device, int type); +typedef int (*acpi_op_start) (struct acpi_device *device); +typedef int (*acpi_op_stop) (struct acpi_device *device, int type); +typedef int (*acpi_op_suspend) (struct acpi_device *device, int state); +typedef int (*acpi_op_resume) (struct acpi_device *device, int state); +typedef int (*acpi_op_scan) (struct acpi_device *device); +typedef int (*acpi_op_bind) (struct acpi_device *device); + +struct acpi_device_ops { + acpi_op_add add; + acpi_op_remove remove; + acpi_op_lock lock; + acpi_op_start start; + acpi_op_stop stop; + acpi_op_suspend suspend; + acpi_op_resume resume; + acpi_op_scan scan; + acpi_op_bind bind; +}; + +struct acpi_driver { + struct list_head node; + char name[80]; + char class[80]; + atomic_t references; + char *ids; /* Supported Hardware IDs */ + struct acpi_device_ops ops; +}; + +/* + * ACPI Device + * ----------- + */ + +/* Status (_STA) */ + +struct acpi_device_status { + u32 present:1; + u32 enabled:1; + u32 show_in_ui:1; + u32 functional:1; + u32 battery_present:1; + u32 reserved:27; +}; + + +/* Flags */ + +struct acpi_device_flags { + u32 dynamic_status:1; + u32 hardware_id:1; + u32 compatible_ids:1; + u32 bus_address:1; + u32 unique_id:1; + u32 removable:1; + u32 ejectable:1; + u32 lockable:1; + u32 suprise_removal_ok:1; + u32 power_manageable:1; + u32 performance_manageable:1; + u32 reserved:21; +}; + + +/* File System */ + +struct acpi_device_dir { + struct proc_dir_entry *entry; +}; + +#define acpi_device_dir(d) ((d)->dir.entry) + + +/* Plug and Play */ + +typedef char acpi_bus_id[5]; +typedef unsigned long acpi_bus_address; +typedef char acpi_hardware_id[9]; +typedef char acpi_unique_id[9]; +typedef char acpi_device_name[40]; +typedef char acpi_device_class[20]; + +struct acpi_device_pnp { + acpi_bus_id bus_id; /* Object name */ + acpi_bus_address bus_address; /* _ADR */ + acpi_hardware_id hardware_id; /* _HID */ + acpi_unique_id unique_id; /* _UID */ + acpi_device_name device_name; /* Driver-determined */ + acpi_device_class device_class; /* " */ +}; + +#define acpi_device_bid(d) ((d)->pnp.bus_id) +#define acpi_device_adr(d) ((d)->pnp.bus_address) +#define acpi_device_hid(d) ((d)->pnp.hardware_id) +#define acpi_device_uid(d) ((d)->pnp.unique_id) +#define acpi_device_name(d) ((d)->pnp.device_name) +#define acpi_device_class(d) ((d)->pnp.device_class) + + +/* Power Management */ + +struct acpi_device_power_flags { + u32 explicit_get:1; /* _PSC present? */ + u32 power_resources:1; /* Power resources */ + u32 inrush_current:1; /* Serialize Dx->D0 */ + u32 wake_capable:1; /* Wakeup supported? */ + u32 wake_enabled:1; /* Enabled for wakeup */ + u32 power_removed:1; /* Optimize Dx->D0 */ + u32 reserved:26; +}; + +struct acpi_device_power_state { + struct { + u8 valid:1; + u8 explicit_set:1; /* _PSx present? */ + u8 reserved:6; + } flags; + int power; /* % Power (compared to D0) */ + int latency; /* Dx->D0 time (microseconds) */ + struct acpi_handle_list resources; /* Power resources referenced */ +}; + +struct acpi_device_power { + int state; /* Current state */ + struct acpi_device_power_flags flags; + struct acpi_device_power_state states[4]; /* Power states (D0-D3) */ +}; + + +/* Performance Management */ + +struct acpi_device_perf_flags { + u8 reserved:8; +}; + +struct acpi_device_perf_state { + struct { + u8 valid:1; + u8 reserved:7; + } flags; + u8 power; /* % Power (compared to P0) */ + u8 performance; /* % Performance ( " ) */ + int latency; /* Px->P0 time (microseconds) */ +}; + +struct acpi_device_perf { + int state; + struct acpi_device_perf_flags flags; + int state_count; + struct acpi_device_perf_state *states; +}; + + +/* Device */ + +struct acpi_device { + acpi_handle handle; + struct acpi_device *parent; + struct list_head children; + struct list_head node; + struct list_head g_list; + struct acpi_device_status status; + struct acpi_device_flags flags; + struct acpi_device_pnp pnp; + struct acpi_device_power power; + struct acpi_device_perf performance; + struct acpi_device_dir dir; + struct acpi_device_ops ops; + struct acpi_driver *driver; + void *driver_data; + struct kobject kobj; +}; + +#define acpi_driver_data(d) ((d)->driver_data) + + +/* + * Events + * ------ + */ + +struct acpi_bus_event { + struct list_head node; + acpi_device_class device_class; + acpi_bus_id bus_id; + u32 type; + u32 data; +}; + +extern struct subsystem acpi_subsys; + +/* + * External Functions + */ + +int acpi_bus_get_device(acpi_handle, struct acpi_device **device); +int acpi_bus_get_status (struct acpi_device *device); +int acpi_bus_get_power (acpi_handle handle, int *state); +int acpi_bus_set_power (acpi_handle handle, int state); +int acpi_bus_generate_event (struct acpi_device *device, u8 type, int data); +int acpi_bus_receive_event (struct acpi_bus_event *event); +int acpi_bus_register_driver (struct acpi_driver *driver); +int acpi_bus_unregister_driver (struct acpi_driver *driver); + +int acpi_create_dir(struct acpi_device *); +void acpi_remove_dir(struct acpi_device *); + +#endif /*CONFIG_ACPI_BUS*/ + +#endif /*__ACPI_BUS_H__*/ diff -Nru a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acpi_drivers.h Sun Feb 9 21:13:34 2003 @@ -0,0 +1,163 @@ +/* + * acpi_drivers.h ($Revision: 31 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#ifndef __ACPI_DRIVERS_H__ +#define __ACPI_DRIVERS_H__ + +#include +#include "acpi_bus.h" + + +#define ACPI_MAX_STRING 80 + +#define ACPI_BUS_COMPONENT 0x00010000 +#define ACPI_SYSTEM_COMPONENT 0x02000000 + +/* _HID definitions */ + +#define ACPI_POWER_HID "ACPI_PWR" +#define ACPI_PROCESSOR_HID "ACPI_CPU" +#define ACPI_SYSTEM_HID "ACPI_SYS" +#define ACPI_THERMAL_HID "ACPI_THM" +#define ACPI_BUTTON_HID_POWERF "ACPI_FPB" +#define ACPI_BUTTON_HID_SLEEPF "ACPI_FSB" + + +/* -------------------------------------------------------------------------- + PCI + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_PCI + +#define ACPI_PCI_COMPONENT 0x00400000 + +/* ACPI PCI Root Bridge (pci_root.c) */ + +void acpi_pci_get_translations (struct acpi_pci_id* id, u64* mem_tra, u64* io_tra); + +/* ACPI PCI Interrupt Link (pci_link.c) */ + +int acpi_pci_link_check (void); +int acpi_pci_link_get_irq (acpi_handle handle, int index); + +/* ACPI PCI Interrupt Routing (pci_irq.c) */ + +int acpi_pci_irq_add_prt (acpi_handle handle, int segment, int bus); + +/* ACPI PCI Device Binding (pci_bind.c) */ + +struct pci_bus; + +int acpi_pci_bind (struct acpi_device *device); +int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus); + +#endif /*CONFIG_ACPI_PCI*/ + + +/* -------------------------------------------------------------------------- + Power Resource + -------------------------------------------------------------------------- */ + +#ifdef CONFIG_ACPI_POWER + +int acpi_power_get_inferred_state (struct acpi_device *device); +int acpi_power_transition (struct acpi_device *device, int state); +#endif + + +/* -------------------------------------------------------------------------- + Embedded Controller + -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_EC +int acpi_ec_ecdt_probe (void); +#endif + +/* -------------------------------------------------------------------------- + Processor + -------------------------------------------------------------------------- */ + +#define ACPI_PROCESSOR_LIMIT_NONE 0x00 +#define ACPI_PROCESSOR_LIMIT_INCREMENT 0x01 +#define ACPI_PROCESSOR_LIMIT_DECREMENT 0x02 + +int acpi_processor_set_thermal_limit(acpi_handle handle, int type); + + +/* -------------------------------------------------------------------------- + Debug Support + -------------------------------------------------------------------------- */ + +#define ACPI_DEBUG_RESTORE 0 +#define ACPI_DEBUG_LOW 1 +#define ACPI_DEBUG_MEDIUM 2 +#define ACPI_DEBUG_HIGH 3 +#define ACPI_DEBUG_DRIVERS 4 + +extern u32 acpi_dbg_level; +extern u32 acpi_dbg_layer; + +static inline void +acpi_set_debug ( + u32 flag) +{ + static u32 layer_save; + static u32 level_save; + + switch (flag) { + case ACPI_DEBUG_RESTORE: + acpi_dbg_layer = layer_save; + acpi_dbg_level = level_save; + break; + case ACPI_DEBUG_LOW: + case ACPI_DEBUG_MEDIUM: + case ACPI_DEBUG_HIGH: + case ACPI_DEBUG_DRIVERS: + layer_save = acpi_dbg_layer; + level_save = acpi_dbg_level; + break; + } + + switch (flag) { + case ACPI_DEBUG_LOW: + acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS; + acpi_dbg_level = ACPI_DEBUG_DEFAULT; + break; + case ACPI_DEBUG_MEDIUM: + acpi_dbg_layer = ACPI_COMPONENT_DEFAULT | ACPI_ALL_DRIVERS; + acpi_dbg_level = ACPI_LV_FUNCTIONS | ACPI_LV_ALL_EXCEPTIONS; + break; + case ACPI_DEBUG_HIGH: + acpi_dbg_layer = 0xFFFFFFFF; + acpi_dbg_level = 0xFFFFFFFF; + break; + case ACPI_DEBUG_DRIVERS: + acpi_dbg_layer = ACPI_ALL_DRIVERS; + acpi_dbg_level = 0xFFFFFFFF; + break; + } +} + + +#endif /*__ACPI_DRIVERS_H__*/ diff -Nru a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acpiosxf.h Sun Feb 9 21:13:28 2003 @@ -0,0 +1,344 @@ + +/****************************************************************************** + * + * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL). These + * interfaces must be implemented by OSL to interface the + * ACPI components to the host operating system. + * + *****************************************************************************/ + + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACPIOSXF_H__ +#define __ACPIOSXF_H__ + +#include "platform/acenv.h" +#include "actypes.h" + + +/* Priorities for acpi_os_queue_for_execution */ + +#define OSD_PRIORITY_GPE 1 +#define OSD_PRIORITY_HIGH 2 +#define OSD_PRIORITY_MED 3 +#define OSD_PRIORITY_LO 4 + +#define ACPI_NO_UNIT_LIMIT ((u32) -1) +#define ACPI_MUTEX_SEM 1 + + +/* Functions for acpi_os_signal */ + +#define ACPI_SIGNAL_FATAL 0 +#define ACPI_SIGNAL_BREAKPOINT 1 + +struct acpi_signal_fatal_info +{ + u32 type; + u32 code; + u32 argument; +}; + + +/* + * Types specific to the OS service interfaces + */ + +typedef u32 +(ACPI_SYSTEM_XFACE *OSD_HANDLER) ( + void *context); + +typedef void +(ACPI_SYSTEM_XFACE *OSD_EXECUTION_CALLBACK) ( + void *context); + + +/* + * OSL Initialization and shutdown primitives + */ + +acpi_status +acpi_os_initialize ( + void); + +acpi_status +acpi_os_terminate ( + void); + + +/* + * ACPI Table interfaces + */ + +acpi_status +acpi_os_get_root_pointer ( + u32 flags, + struct acpi_pointer *address); + +acpi_status +acpi_os_table_override ( + struct acpi_table_header *existing_table, + struct acpi_table_header **new_table); + + +/* + * Synchronization primitives + */ + +acpi_status +acpi_os_create_semaphore ( + u32 max_units, + u32 initial_units, + acpi_handle *out_handle); + +acpi_status +acpi_os_delete_semaphore ( + acpi_handle handle); + +acpi_status +acpi_os_wait_semaphore ( + acpi_handle handle, + u32 units, + u16 timeout); + +acpi_status +acpi_os_signal_semaphore ( + acpi_handle handle, + u32 units); + + +/* + * Memory allocation and mapping + */ + +void * +acpi_os_allocate ( + acpi_size size); + +void +acpi_os_free ( + void * memory); + +acpi_status +acpi_os_map_memory ( + acpi_physical_address physical_address, + acpi_size size, + void **logical_address); + +void +acpi_os_unmap_memory ( + void *logical_address, + acpi_size size); + +acpi_status +acpi_os_get_physical_address ( + void *logical_address, + acpi_physical_address *physical_address); + + +/* + * Interrupt handlers + */ + +acpi_status +acpi_os_install_interrupt_handler ( + u32 interrupt_number, + OSD_HANDLER service_routine, + void *context); + +acpi_status +acpi_os_remove_interrupt_handler ( + u32 interrupt_number, + OSD_HANDLER service_routine); + + +/* + * Threads and Scheduling + */ + +u32 +acpi_os_get_thread_id ( + void); + +acpi_status +acpi_os_queue_for_execution ( + u32 priority, + OSD_EXECUTION_CALLBACK function, + void *context); + +void +acpi_os_sleep ( + u32 seconds, + u32 milliseconds); + +void +acpi_os_stall ( + u32 microseconds); + + +/* + * Platform and hardware-independent I/O interfaces + */ + +acpi_status +acpi_os_read_port ( + acpi_io_address address, + void *value, + u32 width); + +acpi_status +acpi_os_write_port ( + acpi_io_address address, + acpi_integer value, + u32 width); + + +/* + * Platform and hardware-independent physical memory interfaces + */ + +acpi_status +acpi_os_read_memory ( + acpi_physical_address address, + void *value, + u32 width); + +acpi_status +acpi_os_write_memory ( + acpi_physical_address address, + acpi_integer value, + u32 width); + + +/* + * Platform and hardware-independent PCI configuration space access + */ + +acpi_status +acpi_os_read_pci_configuration ( + struct acpi_pci_id *pci_id, + u32 register, + void *value, + u32 width); + +acpi_status +acpi_os_write_pci_configuration ( + struct acpi_pci_id *pci_id, + u32 register, + acpi_integer value, + u32 width); + +/* + * Interim function needed for PCI IRQ routing + */ +void +acpi_os_derive_pci_id( + acpi_handle rhandle, + acpi_handle chandle, + struct acpi_pci_id **pci_id); + +/* + * Miscellaneous + */ + +u8 +acpi_os_readable ( + void *pointer, + u32 length); + +u8 +acpi_os_writable ( + void *pointer, + u32 length); + +u32 +acpi_os_get_timer ( + void); + +acpi_status +acpi_os_signal ( + u32 function, + void *info); + +/* + * Debug print routines + */ + +void ACPI_INTERNAL_VAR_XFACE +acpi_os_printf ( + const char *format, + ...); + +void +acpi_os_vprintf ( + const char *format, + va_list args); + +void +acpi_os_redirect_output ( + void *destination); + + +/* + * Debug input + */ + +u32 +acpi_os_get_line ( + char *buffer); + + +/* + * Directory manipulation + */ + +void * +acpi_os_open_directory ( + char *pathname, + char *wildcard_spec, + char requested_file_type); + +/* requeste_file_type values */ + +#define REQUEST_FILE_ONLY 0 +#define REQUEST_DIR_ONLY 1 + + +char * +acpi_os_get_next_filename ( + void *dir_handle); + +void +acpi_os_close_directory ( + void *dir_handle); + +/* + * Debug + */ + +void +acpi_os_dbg_assert( + void *failed_assertion, + void *file_name, + u32 line_number, + char *message); + + +#endif /* __ACPIOSXF_H__ */ diff -Nru a/include/acpi/acpixf.h b/include/acpi/acpixf.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acpixf.h Sun Feb 9 21:13:28 2003 @@ -0,0 +1,387 @@ + +/****************************************************************************** + * + * Name: acpixf.h - External interfaces to the ACPI subsystem + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + + +#ifndef __ACXFACE_H__ +#define __ACXFACE_H__ + +#include "actypes.h" +#include "actbl.h" + + + /* + * Global interfaces + */ + +acpi_status +acpi_initialize_subsystem ( + void); + +acpi_status +acpi_enable_subsystem ( + u32 flags); + +acpi_status +acpi_initialize_objects ( + u32 flags); + +acpi_status +acpi_terminate ( + void); + +acpi_status +acpi_subsystem_status ( + void); + +acpi_status +acpi_enable ( + void); + +acpi_status +acpi_disable ( + void); + +acpi_status +acpi_get_system_info ( + struct acpi_buffer *ret_buffer); + +const char * +acpi_format_exception ( + acpi_status exception); + +acpi_status +acpi_purge_cached_objects ( + void); + +acpi_status +acpi_install_initialization_handler ( + acpi_init_handler handler, + u32 function); + +/* + * ACPI Memory manager + */ + +void * +acpi_allocate ( + u32 size); + +void * +acpi_callocate ( + u32 size); + +void +acpi_free ( + void *address); + + +/* + * ACPI table manipulation interfaces + */ + +acpi_status +acpi_find_root_pointer ( + u32 flags, + struct acpi_pointer *rsdp_address); + +acpi_status +acpi_load_tables ( + void); + +acpi_status +acpi_load_table ( + struct acpi_table_header *table_ptr); + +acpi_status +acpi_unload_table ( + acpi_table_type table_type); + +acpi_status +acpi_get_table_header ( + acpi_table_type table_type, + u32 instance, + struct acpi_table_header *out_table_header); + +acpi_status +acpi_get_table ( + acpi_table_type table_type, + u32 instance, + struct acpi_buffer *ret_buffer); + +acpi_status +acpi_get_firmware_table ( + acpi_string signature, + u32 instance, + u32 flags, + struct acpi_table_header **table_pointer); + + +/* + * Namespace and name interfaces + */ + +acpi_status +acpi_walk_namespace ( + acpi_object_type type, + acpi_handle start_object, + u32 max_depth, + acpi_walk_callback user_function, + void *context, + void **return_value); + +acpi_status +acpi_get_devices ( + char *HID, + acpi_walk_callback user_function, + void *context, + void **return_value); + +acpi_status +acpi_get_name ( + acpi_handle handle, + u32 name_type, + struct acpi_buffer *ret_path_ptr); + +acpi_status +acpi_get_handle ( + acpi_handle parent, + acpi_string pathname, + acpi_handle *ret_handle); + +acpi_status +acpi_attach_data ( + acpi_handle obj_handle, + acpi_object_handler handler, + void *data); + +acpi_status +acpi_detach_data ( + acpi_handle obj_handle, + acpi_object_handler handler); + +acpi_status +acpi_get_data ( + acpi_handle obj_handle, + acpi_object_handler handler, + void **data); + + +/* + * Object manipulation and enumeration + */ + +acpi_status +acpi_evaluate_object ( + acpi_handle object, + acpi_string pathname, + struct acpi_object_list *parameter_objects, + struct acpi_buffer *return_object_buffer); + +acpi_status +acpi_evaluate_object_typed ( + acpi_handle object, + acpi_string pathname, + struct acpi_object_list *external_params, + struct acpi_buffer *return_buffer, + acpi_object_type return_type); + +acpi_status +acpi_get_object_info ( + acpi_handle device, + struct acpi_device_info *info); + +acpi_status +acpi_get_next_object ( + acpi_object_type type, + acpi_handle parent, + acpi_handle child, + acpi_handle *out_handle); + +acpi_status +acpi_get_type ( + acpi_handle object, + acpi_object_type *out_type); + +acpi_status +acpi_get_parent ( + acpi_handle object, + acpi_handle *out_handle); + + +/* + * Event handler interfaces + */ + +acpi_status +acpi_install_fixed_event_handler ( + u32 acpi_event, + acpi_event_handler handler, + void *context); + +acpi_status +acpi_remove_fixed_event_handler ( + u32 acpi_event, + acpi_event_handler handler); + +acpi_status +acpi_install_notify_handler ( + acpi_handle device, + u32 handler_type, + acpi_notify_handler handler, + void *context); + +acpi_status +acpi_remove_notify_handler ( + acpi_handle device, + u32 handler_type, + acpi_notify_handler handler); + +acpi_status +acpi_install_address_space_handler ( + acpi_handle device, + acpi_adr_space_type space_id, + acpi_adr_space_handler handler, + acpi_adr_space_setup setup, + void *context); + +acpi_status +acpi_remove_address_space_handler ( + acpi_handle device, + acpi_adr_space_type space_id, + acpi_adr_space_handler handler); + +acpi_status +acpi_install_gpe_handler ( + u32 gpe_number, + u32 type, + acpi_gpe_handler handler, + void *context); + +acpi_status +acpi_acquire_global_lock ( + u16 timeout, + u32 *handle); + +acpi_status +acpi_release_global_lock ( + u32 handle); + +acpi_status +acpi_remove_gpe_handler ( + u32 gpe_number, + acpi_gpe_handler handler); + +acpi_status +acpi_enable_event ( + u32 acpi_event, + u32 type, + u32 flags); + +acpi_status +acpi_disable_event ( + u32 acpi_event, + u32 type, + u32 flags); + +acpi_status +acpi_clear_event ( + u32 acpi_event, + u32 type); + +acpi_status +acpi_get_event_status ( + u32 acpi_event, + u32 type, + acpi_event_status *event_status); + +/* + * Resource interfaces + */ + +acpi_status +acpi_get_current_resources( + acpi_handle device_handle, + struct acpi_buffer *ret_buffer); + +acpi_status +acpi_get_possible_resources( + acpi_handle device_handle, + struct acpi_buffer *ret_buffer); + +acpi_status +acpi_set_current_resources ( + acpi_handle device_handle, + struct acpi_buffer *in_buffer); + +acpi_status +acpi_get_irq_routing_table ( + acpi_handle bus_device_handle, + struct acpi_buffer *ret_buffer); + + +/* + * Hardware (ACPI device) interfaces + */ + +acpi_status +acpi_get_register ( + u32 register_id, + u32 *return_value, + u32 flags); + +acpi_status +acpi_set_register ( + u32 register_id, + u32 value, + u32 flags); + +acpi_status +acpi_set_firmware_waking_vector ( + acpi_physical_address physical_address); + +acpi_status +acpi_get_firmware_waking_vector ( + acpi_physical_address *physical_address); + +acpi_status +acpi_get_sleep_type_data ( + u8 sleep_state, + u8 *slp_typ_a, + u8 *slp_typ_b); + +acpi_status +acpi_enter_sleep_state_prep ( + u8 sleep_state); + +acpi_status +acpi_enter_sleep_state ( + u8 sleep_state); + +acpi_status +acpi_leave_sleep_state ( + u8 sleep_state); + + +#endif /* __ACXFACE_H__ */ diff -Nru a/include/acpi/acresrc.h b/include/acpi/acresrc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acresrc.h Sun Feb 9 21:13:29 2003 @@ -0,0 +1,366 @@ +/****************************************************************************** + * + * Name: acresrc.h - Resource Manager function prototypes + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACRESRC_H__ +#define __ACRESRC_H__ + + +/* + * Function prototypes called from Acpi* APIs + */ + +acpi_status +acpi_rs_get_prt_method_data ( + acpi_handle handle, + struct acpi_buffer *ret_buffer); + + +acpi_status +acpi_rs_get_crs_method_data ( + acpi_handle handle, + struct acpi_buffer *ret_buffer); + +acpi_status +acpi_rs_get_prs_method_data ( + acpi_handle handle, + struct acpi_buffer *ret_buffer); + +acpi_status +acpi_rs_set_srs_method_data ( + acpi_handle handle, + struct acpi_buffer *ret_buffer); + +acpi_status +acpi_rs_create_resource_list ( + union acpi_operand_object *byte_stream_buffer, + struct acpi_buffer *output_buffer); + +acpi_status +acpi_rs_create_byte_stream ( + struct acpi_resource *linked_list_buffer, + struct acpi_buffer *output_buffer); + +acpi_status +acpi_rs_create_pci_routing_table ( + union acpi_operand_object *package_object, + struct acpi_buffer *output_buffer); + + +/* + * Function prototypes called from acpi_rs_create* + */ +void +acpi_rs_dump_irq ( + union acpi_resource_data *data); + +void +acpi_rs_dump_address16 ( + union acpi_resource_data *data); + +void +acpi_rs_dump_address32 ( + union acpi_resource_data *data); + +void +acpi_rs_dump_address64 ( + union acpi_resource_data *data); + +void +acpi_rs_dump_dma ( + union acpi_resource_data *data); + +void +acpi_rs_dump_io ( + union acpi_resource_data *data); + +void +acpi_rs_dump_extended_irq ( + union acpi_resource_data *data); + +void +acpi_rs_dump_fixed_io ( + union acpi_resource_data *data); + +void +acpi_rs_dump_fixed_memory32 ( + union acpi_resource_data *data); + +void +acpi_rs_dump_memory24 ( + union acpi_resource_data *data); + +void +acpi_rs_dump_memory32 ( + union acpi_resource_data *data); + +void +acpi_rs_dump_start_depend_fns ( + union acpi_resource_data *data); + +void +acpi_rs_dump_vendor_specific ( + union acpi_resource_data *data); + +void +acpi_rs_dump_resource_list ( + struct acpi_resource *resource); + +void +acpi_rs_dump_irq_list ( + u8 *route_table); + +acpi_status +acpi_rs_get_byte_stream_start ( + u8 *byte_stream_buffer, + u8 **byte_stream_start, + u32 *size); + +acpi_status +acpi_rs_get_list_length ( + u8 *byte_stream_buffer, + u32 byte_stream_buffer_length, + acpi_size *size_needed); + +acpi_status +acpi_rs_get_byte_stream_length ( + struct acpi_resource *linked_list_buffer, + acpi_size *size_needed); + +acpi_status +acpi_rs_get_pci_routing_table_length ( + union acpi_operand_object *package_object, + acpi_size *buffer_size_needed); + +acpi_status +acpi_rs_byte_stream_to_list ( + u8 *byte_stream_buffer, + u32 byte_stream_buffer_length, + u8 *output_buffer); + +acpi_status +acpi_rs_list_to_byte_stream ( + struct acpi_resource *linked_list, + acpi_size byte_stream_size_needed, + u8 *output_buffer); + +acpi_status +acpi_rs_io_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_fixed_io_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_io_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_fixed_io_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_irq_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_irq_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_dma_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_dma_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_address16_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_address16_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_address32_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_address32_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_address64_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_address64_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_start_depend_fns_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_end_depend_fns_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_start_depend_fns_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_end_depend_fns_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_memory24_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_memory24_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_memory32_range_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_fixed_memory32_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_memory32_range_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_fixed_memory32_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_extended_irq_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_extended_irq_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_end_tag_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_end_tag_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +acpi_status +acpi_rs_vendor_resource ( + u8 *byte_stream_buffer, + acpi_size *bytes_consumed, + u8 **output_buffer, + acpi_size *structure_size); + +acpi_status +acpi_rs_vendor_stream ( + struct acpi_resource *linked_list, + u8 **output_buffer, + acpi_size *bytes_consumed); + +u8 +acpi_rs_get_resource_type ( + u8 resource_start_byte); + +#endif /* __ACRESRC_H__ */ diff -Nru a/include/acpi/acstruct.h b/include/acpi/acstruct.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acstruct.h Sun Feb 9 21:13:29 2003 @@ -0,0 +1,183 @@ +/****************************************************************************** + * + * Name: acstruct.h - Internal structs + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACSTRUCT_H__ +#define __ACSTRUCT_H__ + + +/***************************************************************************** + * + * Tree walking typedefs and structs + * + ****************************************************************************/ + + +/* + * Walk state - current state of a parse tree walk. Used for both a leisurely stroll through + * the tree (for whatever reason), and for control method execution. + */ + +#define ACPI_NEXT_OP_DOWNWARD 1 +#define ACPI_NEXT_OP_UPWARD 2 + +#define ACPI_WALK_NON_METHOD 0 +#define ACPI_WALK_METHOD 1 +#define ACPI_WALK_METHOD_RESTART 2 +#define ACPI_WALK_CONST_REQUIRED 3 +#define ACPI_WALK_CONST_OPTIONAL 4 + +struct acpi_walk_state +{ + u8 data_type; /* To differentiate various internal objs MUST BE FIRST!*/\ + acpi_owner_id owner_id; /* Owner of objects created during the walk */ + u8 last_predicate; /* Result of last predicate */ + u8 current_result; /* */ + u8 next_op_info; /* Info about next_op */ + u8 num_operands; /* Stack pointer for Operands[] array */ + u8 return_used; + u8 walk_type; + u16 opcode; /* Current AML opcode */ + u8 scope_depth; + u8 reserved1; + u32 arg_count; /* push for fixed or var args */ + u32 aml_offset; + u32 arg_types; + u32 method_breakpoint; /* For single stepping */ + u32 user_breakpoint; /* User AML breakpoint */ + u32 parse_flags; + u32 prev_arg_types; + + u8 *aml_last_while; + struct acpi_namespace_node arguments[ACPI_METHOD_NUM_ARGS]; /* Control method arguments */ + union acpi_operand_object **caller_return_desc; + union acpi_generic_state *control_state; /* List of control states (nested IFs) */ + struct acpi_namespace_node local_variables[ACPI_METHOD_NUM_LOCALS]; /* Control method locals */ + struct acpi_namespace_node *method_call_node; /* Called method Node*/ + union acpi_parse_object *method_call_op; /* method_call Op if running a method */ + union acpi_operand_object *method_desc; /* Method descriptor if running a method */ + struct acpi_namespace_node *method_node; /* Method Node if running a method */ + union acpi_parse_object *op; /* Current parser op */ + union acpi_operand_object *operands[ACPI_OBJ_NUM_OPERANDS+1]; /* Operands passed to the interpreter (+1 for NULL terminator) */ + const struct acpi_opcode_info *op_info; /* Info on current opcode */ + union acpi_parse_object *origin; /* Start of walk [Obsolete] */ + union acpi_operand_object **params; + struct acpi_parse_state parser_state; /* Current state of parser */ + union acpi_operand_object *result_obj; + union acpi_generic_state *results; /* Stack of accumulated results */ + union acpi_operand_object *return_desc; /* Return object, if any */ + union acpi_generic_state *scope_info; /* Stack of nested scopes */ + + union acpi_parse_object *prev_op; /* Last op that was processed */ + union acpi_parse_object *next_op; /* next op to be processed */ + acpi_parse_downwards descending_callback; + acpi_parse_upwards ascending_callback; + struct acpi_thread_state *thread; + struct acpi_walk_state *next; /* Next walk_state in list */ +}; + + +/* Info used by acpi_ps_init_objects */ + +struct acpi_init_walk_info +{ + u16 method_count; + u16 device_count; + u16 op_region_count; + u16 field_count; + u16 buffer_count; + u16 package_count; + u16 op_region_init; + u16 field_init; + u16 buffer_init; + u16 package_init; + u16 object_count; + struct acpi_table_desc *table_desc; +}; + + +/* Info used by acpi_ns_initialize_devices */ + +struct acpi_device_walk_info +{ + u16 device_count; + u16 num_STA; + u16 num_INI; + struct acpi_table_desc *table_desc; +}; + + +/* TBD: [Restructure] Merge with struct above */ + +struct acpi_walk_info +{ + u32 debug_level; + u32 owner_id; + u8 display_type; +}; + +/* Display Types */ + +#define ACPI_DISPLAY_SUMMARY 0 +#define ACPI_DISPLAY_OBJECTS 1 + +struct acpi_get_devices_info +{ + acpi_walk_callback user_function; + void *context; + char *hid; +}; + + +union acpi_aml_operands +{ + union acpi_operand_object *operands[7]; + + struct + { + struct acpi_object_integer *type; + struct acpi_object_integer *code; + struct acpi_object_integer *argument; + + } fatal; + + struct + { + union acpi_operand_object *source; + struct acpi_object_integer *index; + union acpi_operand_object *target; + + } index; + + struct + { + union acpi_operand_object *source; + struct acpi_object_integer *index; + struct acpi_object_integer *length; + union acpi_operand_object *target; + + } mid; +}; + + +#endif diff -Nru a/include/acpi/actables.h b/include/acpi/actables.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/actables.h Sun Feb 9 21:13:30 2003 @@ -0,0 +1,218 @@ +/****************************************************************************** + * + * Name: actables.h - ACPI table management + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACTABLES_H__ +#define __ACTABLES_H__ + + +/* Used in acpi_tb_map_acpi_table for size parameter if table header is to be used */ + +#define SIZE_IN_HEADER 0 + + +acpi_status +acpi_tb_handle_to_object ( + u16 table_id, + struct acpi_table_desc **table_desc); + +/* + * tbconvrt - Table conversion routines + */ + +acpi_status +acpi_tb_convert_to_xsdt ( + struct acpi_table_desc *table_info); + +acpi_status +acpi_tb_convert_table_fadt ( + void); + +acpi_status +acpi_tb_build_common_facs ( + struct acpi_table_desc *table_info); + +u32 +acpi_tb_get_table_count ( + struct rsdp_descriptor *RSDP, + struct acpi_table_header *RSDT); + +/* + * tbget - Table "get" routines + */ + +acpi_status +acpi_tb_get_table ( + struct acpi_pointer *address, + struct acpi_table_desc *table_info); + +acpi_status +acpi_tb_get_table_header ( + struct acpi_pointer *address, + struct acpi_table_header *return_header); + +acpi_status +acpi_tb_get_table_body ( + struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info); + +acpi_status +acpi_tb_get_this_table ( + struct acpi_pointer *address, + struct acpi_table_header *header, + struct acpi_table_desc *table_info); + +acpi_status +acpi_tb_table_override ( + struct acpi_table_header *header, + struct acpi_table_desc *table_info); + +acpi_status +acpi_tb_get_table_ptr ( + acpi_table_type table_type, + u32 instance, + struct acpi_table_header **table_ptr_loc); + +acpi_status +acpi_tb_verify_rsdp ( + struct acpi_pointer *address); + +void +acpi_tb_get_rsdt_address ( + struct acpi_pointer *out_address); + +acpi_status +acpi_tb_validate_rsdt ( + struct acpi_table_header *table_ptr); + +acpi_status +acpi_tb_get_required_tables ( + void); + +acpi_status +acpi_tb_get_primary_table ( + struct acpi_pointer *address, + struct acpi_table_desc *table_info); + +acpi_status +acpi_tb_get_secondary_table ( + struct acpi_pointer *address, + acpi_string signature, + struct acpi_table_desc *table_info); + +/* + * tbinstall - Table installation + */ + +acpi_status +acpi_tb_install_table ( + struct acpi_table_desc *table_info); + +acpi_status +acpi_tb_match_signature ( + char *signature, + struct acpi_table_desc *table_info, + u8 search_type); + +acpi_status +acpi_tb_recognize_table ( + struct acpi_table_desc *table_info, + u8 search_type); + +acpi_status +acpi_tb_init_table_descriptor ( + acpi_table_type table_type, + struct acpi_table_desc *table_info); + + +/* + * tbremove - Table removal and deletion + */ + +void +acpi_tb_delete_acpi_tables ( + void); + +void +acpi_tb_delete_acpi_table ( + acpi_table_type type); + +void +acpi_tb_delete_single_table ( + struct acpi_table_desc *table_desc); + +struct acpi_table_desc * +acpi_tb_uninstall_table ( + struct acpi_table_desc *table_desc); + +void +acpi_tb_free_acpi_tables_of_type ( + struct acpi_table_desc *table_info); + + +/* + * tbrsd - RSDP, RSDT utilities + */ + +acpi_status +acpi_tb_get_table_rsdt ( + void); + +u8 * +acpi_tb_scan_memory_for_rsdp ( + u8 *start_address, + u32 length); + +acpi_status +acpi_tb_find_rsdp ( + struct acpi_table_desc *table_info, + u32 flags); + + +/* + * tbutils - common table utilities + */ + +acpi_status +acpi_tb_find_table ( + char *signature, + char *oem_id, + char *oem_table_id, + struct acpi_table_header **table_ptr); + +acpi_status +acpi_tb_verify_table_checksum ( + struct acpi_table_header *table_header); + +u8 +acpi_tb_checksum ( + void *buffer, + u32 length); + +acpi_status +acpi_tb_validate_table_header ( + struct acpi_table_header *table_header); + + +#endif /* __ACTABLES_H__ */ diff -Nru a/include/acpi/actbl.h b/include/acpi/actbl.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/actbl.h Sun Feb 9 21:13:32 2003 @@ -0,0 +1,208 @@ +/****************************************************************************** + * + * Name: actbl.h - Table data structures defined in ACPI specification + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACTBL_H__ +#define __ACTBL_H__ + + +/* + * Values for description table header signatures + */ +#define RSDP_NAME "RSDP" +#define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */ +#define APIC_SIG "APIC" /* Multiple APIC Description Table */ +#define DSDT_SIG "DSDT" /* Differentiated System Description Table */ +#define FADT_SIG "FACP" /* Fixed ACPI Description Table */ +#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */ +#define PSDT_SIG "PSDT" /* Persistent System Description Table */ +#define RSDT_SIG "RSDT" /* Root System Description Table */ +#define XSDT_SIG "XSDT" /* Extended System Description Table */ +#define SSDT_SIG "SSDT" /* Secondary System Description Table */ +#define SBST_SIG "SBST" /* Smart Battery Specification Table */ +#define SPIC_SIG "SPIC" /* IOSAPIC table */ +#define BOOT_SIG "BOOT" /* Boot table */ + + +#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */ + +/* values of Mapic.Model */ + +#define DUAL_PIC 0 +#define MULTIPLE_APIC 1 + +/* values of Type in struct apic_header */ + +#define APIC_PROC 0 +#define APIC_IO 1 + + +/* + * Common table types. The base code can remain + * constant if the underlying tables are changed + */ +#define RSDT_DESCRIPTOR struct rsdt_descriptor_rev2 +#define XSDT_DESCRIPTOR struct xsdt_descriptor_rev2 +#define FACS_DESCRIPTOR struct facs_descriptor_rev2 +#define FADT_DESCRIPTOR struct fadt_descriptor_rev2 + + +#pragma pack(1) + +/* + * Architecture-independent tables + * The architecture dependent tables are in separate files + */ +struct rsdp_descriptor /* Root System Descriptor Pointer */ +{ + char signature [8]; /* ACPI signature, contains "RSD PTR " */ + u8 checksum; /* To make sum of struct == 0 */ + char oem_id [6]; /* OEM identification */ + u8 revision; /* Must be 0 for 1.0, 2 for 2.0 */ + u32 rsdt_physical_address; /* 32-bit physical address of RSDT */ + u32 length; /* XSDT Length in bytes including hdr */ + u64 xsdt_physical_address; /* 64-bit physical address of XSDT */ + u8 extended_checksum; /* Checksum of entire table */ + char reserved [3]; /* Reserved field must be 0 */ +}; + + +struct acpi_table_header /* ACPI common table header */ +{ + char signature [4]; /* ACPI signature (4 ASCII characters) */ + u32 length; /* Length of table, in bytes, including header */ + u8 revision; /* ACPI Specification minor version # */ + u8 checksum; /* To make sum of entire table == 0 */ + char oem_id [6]; /* OEM identification */ + char oem_table_id [8]; /* OEM table identification */ + u32 oem_revision; /* OEM revision number */ + char asl_compiler_id [4]; /* ASL compiler vendor ID */ + u32 asl_compiler_revision; /* ASL compiler revision number */ +}; + + +struct acpi_common_facs /* Common FACS for internal use */ +{ + u32 *global_lock; + u64 *firmware_waking_vector; + u8 vector_width; +}; + + +struct apic_table +{ + struct acpi_table_header header; /* ACPI table header */ + u32 local_apic_address; /* Physical address for accessing local APICs */ + u32 PCATcompat : 1; /* a one indicates system also has dual 8259s */ + u32 reserved1 : 31; +}; + + +struct apic_header +{ + u8 type; /* APIC type. Either APIC_PROC or APIC_IO */ + u8 length; /* Length of APIC structure */ +}; + + +struct processor_apic +{ + struct apic_header header; + u8 processor_apic_id; /* ACPI processor id */ + u8 local_apic_id; /* Processor's local APIC id */ + u32 processor_enabled: 1; /* Processor is usable if set */ + u32 reserved1 : 31; +}; + + +struct io_apic +{ + struct apic_header header; + u8 io_apic_id; /* I/O APIC ID */ + u8 reserved; /* Reserved - must be zero */ + u32 io_apic_address; /* APIC's physical address */ + u32 vector; /* Interrupt vector index where INTI + * lines start */ +}; + + +/* + * IA64 TBD: Add SAPIC Tables + */ + +/* + * IA64 TBD: Modify Smart Battery Description to comply with ACPI IA64 + * extensions. + */ +struct smart_battery_description_table +{ + struct acpi_table_header header; + u32 warning_level; + u32 low_level; + u32 critical_level; +}; + + +#pragma pack() + + +/* + * ACPI Table information. We save the table address, length, + * and type of memory allocation (mapped or allocated) for each + * table for 1) when we exit, and 2) if a new table is installed + */ +#define ACPI_MEM_NOT_ALLOCATED 0 +#define ACPI_MEM_ALLOCATED 1 +#define ACPI_MEM_MAPPED 2 + +/* Definitions for the Flags bitfield member of struct acpi_table_support */ + +#define ACPI_TABLE_SINGLE 0x00 +#define ACPI_TABLE_MULTIPLE 0x01 +#define ACPI_TABLE_EXECUTABLE 0x02 + +#define ACPI_TABLE_ROOT 0x00 +#define ACPI_TABLE_PRIMARY 0x10 +#define ACPI_TABLE_SECONDARY 0x20 +#define ACPI_TABLE_ALL 0x30 +#define ACPI_TABLE_TYPE_MASK 0x30 + +/* Data about each known table type */ + +struct acpi_table_support +{ + char *name; + char *signature; + void **global_ptr; + u8 sig_length; + u8 flags; +}; + + +/* + * Get the architecture-specific tables + */ +#include "actbl1.h" /* Acpi 1.0 table definitions */ +#include "actbl2.h" /* Acpi 2.0 table definitions */ + +#endif /* __ACTBL_H__ */ diff -Nru a/include/acpi/actbl1.h b/include/acpi/actbl1.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/actbl1.h Sun Feb 9 21:13:29 2003 @@ -0,0 +1,117 @@ +/****************************************************************************** + * + * Name: actbl1.h - ACPI 1.0 tables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACTBL1_H__ +#define __ACTBL1_H__ + +#pragma pack(1) + +/* + * ACPI 1.0 Root System Description Table (RSDT) + */ +struct rsdt_descriptor_rev1 +{ + struct acpi_table_header header; /* ACPI Table header */ + u32 table_offset_entry [1]; /* Array of pointers to other */ + /* ACPI tables */ +}; + + +/* + * ACPI 1.0 Firmware ACPI Control Structure (FACS) + */ +struct facs_descriptor_rev1 +{ + char signature[4]; /* ACPI Signature */ + u32 length; /* Length of structure, in bytes */ + u32 hardware_signature; /* Hardware configuration signature */ + u32 firmware_waking_vector; /* ACPI OS waking vector */ + u32 global_lock; /* Global Lock */ + u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */ + u32 reserved1 : 31; /* Must be 0 */ + u8 resverved3 [40]; /* Reserved - must be zero */ +}; + + +/* + * ACPI 1.0 Fixed ACPI Description Table (FADT) + */ +struct fadt_descriptor_rev1 +{ + struct acpi_table_header header; /* ACPI Table header */ + u32 firmware_ctrl; /* Physical address of FACS */ + u32 dsdt; /* Physical address of DSDT */ + u8 model; /* System Interrupt Model */ + u8 reserved1; /* Reserved */ + u16 sci_int; /* System vector of SCI interrupt */ + u32 smi_cmd; /* Port address of SMI command port */ + u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ + u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ + u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ + u8 reserved2; /* Reserved - must be zero */ + u32 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ + u32 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ + u32 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + u32 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + u32 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + u32 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + u32 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ + u32 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ + u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ + u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ + u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ + u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ + u8 reserved3; /* Reserved */ + u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ + u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ + u16 flush_size; /* Size of area read to flush caches */ + u16 flush_stride; /* Stride used in flushing caches */ + u8 duty_offset; /* Bit location of duty cycle field in p_cnt reg */ + u8 duty_width; /* Bit width of duty cycle field in p_cnt reg */ + u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ + u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ + u8 century; /* Index to century in RTC CMOS RAM */ + u8 reserved4; /* Reserved */ + u8 reserved4a; /* Reserved */ + u8 reserved4b; /* Reserved */ + u32 wb_invd : 1; /* The wbinvd instruction works properly */ + u32 wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */ + u32 proc_c1 : 1; /* All processors support C1 state */ + u32 plvl2_up : 1; /* C2 state works on MP system */ + u32 pwr_button : 1; /* Power button is handled as a generic feature */ + u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ + u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ + u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ + u32 tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */ + u32 reserved5 : 23; /* Reserved - must be zero */ +}; + +#pragma pack() + +#endif /* __ACTBL1_H__ */ + + diff -Nru a/include/acpi/actbl2.h b/include/acpi/actbl2.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/actbl2.h Sun Feb 9 21:13:33 2003 @@ -0,0 +1,182 @@ +/****************************************************************************** + * + * Name: actbl2.h - ACPI Specification Revision 2.0 Tables + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACTBL2_H__ +#define __ACTBL2_H__ + +/* + * Prefered Power Management Profiles + */ +#define PM_UNSPECIFIED 0 +#define PM_DESKTOP 1 +#define PM_MOBILE 2 +#define PM_WORKSTATION 3 +#define PM_ENTERPRISE_SERVER 4 +#define PM_SOHO_SERVER 5 +#define PM_APPLIANCE_PC 6 + +/* + * ACPI Boot Arch Flags + */ +#define BAF_LEGACY_DEVICES 0x0001 +#define BAF_8042_KEYBOARD_CONTROLLER 0x0002 + +#define FADT2_REVISION_ID 3 + + +#pragma pack(1) + +/* + * ACPI 2.0 Root System Description Table (RSDT) + */ +struct rsdt_descriptor_rev2 +{ + struct acpi_table_header header; /* ACPI table header */ + u32 table_offset_entry [1]; /* Array of pointers to */ + /* ACPI table headers */ +}; + + +/* + * ACPI 2.0 Extended System Description Table (XSDT) + */ +struct xsdt_descriptor_rev2 +{ + struct acpi_table_header header; /* ACPI table header */ + u64 table_offset_entry [1]; /* Array of pointers to */ + /* ACPI table headers */ +}; + + +/* + * ACPI 2.0 Firmware ACPI Control Structure (FACS) + */ +struct facs_descriptor_rev2 +{ + char signature[4]; /* ACPI signature */ + u32 length; /* Length of structure, in bytes */ + u32 hardware_signature; /* Hardware configuration signature */ + u32 firmware_waking_vector; /* 32bit physical address of the Firmware Waking Vector. */ + u32 global_lock; /* Global Lock used to synchronize access to shared hardware resources */ + u32 S4bios_f : 1; /* S4Bios_f - Indicates if S4BIOS support is present */ + u32 reserved1 : 31; /* Must be 0 */ + u64 xfirmware_waking_vector; /* 64bit physical address of the Firmware Waking Vector. */ + u8 version; /* Version of this table */ + u8 reserved3 [31]; /* Reserved - must be zero */ +}; + + +/* + * ACPI 2.0 Generic Address Structure (GAS) + */ +struct acpi_generic_address +{ + u8 address_space_id; /* Address space where struct or register exists. */ + u8 register_bit_width; /* Size in bits of given register */ + u8 register_bit_offset; /* Bit offset within the register */ + u8 reserved; /* Must be 0 */ + u64 address; /* 64-bit address of struct or register */ +}; + + +/* + * ACPI 2.0 Fixed ACPI Description Table (FADT) + */ +struct fadt_descriptor_rev2 +{ + struct acpi_table_header header; /* ACPI table header */ + u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ + u32 V1_dsdt; /* 32-bit physical address of DSDT */ + u8 reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/ + u8 prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */ + u16 sci_int; /* System vector of SCI interrupt */ + u32 smi_cmd; /* Port address of SMI command port */ + u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ + u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ + u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ + u8 pstate_cnt; /* Processor performance state control*/ + u32 V1_pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ + u32 V1_pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ + u32 V1_pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + u32 V1_pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + u32 V1_pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + u32 V1_pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + u32 V1_gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ + u32 V1_gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ + u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ + u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ + u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ + u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ + u8 cst_cnt; /* Support for the _CST object and C States change notification.*/ + u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ + u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ + u16 flush_size; /* Number of flush strides that need to be read */ + u16 flush_stride; /* Processor's memory cache line width, in bytes */ + u8 duty_offset; /* Processor's duty cycle index in processor's P_CNT reg*/ + u8 duty_width; /* Processor's duty cycle value bit width in P_CNT register.*/ + u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ + u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ + u8 century; /* Index to century in RTC CMOS RAM */ + u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/ + u8 reserved2; /* Reserved */ + u32 wb_invd : 1; /* The wbinvd instruction works properly */ + u32 wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */ + u32 proc_c1 : 1; /* All processors support C1 state */ + u32 plvl2_up : 1; /* C2 state works on MP system */ + u32 pwr_button : 1; /* Power button is handled as a generic feature */ + u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ + u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ + u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ + u32 tmr_val_ext : 1; /* Indicates tmr_val is 32 bits 0=24-bits*/ + u32 dock_cap : 1; /* Supports Docking */ + u32 reset_reg_sup : 1; /* Indicates system supports system reset via the FADT RESET_REG*/ + u32 sealed_case : 1; /* Indicates system has no internal expansion capabilities and case is sealed. */ + u32 headless : 1; /* Indicates system does not have local video capabilities or local input devices.*/ + u32 cpu_sw_sleep : 1; /* Indicates to OSPM that a processor native instruction */ + /* Must be executed after writing the SLP_TYPx register. */ + u32 reserved6 : 18; /* Reserved - must be zero */ + + struct acpi_generic_address reset_register; /* Reset register address in GAS format */ + u8 reset_value; /* Value to write to the reset_register port to reset the system. */ + u8 reserved7[3]; /* These three bytes must be zero */ + u64 xfirmware_ctrl; /* 64-bit physical address of FACS */ + u64 Xdsdt; /* 64-bit physical address of DSDT */ + struct acpi_generic_address xpm1a_evt_blk; /* Extended Power Mgt 1a acpi_event Reg Blk address */ + struct acpi_generic_address xpm1b_evt_blk; /* Extended Power Mgt 1b acpi_event Reg Blk address */ + struct acpi_generic_address xpm1a_cnt_blk; /* Extended Power Mgt 1a Control Reg Blk address */ + struct acpi_generic_address xpm1b_cnt_blk; /* Extended Power Mgt 1b Control Reg Blk address */ + struct acpi_generic_address xpm2_cnt_blk; /* Extended Power Mgt 2 Control Reg Blk address */ + struct acpi_generic_address xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */ + struct acpi_generic_address xgpe0_blk; /* Extended General Purpose acpi_event 0 Reg Blk address */ + struct acpi_generic_address xgpe1_blk; /* Extended General Purpose acpi_event 1 Reg Blk address */ +}; + + +#pragma pack() + +#endif /* __ACTBL2_H__ */ + diff -Nru a/include/acpi/actbl71.h b/include/acpi/actbl71.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/actbl71.h Sun Feb 9 21:13:31 2003 @@ -0,0 +1,144 @@ +/****************************************************************************** + * + * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71 + * This file includes tables specific to this + * specification revision. + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACTBL71_H__ +#define __ACTBL71_H__ + + +/* 0.71 FADT address_space data item bitmasks defines */ +/* If the associated bit is zero then it is in memory space else in io space */ + +#define SMI_CMD_ADDRESS_SPACE 0x01 +#define PM1_BLK_ADDRESS_SPACE 0x02 +#define PM2_CNT_BLK_ADDRESS_SPACE 0x04 +#define PM_TMR_BLK_ADDRESS_SPACE 0x08 +#define GPE0_BLK_ADDRESS_SPACE 0x10 +#define GPE1_BLK_ADDRESS_SPACE 0x20 + +/* Only for clarity in declarations */ + +typedef u64 IO_ADDRESS; + + +#pragma pack(1) +struct /* Root System Descriptor Pointer */ +{ + NATIVE_CHAR signature [8]; /* contains "RSD PTR " */ + u8 checksum; /* to make sum of struct == 0 */ + NATIVE_CHAR oem_id [6]; /* OEM identification */ + u8 reserved; /* Must be 0 for 1.0, 2 for 2.0 */ + u64 rsdt_physical_address; /* 64-bit physical address of RSDT */ +}; + + +/*****************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Root System Description Table */ +/*****************************************/ +struct +{ + struct acpi_table_header header; /* Table header */ + u32 reserved_pad; /* IA64 alignment, must be 0 */ + u64 table_offset_entry [1]; /* Array of pointers to other */ + /* tables' headers */ +}; + + +/*******************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Firmware ACPI Control Structure */ +/*******************************************/ +struct +{ + NATIVE_CHAR signature[4]; /* signature "FACS" */ + u32 length; /* length of structure, in bytes */ + u32 hardware_signature; /* hardware configuration signature */ + u32 reserved4; /* must be 0 */ + u64 firmware_waking_vector; /* ACPI OS waking vector */ + u64 global_lock; /* Global Lock */ + u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */ + u32 reserved1 : 31; /* must be 0 */ + u8 reserved3 [28]; /* reserved - must be zero */ +}; + + +/******************************************/ +/* IA64 Extensions to ACPI Spec Rev 0.71 */ +/* for the Fixed ACPI Description Table */ +/******************************************/ +struct +{ + struct acpi_table_header header; /* table header */ + u32 reserved_pad; /* IA64 alignment, must be 0 */ + u64 firmware_ctrl; /* 64-bit Physical address of FACS */ + u64 dsdt; /* 64-bit Physical address of DSDT */ + u8 model; /* System Interrupt Model */ + u8 address_space; /* Address Space Bitmask */ + u16 sci_int; /* System vector of SCI interrupt */ + u8 acpi_enable; /* value to write to smi_cmd to enable ACPI */ + u8 acpi_disable; /* value to write to smi_cmd to disable ACPI */ + u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ + u8 reserved2; /* reserved - must be zero */ + u64 smi_cmd; /* Port address of SMI command port */ + u64 pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ + u64 pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ + u64 pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ + u64 pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ + u64 pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ + u64 pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ + u64 gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ + u64 gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ + u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ + u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ + u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ + u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ + u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ + u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ + u8 gpe1_base; /* offset in gpe model where gpe1 events start */ + u8 reserved3; /* reserved */ + u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */ + u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */ + u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */ + u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */ + u8 century; /* index to century in RTC CMOS RAM */ + u8 reserved4; /* reserved */ + u32 flush_cash : 1; /* PAL_FLUSH_CACHE is correctly supported */ + u32 reserved5 : 1; /* reserved - must be zero */ + u32 proc_c1 : 1; /* all processors support C1 state */ + u32 plvl2_up : 1; /* C2 state works on MP system */ + u32 pwr_button : 1; /* Power button is handled as a generic feature */ + u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */ + u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */ + u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */ + u32 tmr_val_ext : 1; /* tmr_val is 32 bits */ + u32 dock_cap : 1; /* Supports Docking */ + u32 reserved6 : 22; /* reserved - must be zero */ +}; + +#pragma pack() + +#endif /* __ACTBL71_H__ */ + diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/actypes.h Sun Feb 9 21:13:33 2003 @@ -0,0 +1,1189 @@ +/****************************************************************************** + * + * Name: actypes.h - Common data types for the entire ACPI subsystem + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACTYPES_H__ +#define __ACTYPES_H__ + +/*! [Begin] no source code translation (keep the typedefs) */ + + + +/* + * Data type ranges + */ +#define ACPI_UINT8_MAX (UINT8) 0xFF +#define ACPI_UINT16_MAX (UINT16) 0xFFFF +#define ACPI_UINT32_MAX (UINT32) 0xFFFFFFFF +#define ACPI_UINT64_MAX (UINT64) 0xFFFFFFFFFFFFFFFF +#define ACPI_ASCII_MAX 0x7F + + +#ifdef DEFINE_ALTERNATE_TYPES +/* + * Types used only in translated source, defined here to enable + * cross-platform compilation only. + */ +typedef int s32; +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef COMPILER_DEPENDENT_UINT64 u64; + +#endif + + +/* + * Data types - Fixed across all compilation models (16/32/64) + * + * BOOLEAN Logical Boolean. + * INT8 8-bit (1 byte) signed value + * UINT8 8-bit (1 byte) unsigned value + * INT16 16-bit (2 byte) signed value + * UINT16 16-bit (2 byte) unsigned value + * INT32 32-bit (4 byte) signed value + * UINT32 32-bit (4 byte) unsigned value + * INT64 64-bit (8 byte) signed value + * UINT64 64-bit (8 byte) unsigned value + * ACPI_NATIVE_INT 32-bit on IA-32, 64-bit on IA-64 signed value + * ACPI_NATIVE_UINT 32-bit on IA-32, 64-bit on IA-64 unsigned value + */ + +#ifndef ACPI_MACHINE_WIDTH +#error ACPI_MACHINE_WIDTH not defined +#endif + +#if ACPI_MACHINE_WIDTH == 64 + +/*! [Begin] no source code translation (keep the typedefs) */ + +/* + * 64-bit type definitions + */ +typedef unsigned char UINT8; +typedef unsigned char BOOLEAN; +typedef unsigned short UINT16; +typedef int INT32; +typedef unsigned int UINT32; +typedef COMPILER_DEPENDENT_INT64 INT64; +typedef COMPILER_DEPENDENT_UINT64 UINT64; + +/*! [End] no source code translation !*/ + +typedef s64 acpi_native_int; +typedef u64 acpi_native_uint; + +typedef u64 acpi_table_ptr; +typedef u64 acpi_io_address; +typedef u64 acpi_physical_address; +typedef u64 acpi_size; + +#define ALIGNED_ADDRESS_BOUNDARY 0x00000008 /* No hardware alignment support in IA64 */ +#define ACPI_USE_NATIVE_DIVIDE /* Native 64-bit integer support */ +#define ACPI_MAX_PTR ACPI_UINT64_MAX +#define ACPI_SIZE_MAX ACPI_UINT64_MAX + + +#elif ACPI_MACHINE_WIDTH == 16 + +/*! [Begin] no source code translation (keep the typedefs) */ + +/* + * 16-bit type definitions + */ +typedef unsigned char UINT8; +typedef unsigned char BOOLEAN; +typedef unsigned int UINT16; +typedef long INT32; +typedef int INT16; +typedef unsigned long UINT32; + +struct +{ + UINT32 Lo; + UINT32 Hi; +}; + +/*! [End] no source code translation !*/ + +typedef u16 acpi_native_uint; +typedef s16 acpi_native_int; + +typedef u32 acpi_table_ptr; +typedef u32 acpi_io_address; +typedef char *acpi_physical_address; +typedef u16 acpi_size; + +#define ALIGNED_ADDRESS_BOUNDARY 0x00000002 +#define _HW_ALIGNMENT_SUPPORT +#define ACPI_USE_NATIVE_DIVIDE /* No 64-bit integers, ok to use native divide */ +#define ACPI_MAX_PTR ACPI_UINT16_MAX +#define ACPI_SIZE_MAX ACPI_UINT16_MAX + +/* + * (16-bit only) internal integers must be 32-bits, so + * 64-bit integers cannot be supported + */ +#define ACPI_NO_INTEGER64_SUPPORT + + +#elif ACPI_MACHINE_WIDTH == 32 + +/*! [Begin] no source code translation (keep the typedefs) */ + +/* + * 32-bit type definitions (default) + */ +typedef unsigned char UINT8; +typedef unsigned char BOOLEAN; +typedef unsigned short UINT16; +typedef int INT32; +typedef unsigned int UINT32; +typedef COMPILER_DEPENDENT_INT64 INT64; +typedef COMPILER_DEPENDENT_UINT64 UINT64; + +/*! [End] no source code translation !*/ + +typedef s32 acpi_native_int; +typedef u32 acpi_native_uint; + +typedef u64 acpi_table_ptr; +typedef u32 acpi_io_address; +typedef u64 acpi_physical_address; +typedef u32 acpi_size; + +#define ALIGNED_ADDRESS_BOUNDARY 0x00000004 +#define _HW_ALIGNMENT_SUPPORT +#define ACPI_MAX_PTR ACPI_UINT32_MAX +#define ACPI_SIZE_MAX ACPI_UINT32_MAX + +#else +#error unknown ACPI_MACHINE_WIDTH +#endif + + +/* + * Miscellaneous common types + */ +typedef u32 UINT32_BIT; +typedef acpi_native_uint ACPI_PTRDIFF; + +/* + * Pointer overlays to avoid lots of typecasting for + * code that accepts both physical and logical pointers. + */ +union acpi_pointers +{ + acpi_physical_address physical; + void *logical; + acpi_table_ptr value; +}; + +struct acpi_pointer +{ + u32 pointer_type; + union acpi_pointers pointer; +}; + +/* pointer_types for above */ + +#define ACPI_PHYSICAL_POINTER 0x01 +#define ACPI_LOGICAL_POINTER 0x02 + +/* Processor mode */ + +#define ACPI_PHYSICAL_ADDRESSING 0x04 +#define ACPI_LOGICAL_ADDRESSING 0x08 +#define ACPI_MEMORY_MODE 0x0C + +#define ACPI_PHYSMODE_PHYSPTR ACPI_PHYSICAL_ADDRESSING | ACPI_PHYSICAL_POINTER +#define ACPI_LOGMODE_PHYSPTR ACPI_LOGICAL_ADDRESSING | ACPI_PHYSICAL_POINTER +#define ACPI_LOGMODE_LOGPTR ACPI_LOGICAL_ADDRESSING | ACPI_LOGICAL_POINTER + + +/* + * Useful defines + */ +#ifdef FALSE +#undef FALSE +#endif +#define FALSE (1 == 0) + +#ifdef TRUE +#undef TRUE +#endif +#define TRUE (1 == 1) + +#ifndef NULL +#define NULL (void *) 0 +#endif + + +/* + * Local datatypes + */ +typedef u32 acpi_status; /* All ACPI Exceptions */ +typedef u32 acpi_name; /* 4-byte ACPI name */ +typedef char * acpi_string; /* Null terminated ASCII string */ +typedef void * acpi_handle; /* Actually a ptr to an Node */ + +struct uint64_struct +{ + u32 lo; + u32 hi; +}; + +union uint64_overlay +{ + u64 full; + struct uint64_struct part; +}; + +struct uint32_struct +{ + u32 lo; + u32 hi; +}; + + +/* + * Acpi integer width. In ACPI version 1, integers are + * 32 bits. In ACPI version 2, integers are 64 bits. + * Note that this pertains to the ACPI integer type only, not + * other integers used in the implementation of the ACPI CA + * subsystem. + */ +#ifdef ACPI_NO_INTEGER64_SUPPORT + +/* 32-bit integers only, no 64-bit support */ + +typedef u32 acpi_integer; +#define ACPI_INTEGER_MAX ACPI_UINT32_MAX +#define ACPI_INTEGER_BIT_SIZE 32 +#define ACPI_MAX_BCD_VALUE 99999999 +#define ACPI_MAX_BCD_DIGITS 8 +#define ACPI_MAX_DECIMAL_DIGITS 10 + +#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 32-bit divide */ + + +#else + +/* 64-bit integers */ + +typedef u64 acpi_integer; +#define ACPI_INTEGER_MAX ACPI_UINT64_MAX +#define ACPI_INTEGER_BIT_SIZE 64 +#define ACPI_MAX_BCD_VALUE 9999999999999999 +#define ACPI_MAX_BCD_DIGITS 16 +#define ACPI_MAX_DECIMAL_DIGITS 19 + +#if ACPI_MACHINE_WIDTH == 64 +#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 64-bit divide */ +#endif +#endif + + +/* + * Constants with special meanings + */ +#define ACPI_ROOT_OBJECT (acpi_handle) ACPI_PTR_ADD (char, NULL, ACPI_MAX_PTR) + + +/* + * Initialization sequence + */ +#define ACPI_FULL_INITIALIZATION 0x00 +#define ACPI_NO_ADDRESS_SPACE_INIT 0x01 +#define ACPI_NO_HARDWARE_INIT 0x02 +#define ACPI_NO_EVENT_INIT 0x04 +#define ACPI_NO_HANDLER_INIT 0x08 +#define ACPI_NO_ACPI_ENABLE 0x10 +#define ACPI_NO_DEVICE_INIT 0x20 +#define ACPI_NO_OBJECT_INIT 0x40 + +/* + * Initialization state + */ +#define ACPI_INITIALIZED_OK 0x01 + +/* + * Power state values + */ + +#define ACPI_STATE_UNKNOWN (u8) 0xFF + +#define ACPI_STATE_S0 (u8) 0 +#define ACPI_STATE_S1 (u8) 1 +#define ACPI_STATE_S2 (u8) 2 +#define ACPI_STATE_S3 (u8) 3 +#define ACPI_STATE_S4 (u8) 4 +#define ACPI_STATE_S5 (u8) 5 +#define ACPI_S_STATES_MAX ACPI_STATE_S5 +#define ACPI_S_STATE_COUNT 6 + +#define ACPI_STATE_D0 (u8) 0 +#define ACPI_STATE_D1 (u8) 1 +#define ACPI_STATE_D2 (u8) 2 +#define ACPI_STATE_D3 (u8) 3 +#define ACPI_D_STATES_MAX ACPI_STATE_D3 +#define ACPI_D_STATE_COUNT 4 + +#define ACPI_STATE_C0 (u8) 0 +#define ACPI_STATE_C1 (u8) 1 +#define ACPI_STATE_C2 (u8) 2 +#define ACPI_STATE_C3 (u8) 3 +#define ACPI_C_STATES_MAX ACPI_STATE_C3 +#define ACPI_C_STATE_COUNT 4 + +/* + * Sleep type invalid value + */ +#define ACPI_SLEEP_TYPE_MAX 0x7 +#define ACPI_SLEEP_TYPE_INVALID 0xFF + +/* + * Standard notify values + */ +#define ACPI_NOTIFY_BUS_CHECK (u8) 0 +#define ACPI_NOTIFY_DEVICE_CHECK (u8) 1 +#define ACPI_NOTIFY_DEVICE_WAKE (u8) 2 +#define ACPI_NOTIFY_EJECT_REQUEST (u8) 3 +#define ACPI_NOTIFY_DEVICE_CHECK_LIGHT (u8) 4 +#define ACPI_NOTIFY_FREQUENCY_MISMATCH (u8) 5 +#define ACPI_NOTIFY_BUS_MODE_MISMATCH (u8) 6 +#define ACPI_NOTIFY_POWER_FAULT (u8) 7 + + +/* + * Table types. These values are passed to the table related APIs + */ +typedef u32 acpi_table_type; + +#define ACPI_TABLE_RSDP (acpi_table_type) 0 +#define ACPI_TABLE_DSDT (acpi_table_type) 1 +#define ACPI_TABLE_FADT (acpi_table_type) 2 +#define ACPI_TABLE_FACS (acpi_table_type) 3 +#define ACPI_TABLE_PSDT (acpi_table_type) 4 +#define ACPI_TABLE_SSDT (acpi_table_type) 5 +#define ACPI_TABLE_XSDT (acpi_table_type) 6 +#define ACPI_TABLE_MAX 6 +#define NUM_ACPI_TABLES (ACPI_TABLE_MAX+1) + + +/* + * Types associated with ACPI names and objects. The first group of + * values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition + * of the ACPI object_type() operator (See the ACPI Spec). Therefore, + * only add to the first group if the spec changes. + * + * Types must be kept in sync with the global acpi_ns_properties + * and acpi_ns_type_names arrays. + */ +typedef u32 acpi_object_type; + +#define ACPI_TYPE_ANY 0x00 +#define ACPI_TYPE_INTEGER 0x01 /* Byte/Word/Dword/Zero/One/Ones */ +#define ACPI_TYPE_STRING 0x02 +#define ACPI_TYPE_BUFFER 0x03 +#define ACPI_TYPE_PACKAGE 0x04 /* byte_const, multiple data_term/Constant/super_name */ +#define ACPI_TYPE_FIELD_UNIT 0x05 +#define ACPI_TYPE_DEVICE 0x06 /* Name, multiple Node */ +#define ACPI_TYPE_EVENT 0x07 +#define ACPI_TYPE_METHOD 0x08 /* Name, byte_const, multiple Code */ +#define ACPI_TYPE_MUTEX 0x09 +#define ACPI_TYPE_REGION 0x0A +#define ACPI_TYPE_POWER 0x0B /* Name,byte_const,word_const,multi Node */ +#define ACPI_TYPE_PROCESSOR 0x0C /* Name,byte_const,Dword_const,byte_const,multi nm_o */ +#define ACPI_TYPE_THERMAL 0x0D /* Name, multiple Node */ +#define ACPI_TYPE_BUFFER_FIELD 0x0E +#define ACPI_TYPE_DDB_HANDLE 0x0F +#define ACPI_TYPE_DEBUG_OBJECT 0x10 + +#define ACPI_TYPE_EXTERNAL_MAX 0x10 + +/* + * These are object types that do not map directly to the ACPI + * object_type() operator. They are used for various internal purposes only. + * If new predefined ACPI_TYPEs are added (via the ACPI specification), these + * internal types must move upwards. (There is code that depends on these + * values being contiguous with the external types above.) + */ +#define ACPI_TYPE_LOCAL_REGION_FIELD 0x11 +#define ACPI_TYPE_LOCAL_BANK_FIELD 0x12 +#define ACPI_TYPE_LOCAL_INDEX_FIELD 0x13 +#define ACPI_TYPE_LOCAL_REFERENCE 0x14 /* Arg#, Local#, Name, Debug, ref_of, Index */ +#define ACPI_TYPE_LOCAL_ALIAS 0x15 +#define ACPI_TYPE_LOCAL_NOTIFY 0x16 +#define ACPI_TYPE_LOCAL_ADDRESS_HANDLER 0x17 +#define ACPI_TYPE_LOCAL_RESOURCE 0x18 +#define ACPI_TYPE_LOCAL_RESOURCE_FIELD 0x19 +#define ACPI_TYPE_LOCAL_SCOPE 0x1A /* 1 Name, multiple object_list Nodes */ + +#define ACPI_TYPE_NS_NODE_MAX 0x1A /* Last typecode used within a NS Node */ + +/* + * These are special object types that never appear in + * a Namespace node, only in an union acpi_operand_object + */ +#define ACPI_TYPE_LOCAL_EXTRA 0x1B +#define ACPI_TYPE_LOCAL_DATA 0x1C + +#define ACPI_TYPE_LOCAL_MAX 0x1C + +/* All types above here are invalid */ + +#define ACPI_TYPE_INVALID 0x1D +#define ACPI_TYPE_NOT_FOUND 0xFF + + +/* + * Bitmapped ACPI types. Used internally only + */ +#define ACPI_BTYPE_ANY 0x00000000 +#define ACPI_BTYPE_INTEGER 0x00000001 +#define ACPI_BTYPE_STRING 0x00000002 +#define ACPI_BTYPE_BUFFER 0x00000004 +#define ACPI_BTYPE_PACKAGE 0x00000008 +#define ACPI_BTYPE_FIELD_UNIT 0x00000010 +#define ACPI_BTYPE_DEVICE 0x00000020 +#define ACPI_BTYPE_EVENT 0x00000040 +#define ACPI_BTYPE_METHOD 0x00000080 +#define ACPI_BTYPE_MUTEX 0x00000100 +#define ACPI_BTYPE_REGION 0x00000200 +#define ACPI_BTYPE_POWER 0x00000400 +#define ACPI_BTYPE_PROCESSOR 0x00000800 +#define ACPI_BTYPE_THERMAL 0x00001000 +#define ACPI_BTYPE_BUFFER_FIELD 0x00002000 +#define ACPI_BTYPE_DDB_HANDLE 0x00004000 +#define ACPI_BTYPE_DEBUG_OBJECT 0x00008000 +#define ACPI_BTYPE_REFERENCE 0x00010000 +#define ACPI_BTYPE_RESOURCE 0x00020000 + +#define ACPI_BTYPE_COMPUTE_DATA (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER) + +#define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_PACKAGE) +#define ACPI_BTYPE_DATA_REFERENCE (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE) +#define ACPI_BTYPE_DEVICE_OBJECTS (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR) +#define ACPI_BTYPE_OBJECTS_AND_REFS 0x0001FFFF /* ARG or LOCAL */ +#define ACPI_BTYPE_ALL_OBJECTS 0x0000FFFF + +/* + * All I/O + */ +#define ACPI_READ 0 +#define ACPI_WRITE 1 +#define ACPI_IO_MASK 1 + + +/* + * acpi_event Types: Fixed & General Purpose + */ +typedef u32 acpi_event_type; + +#define ACPI_EVENT_FIXED 0 +#define ACPI_EVENT_GPE 1 + +/* + * Fixed events + */ +#define ACPI_EVENT_PMTIMER 0 +#define ACPI_EVENT_GLOBAL 1 +#define ACPI_EVENT_POWER_BUTTON 2 +#define ACPI_EVENT_SLEEP_BUTTON 3 +#define ACPI_EVENT_RTC 4 +#define ACPI_EVENT_MAX 4 +#define ACPI_NUM_FIXED_EVENTS ACPI_EVENT_MAX + 1 + +#define ACPI_GPE_INVALID 0xFF +#define ACPI_GPE_MAX 0xFF +#define ACPI_NUM_GPE 256 + +#define ACPI_EVENT_LEVEL_TRIGGERED 1 +#define ACPI_EVENT_EDGE_TRIGGERED 2 + +/* + * GPEs + */ +#define ACPI_EVENT_WAKE_ENABLE 0x1 +#define ACPI_EVENT_WAKE_DISABLE 0x1 + + +/* + * acpi_event Status: + * ------------- + * The encoding of acpi_event_status is illustrated below. + * Note that a set bit (1) indicates the property is TRUE + * (e.g. if bit 0 is set then the event is enabled). + * +-------------+-+-+-+ + * | Bits 31:3 |2|1|0| + * +-------------+-+-+-+ + * | | | | + * | | | +- Enabled? + * | | +--- Enabled for wake? + * | +----- Set? + * +----------- + */ +typedef u32 acpi_event_status; + +#define ACPI_EVENT_FLAG_DISABLED (acpi_event_status) 0x00 +#define ACPI_EVENT_FLAG_ENABLED (acpi_event_status) 0x01 +#define ACPI_EVENT_FLAG_WAKE_ENABLED (acpi_event_status) 0x02 +#define ACPI_EVENT_FLAG_SET (acpi_event_status) 0x04 + + +/* Notify types */ + +#define ACPI_SYSTEM_NOTIFY 0 +#define ACPI_DEVICE_NOTIFY 1 +#define ACPI_MAX_NOTIFY_HANDLER_TYPE 1 + +#define ACPI_MAX_SYS_NOTIFY 0x7f + + +/* Address Space (Operation Region) Types */ + +typedef u8 acpi_adr_space_type; + +#define ACPI_ADR_SPACE_SYSTEM_MEMORY (acpi_adr_space_type) 0 +#define ACPI_ADR_SPACE_SYSTEM_IO (acpi_adr_space_type) 1 +#define ACPI_ADR_SPACE_PCI_CONFIG (acpi_adr_space_type) 2 +#define ACPI_ADR_SPACE_EC (acpi_adr_space_type) 3 +#define ACPI_ADR_SPACE_SMBUS (acpi_adr_space_type) 4 +#define ACPI_ADR_SPACE_CMOS (acpi_adr_space_type) 5 +#define ACPI_ADR_SPACE_PCI_BAR_TARGET (acpi_adr_space_type) 6 +#define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 7 +#define ACPI_ADR_SPACE_FIXED_HARDWARE (acpi_adr_space_type) 127 + + +/* + * bit_register IDs + * These are bitfields defined within the full ACPI registers + */ +#define ACPI_BITREG_TIMER_STATUS 0x00 +#define ACPI_BITREG_BUS_MASTER_STATUS 0x01 +#define ACPI_BITREG_GLOBAL_LOCK_STATUS 0x02 +#define ACPI_BITREG_POWER_BUTTON_STATUS 0x03 +#define ACPI_BITREG_SLEEP_BUTTON_STATUS 0x04 +#define ACPI_BITREG_RT_CLOCK_STATUS 0x05 +#define ACPI_BITREG_WAKE_STATUS 0x06 + +#define ACPI_BITREG_TIMER_ENABLE 0x07 +#define ACPI_BITREG_GLOBAL_LOCK_ENABLE 0x08 +#define ACPI_BITREG_POWER_BUTTON_ENABLE 0x09 +#define ACPI_BITREG_SLEEP_BUTTON_ENABLE 0x0A +#define ACPI_BITREG_RT_CLOCK_ENABLE 0x0B +#define ACPI_BITREG_WAKE_ENABLE 0x0C + +#define ACPI_BITREG_SCI_ENABLE 0x0D +#define ACPI_BITREG_BUS_MASTER_RLD 0x0E +#define ACPI_BITREG_GLOBAL_LOCK_RELEASE 0x0F +#define ACPI_BITREG_SLEEP_TYPE_A 0x10 +#define ACPI_BITREG_SLEEP_TYPE_B 0x11 +#define ACPI_BITREG_SLEEP_ENABLE 0x12 + +#define ACPI_BITREG_ARB_DISABLE 0x13 + +#define ACPI_BITREG_MAX 0x13 +#define ACPI_NUM_BITREG ACPI_BITREG_MAX + 1 + + +/* + * External ACPI object definition + */ +union acpi_object +{ + acpi_object_type type; /* See definition of acpi_ns_type for values */ + struct + { + acpi_object_type type; + acpi_integer value; /* The actual number */ + } integer; + + struct + { + acpi_object_type type; + u32 length; /* # of bytes in string, excluding trailing null */ + char *pointer; /* points to the string value */ + } string; + + struct + { + acpi_object_type type; + u32 length; /* # of bytes in buffer */ + u8 *pointer; /* points to the buffer */ + } buffer; + + struct + { + acpi_object_type type; + u32 fill1; + acpi_handle handle; /* object reference */ + } reference; + + struct + { + acpi_object_type type; + u32 count; /* # of elements in package */ + union acpi_object *elements; /* Pointer to an array of ACPI_OBJECTs */ + } package; + + struct + { + acpi_object_type type; + u32 proc_id; + acpi_io_address pblk_address; + u32 pblk_length; + } processor; + + struct + { + acpi_object_type type; + u32 system_level; + u32 resource_order; + } power_resource; +}; + + +/* + * List of objects, used as a parameter list for control method evaluation + */ +struct acpi_object_list +{ + u32 count; + union acpi_object *pointer; +}; + + +/* + * Miscellaneous common Data Structures used by the interfaces + */ +#define ACPI_NO_BUFFER 0 +#define ACPI_ALLOCATE_BUFFER (acpi_size) (-1) +#define ACPI_ALLOCATE_LOCAL_BUFFER (acpi_size) (-2) + +struct acpi_buffer +{ + acpi_size length; /* Length in bytes of the buffer */ + void *pointer; /* pointer to buffer */ +}; + + +/* + * name_type for acpi_get_name + */ +#define ACPI_FULL_PATHNAME 0 +#define ACPI_SINGLE_NAME 1 +#define ACPI_NAME_TYPE_MAX 1 + + +/* + * Structure and flags for acpi_get_system_info + */ +#define ACPI_SYS_MODE_UNKNOWN 0x0000 +#define ACPI_SYS_MODE_ACPI 0x0001 +#define ACPI_SYS_MODE_LEGACY 0x0002 +#define ACPI_SYS_MODES_MASK 0x0003 + + +/* + * ACPI Table Info. One per ACPI table _type_ + */ +struct acpi_table_info +{ + u32 count; +}; + + +/* + * System info returned by acpi_get_system_info() + */ +struct acpi_system_info +{ + u32 acpi_ca_version; + u32 flags; + u32 timer_resolution; + u32 reserved1; + u32 reserved2; + u32 debug_level; + u32 debug_layer; + u32 num_table_types; + struct acpi_table_info table_info [NUM_ACPI_TABLES]; +}; + + +/* + * Various handlers and callback procedures + */ +typedef +u32 (*acpi_event_handler) ( + void *context); + +typedef +void (*acpi_gpe_handler) ( + void *context); + +typedef +void (*acpi_notify_handler) ( + acpi_handle device, + u32 value, + void *context); + +typedef +void (*acpi_object_handler) ( + acpi_handle object, + u32 function, + void *data); + +typedef +acpi_status (*acpi_init_handler) ( + acpi_handle object, + u32 function); + +#define ACPI_INIT_DEVICE_INI 1 + + +/* Address Spaces (Operation Regions */ + +typedef +acpi_status (*acpi_adr_space_handler) ( + u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer *value, + void *handler_context, + void *region_context); + +#define ACPI_DEFAULT_HANDLER NULL + + +typedef +acpi_status (*acpi_adr_space_setup) ( + acpi_handle region_handle, + u32 function, + void *handler_context, + void **region_context); + +#define ACPI_REGION_ACTIVATE 0 +#define ACPI_REGION_DEACTIVATE 1 + +typedef +acpi_status (*acpi_walk_callback) ( + acpi_handle obj_handle, + u32 nesting_level, + void *context, + void **return_value); + + +/* Interrupt handler return values */ + +#define ACPI_INTERRUPT_NOT_HANDLED 0x00 +#define ACPI_INTERRUPT_HANDLED 0x01 + + +/* Structure and flags for acpi_get_device_info */ + +#define ACPI_VALID_HID 0x1 +#define ACPI_VALID_UID 0x2 +#define ACPI_VALID_ADR 0x4 +#define ACPI_VALID_STA 0x8 + + +#define ACPI_COMMON_OBJ_INFO \ + acpi_object_type type; /* ACPI object type */ \ + acpi_name name /* ACPI object Name */ + + +struct acpi_obj_info_header +{ + ACPI_COMMON_OBJ_INFO; +}; + + +struct acpi_device_info +{ + ACPI_COMMON_OBJ_INFO; + + u32 valid; /* Are the next bits legit? */ + char hardware_id[9]; /* _HID value if any */ + char unique_id[9]; /* _UID value if any */ + acpi_integer address; /* _ADR value if any */ + u32 current_status; /* _STA value */ +}; + + +/* Context structs for address space handlers */ + +struct acpi_pci_id +{ + u16 segment; + u16 bus; + u16 device; + u16 function; +}; + + +struct acpi_mem_space_context +{ + u32 length; + acpi_physical_address address; + acpi_physical_address mapped_physical_address; + u8 *mapped_logical_address; + acpi_size mapped_length; +}; + + +/* + * Definitions for Resource Attributes + */ + +/* + * Memory Attributes + */ +#define ACPI_READ_ONLY_MEMORY (u8) 0x00 +#define ACPI_READ_WRITE_MEMORY (u8) 0x01 + +#define ACPI_NON_CACHEABLE_MEMORY (u8) 0x00 +#define ACPI_CACHABLE_MEMORY (u8) 0x01 +#define ACPI_WRITE_COMBINING_MEMORY (u8) 0x02 +#define ACPI_PREFETCHABLE_MEMORY (u8) 0x03 + +/* + * IO Attributes + * The ISA Io ranges are: n000-n0_ffh, n400-n4_ffh, n800-n8_ffh, n_c00-n_cFFh. + * The non-ISA Io ranges are: n100-n3_ffh, n500-n7_ffh, n900-n_bFfh, n_cd0-n_fFFh. + */ +#define ACPI_NON_ISA_ONLY_RANGES (u8) 0x01 +#define ACPI_ISA_ONLY_RANGES (u8) 0x02 +#define ACPI_ENTIRE_RANGE (ACPI_NON_ISA_ONLY_RANGES | ACPI_ISA_ONLY_RANGES) + +/* + * IO Port Descriptor Decode + */ +#define ACPI_DECODE_10 (u8) 0x00 /* 10-bit IO address decode */ +#define ACPI_DECODE_16 (u8) 0x01 /* 16-bit IO address decode */ + +/* + * IRQ Attributes + */ +#define ACPI_EDGE_SENSITIVE (u8) 0x00 +#define ACPI_LEVEL_SENSITIVE (u8) 0x01 + +#define ACPI_ACTIVE_HIGH (u8) 0x00 +#define ACPI_ACTIVE_LOW (u8) 0x01 + +#define ACPI_EXCLUSIVE (u8) 0x00 +#define ACPI_SHARED (u8) 0x01 + +/* + * DMA Attributes + */ +#define ACPI_COMPATIBILITY (u8) 0x00 +#define ACPI_TYPE_A (u8) 0x01 +#define ACPI_TYPE_B (u8) 0x02 +#define ACPI_TYPE_F (u8) 0x03 + +#define ACPI_NOT_BUS_MASTER (u8) 0x00 +#define ACPI_BUS_MASTER (u8) 0x01 + +#define ACPI_TRANSFER_8 (u8) 0x00 +#define ACPI_TRANSFER_8_16 (u8) 0x01 +#define ACPI_TRANSFER_16 (u8) 0x02 + +/* + * Start Dependent Functions Priority definitions + */ +#define ACPI_GOOD_CONFIGURATION (u8) 0x00 +#define ACPI_ACCEPTABLE_CONFIGURATION (u8) 0x01 +#define ACPI_SUB_OPTIMAL_CONFIGURATION (u8) 0x02 + +/* + * 16, 32 and 64-bit Address Descriptor resource types + */ +#define ACPI_MEMORY_RANGE (u8) 0x00 +#define ACPI_IO_RANGE (u8) 0x01 +#define ACPI_BUS_NUMBER_RANGE (u8) 0x02 + +#define ACPI_ADDRESS_NOT_FIXED (u8) 0x00 +#define ACPI_ADDRESS_FIXED (u8) 0x01 + +#define ACPI_POS_DECODE (u8) 0x00 +#define ACPI_SUB_DECODE (u8) 0x01 + +#define ACPI_PRODUCER (u8) 0x00 +#define ACPI_CONSUMER (u8) 0x01 + + +/* + * Structures used to describe device resources + */ +struct acpi_resource_irq +{ + u32 edge_level; + u32 active_high_low; + u32 shared_exclusive; + u32 number_of_interrupts; + u32 interrupts[1]; +}; + +struct acpi_resource_dma +{ + u32 type; + u32 bus_master; + u32 transfer; + u32 number_of_channels; + u32 channels[1]; +}; + +struct acpi_resource_start_dpf +{ + u32 compatibility_priority; + u32 performance_robustness; +}; + +/* + * END_DEPENDENT_FUNCTIONS_RESOURCE struct is not + * needed because it has no fields + */ + +struct acpi_resource_io +{ + u32 io_decode; + u32 min_base_address; + u32 max_base_address; + u32 alignment; + u32 range_length; +}; + +struct acpi_resource_fixed_io +{ + u32 base_address; + u32 range_length; +}; + +struct acpi_resource_vendor +{ + u32 length; + u8 reserved[1]; +}; + +struct acpi_resource_end_tag +{ + u8 checksum; +}; + +struct acpi_resource_mem24 +{ + u32 read_write_attribute; + u32 min_base_address; + u32 max_base_address; + u32 alignment; + u32 range_length; +}; + +struct acpi_resource_mem32 +{ + u32 read_write_attribute; + u32 min_base_address; + u32 max_base_address; + u32 alignment; + u32 range_length; +}; + +struct acpi_resource_fixed_mem32 +{ + u32 read_write_attribute; + u32 range_base_address; + u32 range_length; +}; + +struct acpi_memory_attribute +{ + u16 cache_attribute; + u16 read_write_attribute; +}; + +struct acpi_io_attribute +{ + u16 range_attribute; + u16 reserved; +}; + +struct acpi_bus_attribute +{ + u16 reserved1; + u16 reserved2; +}; + +union acpi_resource_attribute +{ + struct acpi_memory_attribute memory; + struct acpi_io_attribute io; + struct acpi_bus_attribute bus; +}; + +struct acpi_resource_source +{ + u32 index; + u32 string_length; + char *string_ptr; +}; + +struct acpi_resource_address16 +{ + u32 resource_type; + u32 producer_consumer; + u32 decode; + u32 min_address_fixed; + u32 max_address_fixed; + union acpi_resource_attribute attribute; + u32 granularity; + u32 min_address_range; + u32 max_address_range; + u32 address_translation_offset; + u32 address_length; + struct acpi_resource_source resource_source; +}; + +struct acpi_resource_address32 +{ + u32 resource_type; + u32 producer_consumer; + u32 decode; + u32 min_address_fixed; + u32 max_address_fixed; + union acpi_resource_attribute attribute; + u32 granularity; + u32 min_address_range; + u32 max_address_range; + u32 address_translation_offset; + u32 address_length; + struct acpi_resource_source resource_source; +}; + +struct acpi_resource_address64 +{ + u32 resource_type; + u32 producer_consumer; + u32 decode; + u32 min_address_fixed; + u32 max_address_fixed; + union acpi_resource_attribute attribute; + u64 granularity; + u64 min_address_range; + u64 max_address_range; + u64 address_translation_offset; + u64 address_length; + struct acpi_resource_source resource_source; +}; + +struct acpi_resource_ext_irq +{ + u32 producer_consumer; + u32 edge_level; + u32 active_high_low; + u32 shared_exclusive; + u32 number_of_interrupts; + struct acpi_resource_source resource_source; + u32 interrupts[1]; +}; + + +/* ACPI_RESOURCE_TYPEs */ + +#define ACPI_RSTYPE_IRQ 0 +#define ACPI_RSTYPE_DMA 1 +#define ACPI_RSTYPE_START_DPF 2 +#define ACPI_RSTYPE_END_DPF 3 +#define ACPI_RSTYPE_IO 4 +#define ACPI_RSTYPE_FIXED_IO 5 +#define ACPI_RSTYPE_VENDOR 6 +#define ACPI_RSTYPE_END_TAG 7 +#define ACPI_RSTYPE_MEM24 8 +#define ACPI_RSTYPE_MEM32 9 +#define ACPI_RSTYPE_FIXED_MEM32 10 +#define ACPI_RSTYPE_ADDRESS16 11 +#define ACPI_RSTYPE_ADDRESS32 12 +#define ACPI_RSTYPE_ADDRESS64 13 +#define ACPI_RSTYPE_EXT_IRQ 14 + +typedef u32 acpi_resource_type; + +union acpi_resource_data +{ + struct acpi_resource_irq irq; + struct acpi_resource_dma dma; + struct acpi_resource_start_dpf start_dpf; + struct acpi_resource_io io; + struct acpi_resource_fixed_io fixed_io; + struct acpi_resource_vendor vendor_specific; + struct acpi_resource_end_tag end_tag; + struct acpi_resource_mem24 memory24; + struct acpi_resource_mem32 memory32; + struct acpi_resource_fixed_mem32 fixed_memory32; + struct acpi_resource_address16 address16; + struct acpi_resource_address32 address32; + struct acpi_resource_address64 address64; + struct acpi_resource_ext_irq extended_irq; +}; + +struct acpi_resource +{ + acpi_resource_type id; + u32 length; + union acpi_resource_data data; +}; + +#define ACPI_RESOURCE_LENGTH 12 +#define ACPI_RESOURCE_LENGTH_NO_DATA 8 /* Id + Length fields */ + +#define ACPI_SIZEOF_RESOURCE(type) (ACPI_RESOURCE_LENGTH_NO_DATA + sizeof (type)) + +#define ACPI_NEXT_RESOURCE(res) (struct acpi_resource *)((u8 *) res + res->length) + +#ifdef _HW_ALIGNMENT_SUPPORT +#define ACPI_ALIGN_RESOURCE_SIZE(length) (length) +#else +#define ACPI_ALIGN_RESOURCE_SIZE(length) ACPI_ROUND_UP_TO_NATIVE_WORD(length) +#endif + +/* + * END: of definitions for Resource Attributes + */ + + +struct acpi_pci_routing_table +{ + u32 length; + u32 pin; + acpi_integer address; /* here for 64-bit alignment */ + u32 source_index; + char source[4]; /* pad to 64 bits so sizeof() works in all cases */ +}; + +/* + * END: of definitions for PCI Routing tables + */ + + +#endif /* __ACTYPES_H__ */ diff -Nru a/include/acpi/acutils.h b/include/acpi/acutils.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/acutils.h Sun Feb 9 21:13:28 2003 @@ -0,0 +1,815 @@ +/****************************************************************************** + * + * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef _ACUTILS_H +#define _ACUTILS_H + + +typedef +acpi_status (*acpi_pkg_callback) ( + u8 object_type, + union acpi_operand_object *source_object, + union acpi_generic_state *state, + void *context); + + +acpi_status +acpi_ut_walk_package_tree ( + union acpi_operand_object *source_object, + void *target_object, + acpi_pkg_callback walk_callback, + void *context); + + +struct acpi_pkg_info +{ + u8 *free_space; + acpi_size length; + u32 object_space; + u32 num_packages; +}; + +#define REF_INCREMENT (u16) 0 +#define REF_DECREMENT (u16) 1 +#define REF_FORCE_DELETE (u16) 2 + +/* acpi_ut_dump_buffer */ + +#define DB_BYTE_DISPLAY 1 +#define DB_WORD_DISPLAY 2 +#define DB_DWORD_DISPLAY 4 +#define DB_QWORD_DISPLAY 8 + + +/* Global initialization interfaces */ + +void +acpi_ut_init_globals ( + void); + +void +acpi_ut_terminate ( + void); + + +/* + * ut_init - miscellaneous initialization and shutdown + */ + +acpi_status +acpi_ut_hardware_initialize ( + void); + +void +acpi_ut_subsystem_shutdown ( + void); + +acpi_status +acpi_ut_validate_fadt ( + void); + +/* + * ut_global - Global data structures and procedures + */ + +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) + +char * +acpi_ut_get_mutex_name ( + u32 mutex_id); + +#endif + +char * +acpi_ut_get_type_name ( + acpi_object_type type); + +char * +acpi_ut_get_object_type_name ( + union acpi_operand_object *obj_desc); + +char * +acpi_ut_get_region_name ( + u8 space_id); + +char * +acpi_ut_get_event_name ( + u32 event_id); + +char +acpi_ut_hex_to_ascii_char ( + acpi_integer integer, + u32 position); + +u8 +acpi_ut_valid_object_type ( + acpi_object_type type); + +acpi_owner_id +acpi_ut_allocate_owner_id ( + u32 id_type); + + +/* + * ut_clib - Local implementations of C library functions + */ + +#ifndef ACPI_USE_SYSTEM_CLIBRARY + +acpi_size +acpi_ut_strlen ( + const char *string); + +char * +acpi_ut_strcpy ( + char *dst_string, + const char *src_string); + +char * +acpi_ut_strncpy ( + char *dst_string, + const char *src_string, + acpi_size count); + +int +acpi_ut_strncmp ( + const char *string1, + const char *string2, + acpi_size count); + +int +acpi_ut_strcmp ( + const char *string1, + const char *string2); + +char * +acpi_ut_strcat ( + char *dst_string, + const char *src_string); + +char * +acpi_ut_strncat ( + char *dst_string, + const char *src_string, + acpi_size count); + +u32 +acpi_ut_strtoul ( + const char *string, + char **terminator, + u32 base); + +char * +acpi_ut_strstr ( + char *string1, + char *string2); + +void * +acpi_ut_memcpy ( + void *dest, + const void *src, + acpi_size count); + +void * +acpi_ut_memset ( + void *dest, + acpi_native_uint value, + acpi_size count); + +int +acpi_ut_to_upper ( + int c); + +int +acpi_ut_to_lower ( + int c); + +extern const u8 _acpi_ctype[]; + +#define _ACPI_XA 0x00 /* extra alphabetic - not supported */ +#define _ACPI_XS 0x40 /* extra space */ +#define _ACPI_BB 0x00 /* BEL, BS, etc. - not supported */ +#define _ACPI_CN 0x20 /* CR, FF, HT, NL, VT */ +#define _ACPI_DI 0x04 /* '0'-'9' */ +#define _ACPI_LO 0x02 /* 'a'-'z' */ +#define _ACPI_PU 0x10 /* punctuation */ +#define _ACPI_SP 0x08 /* space */ +#define _ACPI_UP 0x01 /* 'A'-'Z' */ +#define _ACPI_XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */ + +#define ACPI_IS_DIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_DI)) +#define ACPI_IS_SPACE(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_SP)) +#define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD)) +#define ACPI_IS_UPPER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP)) +#define ACPI_IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO)) +#define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU)) +#define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP)) +#define ACPI_IS_ASCII(c) ((c) < 0x80) + +#endif /* ACPI_USE_SYSTEM_CLIBRARY */ + +/* + * ut_copy - Object construction and conversion interfaces + */ + +acpi_status +acpi_ut_build_simple_object( + union acpi_operand_object *obj, + union acpi_object *user_obj, + u8 *data_space, + u32 *buffer_space_used); + +acpi_status +acpi_ut_build_package_object ( + union acpi_operand_object *obj, + u8 *buffer, + u32 *space_used); + +acpi_status +acpi_ut_copy_ielement_to_eelement ( + u8 object_type, + union acpi_operand_object *source_object, + union acpi_generic_state *state, + void *context); + +acpi_status +acpi_ut_copy_ielement_to_ielement ( + u8 object_type, + union acpi_operand_object *source_object, + union acpi_generic_state *state, + void *context); + +acpi_status +acpi_ut_copy_iobject_to_eobject ( + union acpi_operand_object *obj, + struct acpi_buffer *ret_buffer); + +acpi_status +acpi_ut_copy_esimple_to_isimple( + union acpi_object *user_obj, + union acpi_operand_object **return_obj); + +acpi_status +acpi_ut_copy_eobject_to_iobject ( + union acpi_object *obj, + union acpi_operand_object **internal_obj); + +acpi_status +acpi_ut_copy_isimple_to_isimple ( + union acpi_operand_object *source_obj, + union acpi_operand_object *dest_obj); + +acpi_status +acpi_ut_copy_ipackage_to_ipackage ( + union acpi_operand_object *source_obj, + union acpi_operand_object *dest_obj, + struct acpi_walk_state *walk_state); + +acpi_status +acpi_ut_copy_simple_object ( + union acpi_operand_object *source_desc, + union acpi_operand_object *dest_desc); + +acpi_status +acpi_ut_copy_iobject_to_iobject ( + union acpi_operand_object *source_desc, + union acpi_operand_object **dest_desc, + struct acpi_walk_state *walk_state); + + +/* + * ut_create - Object creation + */ + +acpi_status +acpi_ut_update_object_reference ( + union acpi_operand_object *object, + u16 action); + + +/* + * ut_debug - Debug interfaces + */ + +void +acpi_ut_init_stack_ptr_trace ( + void); + +void +acpi_ut_track_stack_ptr ( + void); + +void +acpi_ut_trace ( + u32 line_number, + struct acpi_debug_print_info *dbg_info); + +void +acpi_ut_trace_ptr ( + u32 line_number, + struct acpi_debug_print_info *dbg_info, + void *pointer); + +void +acpi_ut_trace_u32 ( + u32 line_number, + struct acpi_debug_print_info *dbg_info, + u32 integer); + +void +acpi_ut_trace_str ( + u32 line_number, + struct acpi_debug_print_info *dbg_info, + char *string); + +void +acpi_ut_exit ( + u32 line_number, + struct acpi_debug_print_info *dbg_info); + +void +acpi_ut_status_exit ( + u32 line_number, + struct acpi_debug_print_info *dbg_info, + acpi_status status); + +void +acpi_ut_value_exit ( + u32 line_number, + struct acpi_debug_print_info *dbg_info, + acpi_integer value); + +void +acpi_ut_ptr_exit ( + u32 line_number, + struct acpi_debug_print_info *dbg_info, + u8 *ptr); + +void +acpi_ut_report_info ( + char *module_name, + u32 line_number, + u32 component_id); + +void +acpi_ut_report_error ( + char *module_name, + u32 line_number, + u32 component_id); + +void +acpi_ut_report_warning ( + char *module_name, + u32 line_number, + u32 component_id); + +void +acpi_ut_dump_buffer ( + u8 *buffer, + u32 count, + u32 display, + u32 component_id); + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_debug_print ( + u32 requested_debug_level, + u32 line_number, + struct acpi_debug_print_info *dbg_info, + char *format, + ...) ACPI_PRINTF_LIKE_FUNC; + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_debug_print_raw ( + u32 requested_debug_level, + u32 line_number, + struct acpi_debug_print_info *dbg_info, + char *format, + ...) ACPI_PRINTF_LIKE_FUNC; + + +/* + * ut_delete - Object deletion + */ + +void +acpi_ut_delete_internal_obj ( + union acpi_operand_object *object); + +void +acpi_ut_delete_internal_package_object ( + union acpi_operand_object *object); + +void +acpi_ut_delete_internal_simple_object ( + union acpi_operand_object *object); + +void +acpi_ut_delete_internal_object_list ( + union acpi_operand_object **obj_list); + + +/* + * ut_eval - object evaluation + */ + +/* Method name strings */ + +#define METHOD_NAME__HID "_HID" +#define METHOD_NAME__CID "_CID" +#define METHOD_NAME__UID "_UID" +#define METHOD_NAME__ADR "_ADR" +#define METHOD_NAME__STA "_STA" +#define METHOD_NAME__REG "_REG" +#define METHOD_NAME__SEG "_SEG" +#define METHOD_NAME__BBN "_BBN" +#define METHOD_NAME__PRT "_PRT" + + +acpi_status +acpi_ut_evaluate_object ( + struct acpi_namespace_node *prefix_node, + char *path, + u32 expected_return_btypes, + union acpi_operand_object **return_desc); + +acpi_status +acpi_ut_evaluate_numeric_object ( + char *object_name, + struct acpi_namespace_node *device_node, + acpi_integer *address); + +acpi_status +acpi_ut_execute_HID ( + struct acpi_namespace_node *device_node, + struct acpi_device_id *hid); + +acpi_status +acpi_ut_execute_CID ( + struct acpi_namespace_node *device_node, + struct acpi_device_id *cid); + +acpi_status +acpi_ut_execute_STA ( + struct acpi_namespace_node *device_node, + u32 *status_flags); + +acpi_status +acpi_ut_execute_UID ( + struct acpi_namespace_node *device_node, + struct acpi_device_id *uid); + + +/* + * ut_mutex - mutual exclusion interfaces + */ + +acpi_status +acpi_ut_mutex_initialize ( + void); + +void +acpi_ut_mutex_terminate ( + void); + +acpi_status +acpi_ut_create_mutex ( + acpi_mutex_handle mutex_id); + +acpi_status +acpi_ut_delete_mutex ( + acpi_mutex_handle mutex_id); + +acpi_status +acpi_ut_acquire_mutex ( + acpi_mutex_handle mutex_id); + +acpi_status +acpi_ut_release_mutex ( + acpi_mutex_handle mutex_id); + + +/* + * ut_object - internal object create/delete/cache routines + */ + +union acpi_operand_object * +acpi_ut_create_internal_object_dbg ( + char *module_name, + u32 line_number, + u32 component_id, + acpi_object_type type); + +void * +acpi_ut_allocate_object_desc_dbg ( + char *module_name, + u32 line_number, + u32 component_id); + +#define acpi_ut_create_internal_object(t) acpi_ut_create_internal_object_dbg (_THIS_MODULE,__LINE__,_COMPONENT,t) +#define acpi_ut_allocate_object_desc() acpi_ut_allocate_object_desc_dbg (_THIS_MODULE,__LINE__,_COMPONENT) + +void +acpi_ut_delete_object_desc ( + union acpi_operand_object *object); + +u8 +acpi_ut_valid_internal_object ( + void *object); + +union acpi_operand_object * +acpi_ut_create_buffer_object ( + acpi_size buffer_size); + + +/* + * ut_ref_cnt - Object reference count management + */ + +void +acpi_ut_add_reference ( + union acpi_operand_object *object); + +void +acpi_ut_remove_reference ( + union acpi_operand_object *object); + +/* + * ut_size - Object size routines + */ + +acpi_status +acpi_ut_get_simple_object_size ( + union acpi_operand_object *obj, + acpi_size *obj_length); + +acpi_status +acpi_ut_get_package_object_size ( + union acpi_operand_object *obj, + acpi_size *obj_length); + +acpi_status +acpi_ut_get_object_size( + union acpi_operand_object *obj, + acpi_size *obj_length); + +acpi_status +acpi_ut_get_element_length ( + u8 object_type, + union acpi_operand_object *source_object, + union acpi_generic_state *state, + void *context); + + +/* + * ut_state - Generic state creation/cache routines + */ + +void +acpi_ut_push_generic_state ( + union acpi_generic_state **list_head, + union acpi_generic_state *state); + +union acpi_generic_state * +acpi_ut_pop_generic_state ( + union acpi_generic_state **list_head); + + +union acpi_generic_state * +acpi_ut_create_generic_state ( + void); + +struct acpi_thread_state * +acpi_ut_create_thread_state ( + void); + +union acpi_generic_state * +acpi_ut_create_update_state ( + union acpi_operand_object *object, + u16 action); + +union acpi_generic_state * +acpi_ut_create_pkg_state ( + void *internal_object, + void *external_object, + u16 index); + +acpi_status +acpi_ut_create_update_state_and_push ( + union acpi_operand_object *object, + u16 action, + union acpi_generic_state **state_list); + +acpi_status +acpi_ut_create_pkg_state_and_push ( + void *internal_object, + void *external_object, + u16 index, + union acpi_generic_state **state_list); + +union acpi_generic_state * +acpi_ut_create_control_state ( + void); + +void +acpi_ut_delete_generic_state ( + union acpi_generic_state *state); + +void +acpi_ut_delete_generic_state_cache ( + void); + +void +acpi_ut_delete_object_cache ( + void); + +/* + * utmisc + */ + +void +acpi_ut_print_string ( + char *string, + u8 max_length); + +acpi_status +acpi_ut_divide ( + acpi_integer *in_dividend, + acpi_integer *in_divisor, + acpi_integer *out_quotient, + acpi_integer *out_remainder); + +acpi_status +acpi_ut_short_divide ( + acpi_integer *in_dividend, + u32 divisor, + acpi_integer *out_quotient, + u32 *out_remainder); + +u8 +acpi_ut_valid_acpi_name ( + u32 name); + +u8 +acpi_ut_valid_acpi_character ( + char character); + +acpi_status +acpi_ut_strtoul64 ( + char *string, + u32 base, + acpi_integer *ret_integer); + +char * +acpi_ut_strupr ( + char *src_string); + +u8 * +acpi_ut_get_resource_end_tag ( + union acpi_operand_object *obj_desc); + +u8 +acpi_ut_generate_checksum ( + u8 *buffer, + u32 length); + +u32 +acpi_ut_dword_byte_swap ( + u32 value); + +void +acpi_ut_set_integer_width ( + u8 revision); + +#ifdef ACPI_DEBUG_OUTPUT +void +acpi_ut_display_init_pathname ( + u8 type, + struct acpi_namespace_node *obj_handle, + char *path); + +#endif + + +/* + * Utalloc - memory allocation and object caching + */ + +void * +acpi_ut_acquire_from_cache ( + u32 list_id); + +void +acpi_ut_release_to_cache ( + u32 list_id, + void *object); + +void +acpi_ut_delete_generic_cache ( + u32 list_id); + +acpi_status +acpi_ut_validate_buffer ( + struct acpi_buffer *buffer); + +acpi_status +acpi_ut_initialize_buffer ( + struct acpi_buffer *buffer, + acpi_size required_length); + + +/* Memory allocation functions */ + +void * +acpi_ut_allocate ( + acpi_size size, + u32 component, + char *module, + u32 line); + +void * +acpi_ut_callocate ( + acpi_size size, + u32 component, + char *module, + u32 line); + + +#ifdef ACPI_DBG_TRACK_ALLOCATIONS + +void * +acpi_ut_allocate_and_track ( + acpi_size size, + u32 component, + char *module, + u32 line); + +void * +acpi_ut_callocate_and_track ( + acpi_size size, + u32 component, + char *module, + u32 line); + +void +acpi_ut_free_and_track ( + void *address, + u32 component, + char *module, + u32 line); + +struct acpi_debug_mem_block * +acpi_ut_find_allocation ( + u32 list_id, + void *allocation); + +acpi_status +acpi_ut_track_allocation ( + u32 list_id, + struct acpi_debug_mem_block *address, + acpi_size size, + u8 alloc_type, + u32 component, + char *module, + u32 line); + +acpi_status +acpi_ut_remove_allocation ( + u32 list_id, + struct acpi_debug_mem_block *address, + u32 component, + char *module, + u32 line); + +void +acpi_ut_dump_allocation_info ( + void); + +void +acpi_ut_dump_allocations ( + u32 component, + char *module); +#endif + + +#endif /* _ACUTILS_H */ diff -Nru a/include/acpi/amlcode.h b/include/acpi/amlcode.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/amlcode.h Sun Feb 9 21:13:33 2003 @@ -0,0 +1,477 @@ +/****************************************************************************** + * + * Name: amlcode.h - Definitions for AML, as included in "definition blocks" + * Declarations and definitions contained herein are derived + * directly from the ACPI specification. + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __AMLCODE_H__ +#define __AMLCODE_H__ + +/* primary opcodes */ + +#define AML_NULL_CHAR (u16) 0x00 + +#define AML_ZERO_OP (u16) 0x00 +#define AML_ONE_OP (u16) 0x01 +#define AML_UNASSIGNED (u16) 0x02 +#define AML_ALIAS_OP (u16) 0x06 +#define AML_NAME_OP (u16) 0x08 +#define AML_BYTE_OP (u16) 0x0a +#define AML_WORD_OP (u16) 0x0b +#define AML_DWORD_OP (u16) 0x0c +#define AML_STRING_OP (u16) 0x0d +#define AML_QWORD_OP (u16) 0x0e /* ACPI 2.0 */ +#define AML_SCOPE_OP (u16) 0x10 +#define AML_BUFFER_OP (u16) 0x11 +#define AML_PACKAGE_OP (u16) 0x12 +#define AML_VAR_PACKAGE_OP (u16) 0x13 /* ACPI 2.0 */ +#define AML_METHOD_OP (u16) 0x14 +#define AML_DUAL_NAME_PREFIX (u16) 0x2e +#define AML_MULTI_NAME_PREFIX_OP (u16) 0x2f +#define AML_NAME_CHAR_SUBSEQ (u16) 0x30 +#define AML_NAME_CHAR_FIRST (u16) 0x41 +#define AML_OP_PREFIX (u16) 0x5b +#define AML_ROOT_PREFIX (u16) 0x5c +#define AML_PARENT_PREFIX (u16) 0x5e +#define AML_LOCAL_OP (u16) 0x60 +#define AML_LOCAL0 (u16) 0x60 +#define AML_LOCAL1 (u16) 0x61 +#define AML_LOCAL2 (u16) 0x62 +#define AML_LOCAL3 (u16) 0x63 +#define AML_LOCAL4 (u16) 0x64 +#define AML_LOCAL5 (u16) 0x65 +#define AML_LOCAL6 (u16) 0x66 +#define AML_LOCAL7 (u16) 0x67 +#define AML_ARG_OP (u16) 0x68 +#define AML_ARG0 (u16) 0x68 +#define AML_ARG1 (u16) 0x69 +#define AML_ARG2 (u16) 0x6a +#define AML_ARG3 (u16) 0x6b +#define AML_ARG4 (u16) 0x6c +#define AML_ARG5 (u16) 0x6d +#define AML_ARG6 (u16) 0x6e +#define AML_STORE_OP (u16) 0x70 +#define AML_REF_OF_OP (u16) 0x71 +#define AML_ADD_OP (u16) 0x72 +#define AML_CONCAT_OP (u16) 0x73 +#define AML_SUBTRACT_OP (u16) 0x74 +#define AML_INCREMENT_OP (u16) 0x75 +#define AML_DECREMENT_OP (u16) 0x76 +#define AML_MULTIPLY_OP (u16) 0x77 +#define AML_DIVIDE_OP (u16) 0x78 +#define AML_SHIFT_LEFT_OP (u16) 0x79 +#define AML_SHIFT_RIGHT_OP (u16) 0x7a +#define AML_BIT_AND_OP (u16) 0x7b +#define AML_BIT_NAND_OP (u16) 0x7c +#define AML_BIT_OR_OP (u16) 0x7d +#define AML_BIT_NOR_OP (u16) 0x7e +#define AML_BIT_XOR_OP (u16) 0x7f +#define AML_BIT_NOT_OP (u16) 0x80 +#define AML_FIND_SET_LEFT_BIT_OP (u16) 0x81 +#define AML_FIND_SET_RIGHT_BIT_OP (u16) 0x82 +#define AML_DEREF_OF_OP (u16) 0x83 +#define AML_CONCAT_RES_OP (u16) 0x84 /* ACPI 2.0 */ +#define AML_MOD_OP (u16) 0x85 /* ACPI 2.0 */ +#define AML_NOTIFY_OP (u16) 0x86 +#define AML_SIZE_OF_OP (u16) 0x87 +#define AML_INDEX_OP (u16) 0x88 +#define AML_MATCH_OP (u16) 0x89 +#define AML_CREATE_DWORD_FIELD_OP (u16) 0x8a +#define AML_CREATE_WORD_FIELD_OP (u16) 0x8b +#define AML_CREATE_BYTE_FIELD_OP (u16) 0x8c +#define AML_CREATE_BIT_FIELD_OP (u16) 0x8d +#define AML_TYPE_OP (u16) 0x8e +#define AML_CREATE_QWORD_FIELD_OP (u16) 0x8f /* ACPI 2.0 */ +#define AML_LAND_OP (u16) 0x90 +#define AML_LOR_OP (u16) 0x91 +#define AML_LNOT_OP (u16) 0x92 +#define AML_LEQUAL_OP (u16) 0x93 +#define AML_LGREATER_OP (u16) 0x94 +#define AML_LLESS_OP (u16) 0x95 +#define AML_TO_BUFFER_OP (u16) 0x96 /* ACPI 2.0 */ +#define AML_TO_DECSTRING_OP (u16) 0x97 /* ACPI 2.0 */ +#define AML_TO_HEXSTRING_OP (u16) 0x98 /* ACPI 2.0 */ +#define AML_TO_INTEGER_OP (u16) 0x99 /* ACPI 2.0 */ +#define AML_TO_STRING_OP (u16) 0x9c /* ACPI 2.0 */ +#define AML_COPY_OP (u16) 0x9d /* ACPI 2.0 */ +#define AML_MID_OP (u16) 0x9e /* ACPI 2.0 */ +#define AML_CONTINUE_OP (u16) 0x9f /* ACPI 2.0 */ +#define AML_IF_OP (u16) 0xa0 +#define AML_ELSE_OP (u16) 0xa1 +#define AML_WHILE_OP (u16) 0xa2 +#define AML_NOOP_OP (u16) 0xa3 +#define AML_RETURN_OP (u16) 0xa4 +#define AML_BREAK_OP (u16) 0xa5 +#define AML_BREAK_POINT_OP (u16) 0xcc +#define AML_ONES_OP (u16) 0xff + +/* prefixed opcodes */ + +#define AML_EXTOP (u16) 0x005b + + +#define AML_MUTEX_OP (u16) 0x5b01 +#define AML_EVENT_OP (u16) 0x5b02 +#define AML_SHIFT_RIGHT_BIT_OP (u16) 0x5b10 +#define AML_SHIFT_LEFT_BIT_OP (u16) 0x5b11 +#define AML_COND_REF_OF_OP (u16) 0x5b12 +#define AML_CREATE_FIELD_OP (u16) 0x5b13 +#define AML_LOAD_TABLE_OP (u16) 0x5b1f /* ACPI 2.0 */ +#define AML_LOAD_OP (u16) 0x5b20 +#define AML_STALL_OP (u16) 0x5b21 +#define AML_SLEEP_OP (u16) 0x5b22 +#define AML_ACQUIRE_OP (u16) 0x5b23 +#define AML_SIGNAL_OP (u16) 0x5b24 +#define AML_WAIT_OP (u16) 0x5b25 +#define AML_RESET_OP (u16) 0x5b26 +#define AML_RELEASE_OP (u16) 0x5b27 +#define AML_FROM_BCD_OP (u16) 0x5b28 +#define AML_TO_BCD_OP (u16) 0x5b29 +#define AML_UNLOAD_OP (u16) 0x5b2a +#define AML_REVISION_OP (u16) 0x5b30 +#define AML_DEBUG_OP (u16) 0x5b31 +#define AML_FATAL_OP (u16) 0x5b32 +#define AML_REGION_OP (u16) 0x5b80 +#define AML_FIELD_OP (u16) 0x5b81 +#define AML_DEVICE_OP (u16) 0x5b82 +#define AML_PROCESSOR_OP (u16) 0x5b83 +#define AML_POWER_RES_OP (u16) 0x5b84 +#define AML_THERMAL_ZONE_OP (u16) 0x5b85 +#define AML_INDEX_FIELD_OP (u16) 0x5b86 +#define AML_BANK_FIELD_OP (u16) 0x5b87 +#define AML_DATA_REGION_OP (u16) 0x5b88 /* ACPI 2.0 */ + + +/* Bogus opcodes (they are actually two separate opcodes) */ + +#define AML_LGREATEREQUAL_OP (u16) 0x9295 +#define AML_LLESSEQUAL_OP (u16) 0x9294 +#define AML_LNOTEQUAL_OP (u16) 0x9293 + + +/* + * Internal opcodes + * Use only "Unknown" AML opcodes, don't attempt to use + * any valid ACPI ASCII values (A-Z, 0-9, '-') + */ + +#define AML_INT_NAMEPATH_OP (u16) 0x002d +#define AML_INT_NAMEDFIELD_OP (u16) 0x0030 +#define AML_INT_RESERVEDFIELD_OP (u16) 0x0031 +#define AML_INT_ACCESSFIELD_OP (u16) 0x0032 +#define AML_INT_BYTELIST_OP (u16) 0x0033 +#define AML_INT_STATICSTRING_OP (u16) 0x0034 +#define AML_INT_METHODCALL_OP (u16) 0x0035 +#define AML_INT_RETURN_VALUE_OP (u16) 0x0036 +#define AML_INT_EVAL_SUBTREE_OP (u16) 0x0037 + + +#define ARG_NONE 0x0 + +/* + * Argument types for the AML Parser + * Each field in the arg_types u32 is 5 bits, allowing for a maximum of 6 arguments. + * There can be up to 31 unique argument types + */ + +#define ARGP_BYTEDATA 0x01 +#define ARGP_BYTELIST 0x02 +#define ARGP_CHARLIST 0x03 +#define ARGP_DATAOBJ 0x04 +#define ARGP_DATAOBJLIST 0x05 +#define ARGP_DWORDDATA 0x06 +#define ARGP_FIELDLIST 0x07 +#define ARGP_NAME 0x08 +#define ARGP_NAMESTRING 0x09 +#define ARGP_OBJLIST 0x0A +#define ARGP_PKGLENGTH 0x0B +#define ARGP_SUPERNAME 0x0C +#define ARGP_TARGET 0x0D +#define ARGP_TERMARG 0x0E +#define ARGP_TERMLIST 0x0F +#define ARGP_WORDDATA 0x10 +#define ARGP_QWORDDATA 0x11 +#define ARGP_SIMPLENAME 0x12 + +/* + * Resolved argument types for the AML Interpreter + * Each field in the arg_types u32 is 5 bits, allowing for a maximum of 6 arguments. + * There can be up to 31 unique argument types (0 is end-of-arg-list indicator) + * + * Note: If and when 5 bits becomes insufficient, it would probably be best + * to convert to a 6-byte array of argument types, allowing 8 bits per argument. + */ + +/* "Standard" ACPI types are 1-15 (0x0F) */ + +#define ARGI_INTEGER ACPI_TYPE_INTEGER /* 1 */ +#define ARGI_STRING ACPI_TYPE_STRING /* 2 */ +#define ARGI_BUFFER ACPI_TYPE_BUFFER /* 3 */ +#define ARGI_PACKAGE ACPI_TYPE_PACKAGE /* 4 */ +#define ARGI_EVENT ACPI_TYPE_EVENT +#define ARGI_MUTEX ACPI_TYPE_MUTEX +#define ARGI_REGION ACPI_TYPE_REGION +#define ARGI_DDBHANDLE ACPI_TYPE_DDB_HANDLE + +/* Custom types are 0x10 through 0x1F */ + +#define ARGI_IF 0x10 +#define ARGI_ANYOBJECT 0x11 +#define ARGI_ANYTYPE 0x12 +#define ARGI_COMPUTEDATA 0x13 /* Buffer, String, or Integer */ +#define ARGI_DATAOBJECT 0x14 /* Buffer, String, package or reference to a Node - Used only by size_of operator*/ +#define ARGI_COMPLEXOBJ 0x15 /* Buffer, String, or package (Used by INDEX op only) */ +#define ARGI_INTEGER_REF 0x16 +#define ARGI_OBJECT_REF 0x17 +#define ARGI_DEVICE_REF 0x18 +#define ARGI_REFERENCE 0x19 +#define ARGI_TARGETREF 0x1A /* Target, subject to implicit conversion */ +#define ARGI_FIXED_TARGET 0x1B /* Target, no implicit conversion */ +#define ARGI_SIMPLE_TARGET 0x1C /* Name, Local, Arg -- no implicit conversion */ +#define ARGI_BUFFERSTRING 0x1D +#define ARGI_REF_OR_STRING 0x1E /* Reference or String (Used by DEREFOF op only) */ + +#define ARGI_INVALID_OPCODE 0xFFFFFFFF + + +/* + * hash offsets + */ +#define AML_EXTOP_HASH_OFFSET 22 +#define AML_LNOT_HASH_OFFSET 19 + + +/* + * opcode groups and types + */ + +#define OPGRP_NAMED 0x01 +#define OPGRP_FIELD 0x02 +#define OPGRP_BYTELIST 0x04 + + +/* + * Opcode information + */ + +/* Opcode flags */ + +#define AML_HAS_ARGS 0x0800 +#define AML_HAS_TARGET 0x0400 +#define AML_HAS_RETVAL 0x0200 +#define AML_NSOBJECT 0x0100 +#define AML_NSOPCODE 0x0080 +#define AML_NSNODE 0x0040 +#define AML_NAMED 0x0020 +#define AML_DEFER 0x0010 +#define AML_FIELD 0x0008 +#define AML_CREATE 0x0004 +#define AML_MATH 0x0002 +#define AML_LOGICAL 0x0001 +#define AML_CONSTANT 0x1000 + +/* Convenient flag groupings */ + +#define AML_FLAGS_EXEC_1A_0T_0R AML_HAS_ARGS /* Monadic1 */ +#define AML_FLAGS_EXEC_1A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Monadic2 */ +#define AML_FLAGS_EXEC_1A_1T_0R AML_HAS_ARGS | AML_HAS_TARGET +#define AML_FLAGS_EXEC_1A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* monadic2_r */ +#define AML_FLAGS_EXEC_2A_0T_0R AML_HAS_ARGS /* Dyadic1 */ +#define AML_FLAGS_EXEC_2A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL /* Dyadic2 */ +#define AML_FLAGS_EXEC_2A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL /* dyadic2_r */ +#define AML_FLAGS_EXEC_2A_2T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL +#define AML_FLAGS_EXEC_3A_0T_0R AML_HAS_ARGS +#define AML_FLAGS_EXEC_3A_1T_1R AML_HAS_ARGS | AML_HAS_TARGET | AML_HAS_RETVAL +#define AML_FLAGS_EXEC_6A_0T_1R AML_HAS_ARGS | AML_HAS_RETVAL + + +/* + * The opcode Type is used in a dispatch table, do not change + * without updating the table. + */ +#define AML_TYPE_EXEC_1A_0T_0R 0x00 /* Monadic1 */ +#define AML_TYPE_EXEC_1A_0T_1R 0x01 /* Monadic2 */ +#define AML_TYPE_EXEC_1A_1T_0R 0x02 +#define AML_TYPE_EXEC_1A_1T_1R 0x03 /* monadic2_r */ +#define AML_TYPE_EXEC_2A_0T_0R 0x04 /* Dyadic1 */ +#define AML_TYPE_EXEC_2A_0T_1R 0x05 /* Dyadic2 */ +#define AML_TYPE_EXEC_2A_1T_1R 0x06 /* dyadic2_r */ +#define AML_TYPE_EXEC_2A_2T_1R 0x07 +#define AML_TYPE_EXEC_3A_0T_0R 0x08 +#define AML_TYPE_EXEC_3A_1T_1R 0x09 +#define AML_TYPE_EXEC_6A_0T_1R 0x0A +/* End of types used in dispatch table */ + +#define AML_TYPE_LITERAL 0x0B +#define AML_TYPE_CONSTANT 0x0C +#define AML_TYPE_METHOD_ARGUMENT 0x0D +#define AML_TYPE_LOCAL_VARIABLE 0x0E +#define AML_TYPE_DATA_TERM 0x0F + +/* Generic for an op that returns a value */ + +#define AML_TYPE_METHOD_CALL 0x10 + +/* Misc */ + +#define AML_TYPE_CREATE_FIELD 0x11 +#define AML_TYPE_CREATE_OBJECT 0x12 +#define AML_TYPE_CONTROL 0x13 +#define AML_TYPE_NAMED_NO_OBJ 0x14 +#define AML_TYPE_NAMED_FIELD 0x15 +#define AML_TYPE_NAMED_SIMPLE 0x16 +#define AML_TYPE_NAMED_COMPLEX 0x17 +#define AML_TYPE_RETURN 0x18 + +#define AML_TYPE_UNDEFINED 0x19 +#define AML_TYPE_BOGUS 0x1A + + +/* + * Opcode classes + */ +#define AML_CLASS_EXECUTE 0x00 +#define AML_CLASS_CREATE 0x01 +#define AML_CLASS_ARGUMENT 0x02 +#define AML_CLASS_NAMED_OBJECT 0x03 +#define AML_CLASS_CONTROL 0x04 +#define AML_CLASS_ASCII 0x05 +#define AML_CLASS_PREFIX 0x06 +#define AML_CLASS_INTERNAL 0x07 +#define AML_CLASS_RETURN_VALUE 0x08 +#define AML_CLASS_METHOD_CALL 0x09 +#define AML_CLASS_UNKNOWN 0x0A + + +/* Predefined Operation Region space_iDs */ + +typedef enum +{ + REGION_MEMORY = 0, + REGION_IO, + REGION_PCI_CONFIG, + REGION_EC, + REGION_SMBUS, + REGION_CMOS, + REGION_PCI_BAR, + REGION_DATA_TABLE, /* Internal use only */ + REGION_FIXED_HW = 0x7F + +} AML_REGION_TYPES; + + +/* Comparison operation codes for match_op operator */ + +typedef enum +{ + MATCH_MTR = 0, + MATCH_MEQ = 1, + MATCH_MLE = 2, + MATCH_MLT = 3, + MATCH_MGE = 4, + MATCH_MGT = 5 + +} AML_MATCH_OPERATOR; + +#define MAX_MATCH_OPERATOR 5 + + +/* + * field_flags + * + * This byte is extracted from the AML and includes three separate + * pieces of information about the field: + * 1) The field access type + * 2) The field update rule + * 3) The lock rule for the field + * + * Bits 00 - 03 : access_type (any_acc, byte_acc, etc.) + * 04 : lock_rule (1 == Lock) + * 05 - 06 : update_rule + */ +#define AML_FIELD_ACCESS_TYPE_MASK 0x0F +#define AML_FIELD_LOCK_RULE_MASK 0x10 +#define AML_FIELD_UPDATE_RULE_MASK 0x60 + + +/* 1) Field Access Types */ + +typedef enum +{ + AML_FIELD_ACCESS_ANY = 0x00, + AML_FIELD_ACCESS_BYTE = 0x01, + AML_FIELD_ACCESS_WORD = 0x02, + AML_FIELD_ACCESS_DWORD = 0x03, + AML_FIELD_ACCESS_QWORD = 0x04, /* ACPI 2.0 */ + AML_FIELD_ACCESS_BUFFER = 0x05 /* ACPI 2.0 */ + +} AML_ACCESS_TYPE; + + +/* 2) Field Lock Rules */ + +typedef enum +{ + AML_FIELD_LOCK_NEVER = 0x00, + AML_FIELD_LOCK_ALWAYS = 0x10 + +} AML_LOCK_RULE; + + +/* 3) Field Update Rules */ + +typedef enum +{ + AML_FIELD_UPDATE_PRESERVE = 0x00, + AML_FIELD_UPDATE_WRITE_AS_ONES = 0x20, + AML_FIELD_UPDATE_WRITE_AS_ZEROS = 0x40 + +} AML_UPDATE_RULE; + + +/* + * Field Access Attributes. + * This byte is extracted from the AML via the + * access_as keyword + */ +typedef enum +{ + AML_FIELD_ATTRIB_SMB_QUICK = 0x02, + AML_FIELD_ATTRIB_SMB_SEND_RCV = 0x04, + AML_FIELD_ATTRIB_SMB_BYTE = 0x06, + AML_FIELD_ATTRIB_SMB_WORD = 0x08, + AML_FIELD_ATTRIB_SMB_BLOCK = 0x0A, + AML_FIELD_ATTRIB_SMB_WORD_CALL = 0x0C, + AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D + +} AML_ACCESS_ATTRIBUTE; + + +/* bit fields in method_flags byte */ + +#define METHOD_FLAGS_ARG_COUNT 0x07 +#define METHOD_FLAGS_SERIALIZED 0x08 +#define METHOD_FLAGS_SYNCH_LEVEL 0xF0 + + +#endif /* __AMLCODE_H__ */ diff -Nru a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/platform/acenv.h Sun Feb 9 21:13:29 2003 @@ -0,0 +1,344 @@ +/****************************************************************************** + * + * Name: acenv.h - Generation environment specific items + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACENV_H__ +#define __ACENV_H__ + + +/* + * Configuration for ACPI tools and utilities + */ + +#ifdef _ACPI_DUMP_APP +#ifndef MSDOS +#define ACPI_DEBUG_OUTPUT +#endif +#define ACPI_APPLICATION +#define ACPI_DISASSEMBLER +#define ACPI_NO_METHOD_EXECUTION +#define ACPI_USE_SYSTEM_CLIBRARY +#endif + +#ifdef _ACPI_EXEC_APP +#undef DEBUGGER_THREADING +#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED +#define ACPI_DEBUG_OUTPUT +#define ACPI_APPLICATION +#define ACPI_DEBUGGER +#define ACPI_DISASSEMBLER +#define ACPI_USE_SYSTEM_CLIBRARY +#endif + +#ifdef _ACPI_ASL_COMPILER +#define ACPI_DEBUG_OUTPUT +#define ACPI_APPLICATION +#define ACPI_DISASSEMBLER +#define ACPI_CONSTANT_EVAL_ONLY +#define ACPI_USE_SYSTEM_CLIBRARY +#endif + +/* + * Environment configuration. The purpose of this file is to interface to the + * local generation environment. + * + * 1) ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library. + * Otherwise, local versions of string/memory functions will be used. + * 2) ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and + * the standard header files may be used. + * + * The ACPI subsystem only uses low level C library functions that do not call + * operating system services and may therefore be inlined in the code. + * + * It may be necessary to tailor these include files to the target + * generation environment. + * + * + * Functions and constants used from each header: + * + * string.h: memcpy + * memset + * strcat + * strcmp + * strcpy + * strlen + * strncmp + * strncat + * strncpy + * + * stdlib.h: strtoul + * + * stdarg.h: va_list + * va_arg + * va_start + * va_end + * + */ + +/*! [Begin] no source code translation */ + +#if defined(_LINUX) +#include "aclinux.h" + +#elif defined(_AED_EFI) +#include "acefi.h" + +#elif defined(WIN32) +#include "acwin.h" + +#elif defined(WIN64) +#include "acwin64.h" + +#elif defined(MSDOS) /* Must appear after WIN32 and WIN64 check */ +#include "acdos16.h" + +#elif defined(__FreeBSD__) +#include "acfreebsd.h" + +#elif defined(MODESTO) +#include "acmodesto.h" + +#elif defined(NETWARE) +#include "acnetware.h" + +#else + +/* All other environments */ + +#define ACPI_USE_STANDARD_HEADERS + +#define COMPILER_DEPENDENT_INT64 long long +#define COMPILER_DEPENDENT_UINT64 unsigned long long + + +/* Name of host operating system (returned by the _OS_ namespace object) */ + +#define ACPI_OS_NAME "Intel ACPI/CA Core Subsystem" + +/* This macro is used to tag functions as "printf-like" because + * some compilers can catch printf format string problems. MSVC + * doesn't, so this is proprocessed away. + */ +#define ACPI_PRINTF_LIKE_FUNC + +#endif + +/* + * Memory allocation tracking. Used only if + * 1) This is the debug version + * 2) This is NOT a 16-bit version of the code (not enough real-mode memory) + */ +#ifdef ACPI_DEBUG_OUTPUT +#if ACPI_MACHINE_WIDTH != 16 +#define ACPI_DBG_TRACK_ALLOCATIONS +#endif +#endif + +/*! [End] no source code translation !*/ + + +/* + * Debugger threading model + * Use single threaded if the entire subsystem is contained in an application + * Use multiple threaded when the subsystem is running in the kernel. + * + * By default the model is single threaded if ACPI_APPLICATION is set, + * multi-threaded if ACPI_APPLICATION is not set. + */ +#define DEBUGGER_SINGLE_THREADED 0 +#define DEBUGGER_MULTI_THREADED 1 + +#ifdef ACPI_APPLICATION +#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED + +#else +#define DEBUGGER_THREADING DEBUGGER_MULTI_THREADED +#endif + + +/****************************************************************************** + * + * C library configuration + * + *****************************************************************************/ + +#ifdef ACPI_USE_SYSTEM_CLIBRARY +/* + * Use the standard C library headers. + * We want to keep these to a minimum. + */ + +#ifdef ACPI_USE_STANDARD_HEADERS +/* + * Use the standard headers from the standard locations + */ +#include +#include +#include +#include + +#endif /* ACPI_USE_STANDARD_HEADERS */ + +/* + * We will be linking to the standard Clib functions + */ + +#define ACPI_STRSTR(s1,s2) strstr((s1), (s2)) +#define ACPI_STRUPR(s) (void) acpi_ut_strupr ((s)) +#define ACPI_STRLEN(s) (acpi_size) strlen((s)) +#define ACPI_STRCPY(d,s) (void) strcpy((d), (s)) +#define ACPI_STRNCPY(d,s,n) (void) strncpy((d), (s), (acpi_size)(n)) +#define ACPI_STRNCMP(d,s,n) strncmp((d), (s), (acpi_size)(n)) +#define ACPI_STRCMP(d,s) strcmp((d), (s)) +#define ACPI_STRCAT(d,s) (void) strcat((d), (s)) +#define ACPI_STRNCAT(d,s,n) strncat((d), (s), (acpi_size)(n)) +#define ACPI_STRTOUL(d,s,n) strtoul((d), (s), (acpi_size)(n)) +#define ACPI_MEMCPY(d,s,n) (void) memcpy((d), (s), (acpi_size)(n)) +#define ACPI_MEMSET(d,s,n) (void) memset((d), (s), (acpi_size)(n)) + +#define ACPI_TOUPPER toupper +#define ACPI_TOLOWER tolower +#define ACPI_IS_XDIGIT isxdigit +#define ACPI_IS_DIGIT isdigit +#define ACPI_IS_SPACE isspace +#define ACPI_IS_UPPER isupper +#define ACPI_IS_PRINT isprint +#define ACPI_IS_ALPHA isalpha +#define ACPI_IS_ASCII isascii + +/****************************************************************************** + * + * Not using native C library, use local implementations + * + *****************************************************************************/ +#else + +/* + * Use local definitions of C library macros and functions + * NOTE: The function implementations may not be as efficient + * as an inline or assembly code implementation provided by a + * native C library. + */ + +#ifndef va_arg + +#ifndef _VALIST +#define _VALIST +typedef char *va_list; +#endif /* _VALIST */ + +/* + * Storage alignment properties + */ + +#define _AUPBND (sizeof (acpi_native_int) - 1) +#define _ADNBND (sizeof (acpi_native_int) - 1) + +/* + * Variable argument list macro definitions + */ + +#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd))) +#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND)))) +#define va_end(ap) (void) 0 +#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND)))) + +#endif /* va_arg */ + + +#define ACPI_STRSTR(s1,s2) acpi_ut_strstr ((s1), (s2)) +#define ACPI_STRUPR(s) (void) acpi_ut_strupr ((s)) +#define ACPI_STRLEN(s) (acpi_size) acpi_ut_strlen ((s)) +#define ACPI_STRCPY(d,s) (void) acpi_ut_strcpy ((d), (s)) +#define ACPI_STRNCPY(d,s,n) (void) acpi_ut_strncpy ((d), (s), (acpi_size)(n)) +#define ACPI_STRNCMP(d,s,n) acpi_ut_strncmp ((d), (s), (acpi_size)(n)) +#define ACPI_STRCMP(d,s) acpi_ut_strcmp ((d), (s)) +#define ACPI_STRCAT(d,s) (void) acpi_ut_strcat ((d), (s)) +#define ACPI_STRNCAT(d,s,n) acpi_ut_strncat ((d), (s), (acpi_size)(n)) +#define ACPI_STRTOUL(d,s,n) acpi_ut_strtoul ((d), (s), (acpi_size)(n)) +#define ACPI_MEMCPY(d,s,n) (void) acpi_ut_memcpy ((d), (s), (acpi_size)(n)) +#define ACPI_MEMSET(d,v,n) (void) acpi_ut_memset ((d), (v), (acpi_size)(n)) +#define ACPI_TOUPPER acpi_ut_to_upper +#define ACPI_TOLOWER acpi_ut_to_lower + +#endif /* ACPI_USE_SYSTEM_CLIBRARY */ + + +/****************************************************************************** + * + * Assembly code macros + * + *****************************************************************************/ + +/* + * Handle platform- and compiler-specific assembly language differences. + * These should already have been defined by the platform includes above. + * + * Notes: + * 1) Interrupt 3 is used to break into a debugger + * 2) Interrupts are turned off during ACPI register setup + */ + +/* Unrecognized compiler, use defaults */ + +#ifndef ACPI_ASM_MACROS + +/* + * Calling conventions: + * + * ACPI_SYSTEM_XFACE - Interfaces to host OS (handlers, threads) + * ACPI_EXTERNAL_XFACE - External ACPI interfaces + * ACPI_INTERNAL_XFACE - Internal ACPI interfaces + * ACPI_INTERNAL_VAR_XFACE - Internal variable-parameter list interfaces + */ +#define ACPI_SYSTEM_XFACE +#define ACPI_EXTERNAL_XFACE +#define ACPI_INTERNAL_XFACE +#define ACPI_INTERNAL_VAR_XFACE + +#define ACPI_ASM_MACROS +#define BREAKPOINT3 +#define ACPI_DISABLE_IRQS() +#define ACPI_ENABLE_IRQS() +#define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acq) +#define ACPI_RELEASE_GLOBAL_LOCK(Glptr, acq) + +#endif /* ACPI_ASM_MACROS */ + + +#ifdef ACPI_APPLICATION + +/* Don't want software interrupts within a ring3 application */ + +#undef BREAKPOINT3 +#define BREAKPOINT3 +#endif + + +/****************************************************************************** + * + * Compiler-specific information is contained in the compiler-specific + * headers. + * + *****************************************************************************/ +#endif /* __ACENV_H__ */ diff -Nru a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/platform/acgcc.h Sun Feb 9 21:13:36 2003 @@ -0,0 +1,40 @@ +/****************************************************************************** + * + * Name: acgcc.h - GCC specific defines, etc. + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACGCC_H__ +#define __ACGCC_H__ + +/* This macro is used to tag functions as "printf-like" because + * some compilers (like GCC) can catch printf format string problems. + */ +#define ACPI_PRINTF_LIKE_FUNC __attribute__ ((__format__ (__printf__, 4, 5))) + +/* Some compilers complain about unused variables. Sometimes we don't want to + * use all the variables (most specifically for _THIS_MODULE). This allow us + * to to tell the compiler warning in a per-variable manner that a variable + * is unused. + */ +#define ACPI_UNUSED_VAR __attribute__ ((unused)) + +#endif /* __ACGCC_H__ */ diff -Nru a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/platform/aclinux.h Sun Feb 9 21:13:35 2003 @@ -0,0 +1,72 @@ +/****************************************************************************** + * + * Name: aclinux.h - OS specific defines, etc. + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * + * 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 + */ + +#ifndef __ACLINUX_H__ +#define __ACLINUX_H__ + +#define ACPI_OS_NAME "Linux" + +#define ACPI_USE_SYSTEM_CLIBRARY + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define strtoul simple_strtoul + +#define ACPI_MACHINE_WIDTH BITS_PER_LONG + +#else /* !__KERNEL__ */ + +#include +#include +#include +#include +#include + +#if defined(__ia64__) || defined(__x86_64__) +#define ACPI_MACHINE_WIDTH 64 +#define COMPILER_DEPENDENT_INT64 long +#define COMPILER_DEPENDENT_UINT64 unsigned long +#else +#define ACPI_MACHINE_WIDTH 32 +#define COMPILER_DEPENDENT_INT64 long long +#define COMPILER_DEPENDENT_UINT64 unsigned long long +#define ACPI_USE_NATIVE_DIVIDE +#endif + +#endif /* __KERNEL__ */ + +/* Linux uses GCC */ + +#include "acgcc.h" + +#endif /* __ACLINUX_H__ */ diff -Nru a/include/acpi/processor.h b/include/acpi/processor.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/acpi/processor.h Sun Feb 9 21:13:37 2003 @@ -0,0 +1,141 @@ +#ifndef __ACPI_PROCESSOR_H +#define __ACPI_PROCESSOR_H + +#include + +#define ACPI_PROCESSOR_BUSY_METRIC 10 + +#define ACPI_PROCESSOR_MAX_POWER ACPI_C_STATE_COUNT +#define ACPI_PROCESSOR_MAX_C2_LATENCY 100 +#define ACPI_PROCESSOR_MAX_C3_LATENCY 1000 + +#define ACPI_PROCESSOR_MAX_PERFORMANCE 8 + +#define ACPI_PROCESSOR_MAX_THROTTLING 16 +#define ACPI_PROCESSOR_MAX_THROTTLE 250 /* 25% */ +#define ACPI_PROCESSOR_MAX_DUTY_WIDTH 4 + +/* Power Management */ + +struct acpi_processor_cx_policy { + u32 count; + int state; + struct { + u32 time; + u32 ticks; + u32 count; + u32 bm; + } threshold; +}; + +struct acpi_processor_cx { + u8 valid; + u32 address; + u32 latency; + u32 latency_ticks; + u32 power; + u32 usage; + struct acpi_processor_cx_policy promotion; + struct acpi_processor_cx_policy demotion; +}; + +struct acpi_processor_power { + int state; + int default_state; + u32 bm_activity; + struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER]; +}; + +/* Performance Management */ + +struct acpi_pct_register { + u8 descriptor; + u16 length; + u8 space_id; + u8 bit_width; + u8 bit_offset; + u8 reserved; + u64 address; +} __attribute__ ((packed)); + +struct acpi_processor_px { + acpi_integer core_frequency; /* megahertz */ + acpi_integer power; /* milliWatts */ + acpi_integer transition_latency; /* microseconds */ + acpi_integer bus_master_latency; /* microseconds */ + acpi_integer control; /* control value */ + acpi_integer status; /* success indicator */ +}; + +struct acpi_processor_performance { + int state; + int platform_limit; + u16 control_register; + u16 status_register; + int state_count; + struct acpi_processor_px states[ACPI_PROCESSOR_MAX_PERFORMANCE]; + struct cpufreq_frequency_table freq_table[ACPI_PROCESSOR_MAX_PERFORMANCE]; + struct acpi_processor *pr; +}; + + +/* Throttling Control */ + +struct acpi_processor_tx { + u16 power; + u16 performance; +}; + +struct acpi_processor_throttling { + int state; + u32 address; + u8 duty_offset; + u8 duty_width; + int state_count; + struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING]; +}; + +/* Limit Interface */ + +struct acpi_processor_lx { + int px; /* performace state */ + int tx; /* throttle level */ +}; + +struct acpi_processor_limit { + struct acpi_processor_lx state; /* current limit */ + struct acpi_processor_lx thermal; /* thermal limit */ + struct acpi_processor_lx user; /* user limit */ +}; + + +struct acpi_processor_flags { + u8 power:1; + u8 performance:1; + u8 throttling:1; + u8 limit:1; + u8 bm_control:1; + u8 bm_check:1; + u8 reserved:2; +}; + +struct acpi_processor { + acpi_handle handle; + u32 acpi_id; + u32 id; + int performance_platform_limit; + struct acpi_processor_flags flags; + struct acpi_processor_power power; + struct acpi_processor_performance *performance; + struct acpi_processor_throttling throttling; + struct acpi_processor_limit limit; +}; + +extern int acpi_processor_get_platform_limit ( + struct acpi_processor* pr); +extern int acpi_processor_register_performance ( + struct acpi_processor_performance * performance, + struct acpi_processor ** pr, + unsigned int cpu); + +#endif diff -Nru a/include/asm-alpha/core_irongate.h b/include/asm-alpha/core_irongate.h --- a/include/asm-alpha/core_irongate.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-alpha/core_irongate.h Sun Feb 9 21:13:30 2003 @@ -50,13 +50,14 @@ igcsr32 bacsr10; /* 0x40 - base address chip selects */ igcsr32 bacsr32; /* 0x44 - base address chip selects */ - igcsr32 bacsr54; /* 0x48 - base address chip selects */ + igcsr32 bacsr54_eccms761; /* 0x48 - 751: base addr. chip selects + 761: ECC, mode/status */ igcsr32 rsrvd2[1]; /* 0x4C-0x4F reserved */ igcsr32 drammap; /* 0x50 - address mapping control */ igcsr32 dramtm; /* 0x54 - timing, driver strength */ - igcsr32 dramms; /* 0x58 - ECC, mode/status */ + igcsr32 dramms; /* 0x58 - DRAM mode/status */ igcsr32 rsrvd3[1]; /* 0x5C-0x5F reserved */ @@ -73,7 +74,10 @@ igcsr32 pciarb; /* 0x84 - PCI arbitration control */ igcsr32 pcicfg; /* 0x88 - PCI config status */ - igcsr32 rsrvd6[5]; /* 0x8C-0x9F reserved */ + igcsr32 rsrvd6[4]; /* 0x8C-0x9B reserved */ + + igcsr32 pci_mem; /* 0x9C - PCI top of memory, + 761 only */ /* AGP (bus 1) control registers */ igcsr32 agpcap; /* 0xA0 - AGP Capability Identifier */ @@ -102,6 +106,7 @@ } Irongate1; +extern igcsr32 *IronECC; /* * Memory spaces: diff -Nru a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h --- a/include/asm-alpha/elf.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-alpha/elf.h Sun Feb 9 21:13:32 2003 @@ -52,53 +52,25 @@ #define ELF_PLAT_INIT(_r) _r->r0 = 0 -/* Use the same format as the OSF/1 procfs interface. The register - layout is sane. However, since dump_thread() creates the funky - layout that ECOFF coredumps want, we need to undo that layout here. - Eventually, it would be nice if the ECOFF core-dump had to do the - translation, then ELF_CORE_COPY_REGS() would become trivial and - faster. */ +/* The registers are layed out in pt_regs for PAL and syscall + convenience. Re-order them for the linear elf_gregset_t. */ -#define ELF_CORE_COPY_REGS(_dest,_regs) \ -{ \ - extern void dump_thread(struct pt_regs *, struct user *); \ - struct user _dump; \ - \ - dump_thread(_regs, &_dump); \ - _dest[ 0] = _dump.regs[EF_V0]; \ - _dest[ 1] = _dump.regs[EF_T0]; \ - _dest[ 2] = _dump.regs[EF_T1]; \ - _dest[ 3] = _dump.regs[EF_T2]; \ - _dest[ 4] = _dump.regs[EF_T3]; \ - _dest[ 5] = _dump.regs[EF_T4]; \ - _dest[ 6] = _dump.regs[EF_T5]; \ - _dest[ 7] = _dump.regs[EF_T6]; \ - _dest[ 8] = _dump.regs[EF_T7]; \ - _dest[ 9] = _dump.regs[EF_S0]; \ - _dest[10] = _dump.regs[EF_S1]; \ - _dest[11] = _dump.regs[EF_S2]; \ - _dest[12] = _dump.regs[EF_S3]; \ - _dest[13] = _dump.regs[EF_S4]; \ - _dest[14] = _dump.regs[EF_S5]; \ - _dest[15] = _dump.regs[EF_S6]; \ - _dest[16] = _dump.regs[EF_A0]; \ - _dest[17] = _dump.regs[EF_A1]; \ - _dest[18] = _dump.regs[EF_A2]; \ - _dest[19] = _dump.regs[EF_A3]; \ - _dest[20] = _dump.regs[EF_A4]; \ - _dest[21] = _dump.regs[EF_A5]; \ - _dest[22] = _dump.regs[EF_T8]; \ - _dest[23] = _dump.regs[EF_T9]; \ - _dest[24] = _dump.regs[EF_T10]; \ - _dest[25] = _dump.regs[EF_T11]; \ - _dest[26] = _dump.regs[EF_RA]; \ - _dest[27] = _dump.regs[EF_T12]; \ - _dest[28] = _dump.regs[EF_AT]; \ - _dest[29] = _dump.regs[EF_GP]; \ - _dest[30] = _dump.regs[EF_SP]; \ - _dest[31] = _dump.regs[EF_PC]; /* store PC here */ \ - _dest[32] = _dump.regs[EF_PS]; \ -} +extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, + struct thread_info *ti); +#define ELF_CORE_COPY_REGS(DEST, REGS) \ + dump_elf_thread(DEST, REGS, current_thread_info()); + +/* Similar, but for a thread other than current. */ + +extern int dump_elf_task(elf_greg_t *dest, struct task_struct *task); +#define ELF_CORE_COPY_TASK_REGS(TASK, DEST) \ + dump_elf_task(*(DEST), TASK) + +/* Similar, but for the FP registers. */ + +extern int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task); +#define ELF_CORE_COPY_FPREGS(TASK, DEST) \ + dump_elf_task_fp(*(DEST), TASK) /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. This is trivial on Alpha, diff -Nru a/include/asm-alpha/kmap_types.h b/include/asm-alpha/kmap_types.h --- a/include/asm-alpha/kmap_types.h Sun Feb 9 21:13:37 2003 +++ b/include/asm-alpha/kmap_types.h Sun Feb 9 21:13:37 2003 @@ -23,8 +23,8 @@ D(8) KM_PTE1, D(9) KM_IRQ0, D(10) KM_IRQ1, -D(11) KM_CRYPTO_USER, -D(12) KM_CRYPTO_SOFTIRQ, +D(11) KM_SOFTIRQ0, +D(12) KM_SOFTIRQ1, D(13) KM_TYPE_NR }; diff -Nru a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h --- a/include/asm-alpha/pci.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-alpha/pci.h Sun Feb 9 21:13:28 2003 @@ -68,16 +68,16 @@ decisions. */ #define PCI_DMA_BUS_IS_PHYS 0 -/* Allocate and map kernel buffer using consistant mode DMA for PCI +/* Allocate and map kernel buffer using consistent mode DMA for PCI device. Returns non-NULL cpu-view pointer to the buffer if successful and sets *DMA_ADDRP to the pci side dma address as well, else DMA_ADDRP is undefined. */ extern void *pci_alloc_consistent(struct pci_dev *, size_t, dma_addr_t *); -/* Free and unmap a consistant DMA buffer. CPU_ADDR and DMA_ADDR must - be values that were returned from pci_alloc_consistant. SIZE must - be the same as what as passed into pci_alloc_consistant. +/* Free and unmap a consistent DMA buffer. CPU_ADDR and DMA_ADDR must + be values that were returned from pci_alloc_consistent. SIZE must + be the same as what as passed into pci_alloc_consistent. References to the memory and mappings assosciated with CPU_ADDR or DMA_ADDR past this call are illegal. */ @@ -139,7 +139,7 @@ extern void pci_unmap_sg(struct pci_dev *, struct scatterlist *, int, int); -/* Make physical memory consistant for a single streaming mode DMA +/* Make physical memory consistent for a single streaming mode DMA translation after a transfer. If you perform a pci_map_single() but wish to interrogate the @@ -155,7 +155,7 @@ /* Nothing to do. */ } -/* Make physical memory consistant for a set of streaming mode DMA +/* Make physical memory consistent for a set of streaming mode DMA translations after a transfer. The same as pci_dma_sync_single but for a scatter-gather list, same rules and usage. */ diff -Nru a/include/asm-alpha/signal.h b/include/asm-alpha/signal.h --- a/include/asm-alpha/signal.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-alpha/signal.h Sun Feb 9 21:13:32 2003 @@ -93,7 +93,7 @@ #define SA_NOCLDSTOP 0x00000004 #define SA_NODEFER 0x00000008 #define SA_RESETHAND 0x00000010 -#define SA_NOCLDWAIT 0x00000020 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000020 #define SA_SIGINFO 0x00000040 #define SA_ONESHOT SA_RESETHAND diff -Nru a/include/asm-alpha/topology.h b/include/asm-alpha/topology.h --- a/include/asm-alpha/topology.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-alpha/topology.h Sun Feb 9 21:13:30 2003 @@ -6,7 +6,7 @@ #include #ifdef CONFIG_NUMA -static inline int __cpu_to_node(int cpu) +static inline int cpu_to_node(int cpu) { int node; @@ -23,13 +23,13 @@ return node; } -static inline int __node_to_cpu_mask(int node) +static inline int node_to_cpumask(int node) { unsigned long node_cpu_mask = 0; int cpu; for(cpu = 0; cpu < NR_CPUS; cpu++) { - if (cpu_online(cpu) && (__cpu_to_node(cpu) == node)) + if (cpu_online(cpu) && (cpu_to_node(cpu) == node)) node_cpu_mask |= 1UL << cpu; } @@ -40,8 +40,11 @@ return node_cpu_mask; } -# define __node_to_memblk(node) (node) -# define __memblk_to_node(memblk) (memblk) +# define node_to_memblk(node) (node) +# define memblk_to_node(memblk) (memblk) + +/* Cross-node load balancing interval. */ +# define NODE_BALANCE_RATE 10 #else /* CONFIG_NUMA */ # include diff -Nru a/include/asm-arm/arch-ebsa110/param.h b/include/asm-arm/arch-ebsa110/param.h --- a/include/asm-arm/arch-ebsa110/param.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-arm/arch-ebsa110/param.h Sun Feb 9 21:13:28 2003 @@ -1,3 +1,4 @@ /* * linux/include/asm-arm/arch-ebsa110/param.h */ +#define __KERNEL_HZ 200 diff -Nru a/include/asm-arm/arch-ebsa110/time.h b/include/asm-arm/arch-ebsa110/time.h --- a/include/asm-arm/arch-ebsa110/time.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-arm/arch-ebsa110/time.h Sun Feb 9 21:13:30 2003 @@ -17,17 +17,80 @@ */ #include +#include -extern int ebsa110_reset_timer(void); -extern void ebsa110_setup_timer(void); +extern unsigned long (*gettimeoffset)(void); + +#define PIT_CTRL (PIT_BASE + 0x0d) +#define PIT_T2 (PIT_BASE + 0x09) +#define PIT_T1 (PIT_BASE + 0x05) +#define PIT_T0 (PIT_BASE + 0x01) + +/* + * This is the rate at which your MCLK signal toggles (in Hz) + * This was measured on a 10 digit frequency counter sampling + * over 1 second. + */ +#define MCLK 47894000 + +/* + * This is the rate at which the PIT timers get clocked + */ +#define CLKBY7 (MCLK / 7) + +/* + * This is the counter value. We tick at 200Hz on this platform. + */ +#define COUNT ((CLKBY7 + (HZ / 2)) / HZ) + +/* + * Get the time offset from the system PIT. Note that if we have missed an + * interrupt, then the PIT counter will roll over (ie, be negative). + * This actually works out to be convenient. + */ +static unsigned long ebsa110_gettimeoffset(void) +{ + unsigned long offset, count; + + __raw_writeb(0x40, PIT_CTRL); + count = __raw_readb(PIT_T1); + count |= __raw_readb(PIT_T1) << 8; + + /* + * If count > COUNT, make the number negative. + */ + if (count > COUNT) + count |= 0xffff0000; + + offset = COUNT; + offset -= count; + + /* + * `offset' is in units of timer counts. Convert + * offset to units of microseconds. + */ + offset = offset * (1000000 / HZ) / COUNT; + + return offset; +} static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - if (ebsa110_reset_timer()) { - do_leds(); - do_timer(regs); - do_profile(regs); - } + u32 count; + + /* latch and read timer 1 */ + __raw_writeb(0x40, PIT_CTRL); + count = __raw_readb(PIT_T1); + count |= __raw_readb(PIT_T1) << 8; + + count += COUNT; + + __raw_writeb(count & 0xff, PIT_T1); + __raw_writeb(count >> 8, PIT_T1); + + do_leds(); + do_timer(regs); + do_profile(regs); } /* @@ -35,7 +98,14 @@ */ void __init time_init(void) { - ebsa110_setup_timer(); + /* + * Timer 1, mode 2, LSB/MSB + */ + __raw_writeb(0x70, PIT_CTRL); + __raw_writeb(COUNT & 0xff, PIT_T1); + __raw_writeb(COUNT >> 8, PIT_T1); + + gettimeoffset = ebsa110_gettimeoffset; timer_irq.handler = timer_interrupt; diff -Nru a/include/asm-arm/arch-rpc/hardware.h b/include/asm-arm/arch-rpc/hardware.h --- a/include/asm-arm/arch-rpc/hardware.h Sun Feb 9 21:13:37 2003 +++ b/include/asm-arm/arch-rpc/hardware.h Sun Feb 9 21:13:37 2003 @@ -63,6 +63,17 @@ #define IO_EC_MEMC8_BASE 0x8000ac00 #define IO_EC_MEMC_BASE 0x80000000 +#define NETSLOT_BASE 0x0302b000 +#define NETSLOT_SIZE 0x00001000 + +#define PODSLOT_IOC0_BASE 0x03240000 +#define PODSLOT_IOC4_BASE 0x03270000 +#define PODSLOT_IOC_SIZE (1 << 14) +#define PODSLOT_MEMC_BASE 0x03000000 +#define PODSLOT_MEMC_SIZE (1 << 14) +#define PODSLOT_EASI_BASE 0x08000000 +#define PODSLOT_EASI_SIZE (1 << 24) + #define EXPMASK_STATUS (EXPMASK_BASE + 0x00) #define EXPMASK_ENABLE (EXPMASK_BASE + 0x04) diff -Nru a/include/asm-arm/arch-rpc/io.h b/include/asm-arm/arch-rpc/io.h --- a/include/asm-arm/arch-rpc/io.h Sun Feb 9 21:13:33 2003 +++ b/include/asm-arm/arch-rpc/io.h Sun Feb 9 21:13:33 2003 @@ -247,4 +247,9 @@ #define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l) #define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l) +/* + * 1:1 mapping for ioremapped regions. + */ +#define __mem_pci(x) (x) + #endif diff -Nru a/include/asm-arm/arch-sa1100/ide.h b/include/asm-arm/arch-sa1100/ide.h --- a/include/asm-arm/arch-sa1100/ide.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-arm/arch-sa1100/ide.h Sun Feb 9 21:13:28 2003 @@ -49,8 +49,9 @@ *irq = 0; } - - +#ifdef CONFIG_SA1100_TRIZEPS +#include +#endif /* * This registers the standard ports for this architecture with the IDE @@ -124,6 +125,23 @@ ide_register_hw(&hw); #endif } -} + else if( machine_is_trizeps() ){ +#ifdef CONFIG_SA1100_TRIZEPS + hw_regs_t hw; + /* Enable appropriate GPIOs as interrupt lines */ + GPDR &= ~GPIO_GPIO(TRIZEPS_IRQ_IDE); + set_irq_type( TRIZEPS_IRQ_IDE, IRQT_RISING ); + /* set the pcmcia interface timing */ + //MECR = 0x00060006; // Done on trizeps init + + /* Take hard drives out of reset */ + GPSR = GPIO_GPIO(TRIZEPS_IRQ_IDE); + + ide_init_hwif_ports(&hw, TRIZEPS_IDE_CS0 + 0, TRIZEPS_IDE_CS1 + 6, NULL); + hw.irq = TRIZEPS_IRQ_IDE; + ide_register_hw(&hw, NULL); +#endif + } +} diff -Nru a/include/asm-arm/arch-sa1100/mftb2.h b/include/asm-arm/arch-sa1100/mftb2.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-arm/arch-sa1100/mftb2.h Sun Feb 9 21:13:38 2003 @@ -0,0 +1,210 @@ +#ifndef _ARCH_ARM_MFTB2_h_ +#define _ARCH_ARM_MFTB2_h_ + +// Defines for arch/arm/mm/mm-sa1100.h +#define TRIZEPS_PHYS_VIRT_MAP_SIZE 0x00800000l + +// physical address (only for mm-sa1100.h) +#define TRIZEPS_PHYS_IO_BASE 0x30000000l +#define TRIZEPS_PHYS_MEM_BASE 0x38000000l + +// virtual +#define TRIZEPS_IO_BASE 0xF0000000l +#define TRIZEPS_MEM_BASE 0xF2000000l + +// Offsets for phys and virtual +#define TRIZEPS_OFFSET_REG0 0x00300000l +#define TRIZEPS_OFFSET_REG1 0x00380000l +#define TRIZEPS_OFFSET_IDE_CS0 0x00000000l +#define TRIZEPS_OFFSET_IDE_CS1 0x00080000l +#define TRIZEPS_OFFSET_UART5 0x00100000l +#define TRIZEPS_OFFSET_UART6 0x00180000l +#define TRIZEPS_PHYS_REG0 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_REG0) +#define TRIZEPS_PHYS_REG1 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_REG1) +#define TRIZEPS_PHYS_IDE_CS0 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_IDE_CS0) +#define TRIZEPS_PHYS_IDE_CS1 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_IDE_CS1) +#define TRIZEPS_PHYS_UART5 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_UART5) +#define TRIZEPS_PHYS_UART6 (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_UART6) + +// Use follow defines in devices +// virtual address +#define TRIZEPS_REG0 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_REG0) +#define TRIZEPS_REG1 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_REG1) +#define TRIZEPS_IDE_CS0 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_IDE_CS0) +#define TRIZEPS_IDE_CS1 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_IDE_CS1) +#define TRIZEPS_UART5 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_UART5) +#define TRIZEPS_UART6 (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_UART6) + +#define TRIZEPS_BAUD_BASE 1500000 + +//#if 0 //temporarily disabled +#ifndef __ASSEMBLY__ +struct tri_uart_cts_data_t { + int cts_gpio; + int cts_prev_state; + struct uart_info *info; + struct uart_port *port; + const char *name; +}; +#endif /* __ASSEMBLY__ */ + +/* Defines for MFTB2 serial_sa1100.c hardware handshaking lines */ +#define SERIAL_FULL +#define NOT_CONNECTED 0 +#ifdef SERIAL_FULL +#define TRIZEPS_GPIO_UART1_RTS GPIO_GPIO14 +#define TRIZEPS_GPIO_UART1_DTR NOT_CONNECTED //GPIO_GPIO9 +#define TRIZEPS_GPIO_UART1_CTS GPIO_GPIO15 +#define TRIZEPS_GPIO_UART1_DCD NOT_CONNECTED //GPIO_GPIO2 +#define TRIZEPS_GPIO_UART1_DSR NOT_CONNECTED //GPIO_GPIO3 +#define TRIZEPS_GPIO_UART3_RTS NOT_CONNECTED //GPIO_GPIO7 +#define TRIZEPS_GPIO_UART3_DTR NOT_CONNECTED //GPIO_GPIO8 +#define TRIZEPS_GPIO_UART3_CTS NOT_CONNECTED //GPIO_GPIO4 +#define TRIZEPS_GPIO_UART3_DCD NOT_CONNECTED //GPIO_GPIO5 +#define TRIZEPS_GPIO_UART3_DSR NOT_CONNECTED //GPIO_GPIO6 + +#define TRIZEPS_GPIO_UART2_RTS NOT_CONNECTED //GPIO_GPIO7 +#define TRIZEPS_GPIO_UART2_DTR NOT_CONNECTED //GPIO_GPIO8 +#define TRIZEPS_GPIO_UART2_CTS NOT_CONNECTED //GPIO_GPIO4 +#define TRIZEPS_GPIO_UART2_DCD NOT_CONNECTED //GPIO_GPIO5 +#define TRIZEPS_GPIO_UART2_DSR NOT_CONNECTED //GPIO_GPIO6 + +#define TRIZEPS_IRQ_UART1_CTS IRQ_GPIO15 +#define TRIZEPS_IRQ_UART1_DCD NO_IRQ //IRQ_GPIO2 +#define TRIZEPS_IRQ_UART1_DSR NO_IRQ //IRQ_GPIO3 +#define TRIZEPS_IRQ_UART3_CTS NO_IRQ //IRQ_GPIO4 +#define TRIZEPS_IRQ_UART3_DCD NO_IRQ //IRQ_GPIO5 +#define TRIZEPS_IRQ_UART3_DSR NO_IRQ //IRQ_GPIO6 + +#define TRIZEPS_IRQ_UART2_CTS NO_IRQ //IRQ_GPIO4 +#define TRIZEPS_IRQ_UART2_DCD NO_IRQ //IRQ_GPIO5 +#define TRIZEPS_IRQ_UART2_DSR NO_IRQ //IRQ_GPIO6 + +#endif /* SERIAL_FULL */ +//#endif //0 + +/* + * This section contains the defines for the MFTB2 implementation + * of drivers/ide/hd.c. HD_IOBASE_0 and HD_IOBASE_1 have to be + * adjusted if hardware changes. + */ +#define TRIZEPS_IRQ_IDE 10 /* MFTB2 specific */ + +/*--- ROOT ---*/ +#define TRIZEPS_GPIO_ROOT_NFS 0 +#define TRIZEPS_GPIO_ROOT_HD 21 +/*--- PCMCIA ---*/ +#define TRIZEPS_GPIO_PCMCIA_IRQ0 1 +#define TRIZEPS_GPIO_PCMCIA_CD0 24 +#define TRIZEPS_IRQ_PCMCIA_IRQ0 TRIZEPS_GPIO_PCMCIA_IRQ0 +#define TRIZEPS_IRQ_PCMCIA_CD0 TRIZEPS_GPIO_PCMCIA_CD0 + 32 - 11 + +// REGISTER 0 -> 0x0XXXX (16bit access) +// read only +#define TRIZEPS_A_STAT 0x8000l +#define TRIZEPS_F_STAT 0x4000l +#define TRIZEPS_BATT_FAULT_EN 0x2000l +#define TRIZEPS_nDQ 0x1000l +#define TRIZEPS_MFT_OFF 0x0800l +#define TRIZEPS_D_APWOFF 0x0400l +#define TRIZEPS_F_CTRL 0x0200l +#define TRIZEPS_F_STOP 0x0100l + +// read / write +#define TRIZEPS_KP_IR_EN 0x0080l +#define TRIZEPS_FIR 0x0040l +#define TRIZEPS_BAR_ON 0x0020l +#define TRIZEPS_VCI_ON 0x0010l +#define TRIZEPS_LED4 0x0008l +#define TRIZEPS_LED3 0x0004l +#define TRIZEPS_LED2 0x0002l +#define TRIZEPS_LED1 0x0001l + +// REGISTER 1 -> 0x1XXXX (16bit access) +// read only +#define TRIZEPS_nVCI2 0x8000l +#define TRIZEPS_nAB_LOW 0x4000l +#define TRIZEPS_nMB_DEAD 0x2000l +#define TRIZEPS_nMB_LOW 0x1000l +#define TRIZEPS_nPCM_VS2 0x0800l +#define TRIZEPS_nPCM_VS1 0x0400l +#define TRIZEPS_PCM_BVD2 0x0200l +#define TRIZEPS_PCM_BVD1 0x0100l + +// read / write +#define TRIZEPS_nROOT_NFS 0x0080l +#define TRIZEPS_nROOT_HD 0x0040l +#define TRIZEPS_nPCM_ENA_REG 0x0020l +#define TRIZEPS_nPCM_RESET_DISABLE 0x0010l +#define TRIZEPS_PCM_EN0_REG 0x0008l +#define TRIZEPS_PCM_EN1_REG 0x0004l +#define TRIZEPS_PCM_V3_EN_REG 0x0002l +#define TRIZEPS_PCM_V5_EN_REG 0x0001l + +/* Access to Board Control Register */ +#define TRIZEPS_BCR0 (*(volatile unsigned short *)(TRIZEPS_REG0)) +#define TRIZEPS_BCR1 (*(volatile unsigned short *)(TRIZEPS_REG1)) + +#define TRIZEPS_BCR_set( reg, x ) do { \ + unsigned long flags; \ + local_irq_save(flags); \ + (reg) |= (x); \ + local_irq_restore(flags); \ +} while (0) + +#define TRIZEPS_BCR_clear( reg, x ) do { \ + unsigned long flags; \ + local_irq_save(flags); \ + (reg) &= ~(x); \ + local_irq_restore(flags); \ +} while (0) + +#define TRIZEPS_OFFSET_KP_REG 0x00200000l +#define TRIZEPS_OFFSET_VCI2 0x00280000l +#define TRIZEPS_OFFSET_VCI4 0x00400000l + +#define TRIZEPS_OFFSET_VCI2_1_DPR (TRIZEPS_OFFSET_VCI2 + 0x00010000l) +#define TRIZEPS_OFFSET_VCI2_2_DPR (TRIZEPS_OFFSET_VCI2 + 0x00018000l) +#define TRIZEPS_OFFSET_VCI2_1_SEMA (TRIZEPS_OFFSET_VCI2 + 0x00020000l) +#define TRIZEPS_OFFSET_VCI2_2_SEMA (TRIZEPS_OFFSET_VCI2 + 0x00028000l) + +#define TRIZEPS_OFFSET_VCI4_1_DPR (TRIZEPS_OFFSET_VCI4 + 0x00000000l) +#define TRIZEPS_OFFSET_VCI4_2_DPR (TRIZEPS_OFFSET_VCI4 + 0x00008000l) +#define TRIZEPS_OFFSET_VCI4_1_SEMA (TRIZEPS_OFFSET_VCI4 + 0x00000380l) +#define TRIZEPS_OFFSET_VCI4_2_SEMA (TRIZEPS_OFFSET_VCI4 + 0x00000388l) +#define TRIZEPS_OFFSET_VCI4_1_CNTR (TRIZEPS_OFFSET_VCI4 + 0x00000390l) +#define TRIZEPS_OFFSET_VCI4_2_CNTR (TRIZEPS_OFFSET_VCI4 + 0x00000392l) + +#define TRIZEPS_PHYS_KP_REG (PHYS_TRIZEPS_IO_BASE + TRIZEPS_OFFSET_KP_REG) + +// VCI address +#define TRIZEPS_PHYS_VCI2_1_DPR (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_DPR) +#define TRIZEPS_PHYS_VCI2_2_DPR (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_DPR) +#define TRIZEPS_PHYS_VCI2_1_SEMA (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_SEMA) +#define TRIZEPS_PHYS_VCI2_2_SEMA (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_SEMA) + +// VCI4 address +#define TRIZEPS_PHYS_VCI4_1_DPR (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI4_1_DPR) +#define TRIZEPS_PHYS_VCI4_2_DPR (TRIZEPS_PHYS_MEM_BASE + TRIZEPS_OFFSET_VCI4_2_DPR) +#define TRIZEPS_PHYS_VCI4_1_SEMA (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_VCI4_1_SEMA) +#define TRIZEPS_PHYS_VCI4_2_SEMA (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_VCI4_2_SEMA) +#define TRIZEPS_PHYS_VCI4_1_CNTR (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_VCI4_1_CNTR) +#define TRIZEPS_PHYS_VCI4_2_CNTR (TRIZEPS_PHYS_IO_BASE + TRIZEPS_OFFSET_VCI4_2_CNTR) + +#define TRIZEPS_KP_REG (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_KP_REG) + +// VCI address +#define TRIZEPS_VCI2_1_DPR (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_DPR) +#define TRIZEPS_VCI2_2_DPR (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_DPR) +#define TRIZEPS_VCI2_1_SEMA (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_1_SEMA) +#define TRIZEPS_VCI2_2_SEMA (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI2_2_SEMA) + +// VCI4 address +#define TRIZEPS_VCI4_1_DPR (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI4_1_DPR) +#define TRIZEPS_VCI4_2_DPR (TRIZEPS_MEM_BASE + TRIZEPS_OFFSET_VCI4_2_DPR) +#define TRIZEPS_VCI4_1_SEMA (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_VCI4_1_SEMA) +#define TRIZEPS_VCI4_2_SEMA (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_VCI4_2_SEMA) +#define TRIZEPS_VCI4_1_CNTR (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_VCI4_1_CNTR) +#define TRIZEPS_VCI4_2_CNTR (TRIZEPS_IO_BASE + TRIZEPS_OFFSET_VCI4_2_CNTR) + +#endif diff -Nru a/include/asm-arm/arch-sa1100/trizeps.h b/include/asm-arm/arch-sa1100/trizeps.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-arm/arch-sa1100/trizeps.h Sun Feb 9 21:13:38 2003 @@ -0,0 +1,20 @@ +/* + * linux/include/asm-arm/arch-sa1100/trizeps.h + * + * This file contains the hardware specific definitions for Trizeps + * + * Authors: + * Andreas Hofer , + * Peter Lueg , + * Guennadi Liakhovetski + * + */ + +#ifndef _ASM_ARCH_TRIZEPS_H_ +#define _ASM_ARCH_TRIZEPS_H_ + +#ifdef CONFIG_TRIZEPS_MFTB2 +#include "mftb2.h" +#endif + +#endif // _INCLUDE_TRIZEPS_ diff -Nru a/include/asm-arm/bug.h b/include/asm-arm/bug.h --- a/include/asm-arm/bug.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-arm/bug.h Sun Feb 9 21:13:28 2003 @@ -18,3 +18,4 @@ #endif +#endif diff -Nru a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h --- a/include/asm-arm/ecard.h Sun Feb 9 21:13:35 2003 +++ b/include/asm-arm/ecard.h Sun Feb 9 21:13:35 2003 @@ -130,6 +130,20 @@ int (*fiqpending)(ecard_t *ec); } expansioncard_ops_t; +#define ECARD_NUM_RESOURCES (6) + +#define ECARD_RES_IOCSLOW (0) +#define ECARD_RES_IOCMEDIUM (1) +#define ECARD_RES_IOCFAST (2) +#define ECARD_RES_IOCSYNC (3) +#define ECARD_RES_MEMC (4) +#define ECARD_RES_EASI (5) + +#define ecard_resource_start(ec,nr) ((ec)->resource[nr].start) +#define ecard_resource_end(ec,nr) ((ec)->resource[nr].end) +#define ecard_resource_len(ec,nr) ((ec)->resource[nr].end - \ + (ec)->resource[nr].start + 1) + /* * This contains all the info needed on an expansion card */ @@ -137,6 +151,7 @@ struct expansion_card *next; struct device dev; + struct resource resource[ECARD_NUM_RESOURCES]; /* Public data */ volatile unsigned char *irqaddr; /* address of IRQ register */ @@ -147,7 +162,7 @@ void *irq_data; /* Data for use for IRQ by card */ void *fiq_data; /* Data for use for FIQ by card */ - expansioncard_ops_t *ops; /* Enable/Disable Ops for card */ + const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */ CONST unsigned int slot_no; /* Slot number */ CONST unsigned int dma; /* DMA number (for request_dma) */ diff -Nru a/include/asm-arm/io.h b/include/asm-arm/io.h --- a/include/asm-arm/io.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-arm/io.h Sun Feb 9 21:13:30 2003 @@ -150,9 +150,17 @@ #define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; }) #define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; }) +#define readsb(p,d,l) __raw_readsb((unsigned int)__mem_pci(p),d,l) +#define readsw(p,d,l) __raw_readsw((unsigned int)__mem_pci(p),d,l) +#define readsl(p,d,l) __raw_readsl((unsigned int)__mem_pci(p),d,l) + #define writeb(v,c) __raw_writeb(v,__mem_pci(c)) #define writew(v,c) __raw_writew(cpu_to_le16(v),__mem_pci(c)) #define writel(v,c) __raw_writel(cpu_to_le32(v),__mem_pci(c)) + +#define writesb(p,d,l) __raw_writesb((unsigned int)__mem_pci(p),d,l) +#define writesw(p,d,l) __raw_writesw((unsigned int)__mem_pci(p),d,l) +#define writesl(p,d,l) __raw_writesl((unsigned int)__mem_pci(p),d,l) #define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l)) #define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l)) diff -Nru a/include/asm-arm/mach/irq.h b/include/asm-arm/mach/irq.h --- a/include/asm-arm/mach/irq.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-arm/mach/irq.h Sun Feb 9 21:13:30 2003 @@ -50,8 +50,8 @@ irq_handler_t handle; struct irqchip *chip; struct irqaction *action; + unsigned int disable_depth; - unsigned int enabled : 1; /* IRQ is currently enabled */ unsigned int triggered: 1; /* IRQ has occurred */ unsigned int running : 1; /* IRQ is running */ unsigned int pending : 1; /* IRQ is pending */ @@ -59,8 +59,7 @@ unsigned int probe_ok : 1; /* IRQ can be used for probe */ unsigned int valid : 1; /* IRQ claimable */ unsigned int noautoenable : 1; /* don't automatically enable IRQ */ - unsigned int unused :23; - unsigned int depth; /* disable depth */ + unsigned int unused :25; /* * IRQ lock detection diff -Nru a/include/asm-arm/module.h b/include/asm-arm/module.h --- a/include/asm-arm/module.h Sun Feb 9 21:13:33 2003 +++ b/include/asm-arm/module.h Sun Feb 9 21:13:33 2003 @@ -10,4 +10,9 @@ #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr +/* + * Include the ARM architecture version. + */ +#define MODULE_ARCH_VERMAGIC "ARMv" __stringify(__LINUX_ARM_ARCH__) " " + #endif /* _ASM_ARM_MODULE_H */ diff -Nru a/include/asm-arm/proc-armv/processor.h b/include/asm-arm/proc-armv/processor.h --- a/include/asm-arm/proc-armv/processor.h Sun Feb 9 21:13:36 2003 +++ b/include/asm-arm/proc-armv/processor.h Sun Feb 9 21:13:36 2003 @@ -23,7 +23,7 @@ #define KERNEL_STACK_SIZE PAGE_SIZE #define INIT_EXTRA_THREAD_INFO \ - cpu_domain: domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \ + .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ domain_val(DOMAIN_IO, DOMAIN_CLIENT) @@ -45,7 +45,7 @@ regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ }) -#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) -#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1017]) +#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019]) +#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1017]) #endif diff -Nru a/include/asm-arm/signal.h b/include/asm-arm/signal.h --- a/include/asm-arm/signal.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-arm/signal.h Sun Feb 9 21:13:32 2003 @@ -90,7 +90,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_THIRTYTWO 0x02000000 #define SA_RESTORER 0x04000000 diff -Nru a/include/asm-cris/io.h b/include/asm-cris/io.h --- a/include/asm-cris/io.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-cris/io.h Sun Feb 9 21:13:34 2003 @@ -246,7 +246,7 @@ #define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void *)(b),(c),(d)) -/* The following is junk needed for the arch-independant code but which +/* The following is junk needed for the arch-independent code but which * we never use in the CRIS port */ diff -Nru a/include/asm-cris/signal.h b/include/asm-cris/signal.h --- a/include/asm-cris/signal.h Sun Feb 9 21:13:35 2003 +++ b/include/asm-cris/signal.h Sun Feb 9 21:13:35 2003 @@ -86,7 +86,7 @@ */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/asm-generic/rmap.h b/include/asm-generic/rmap.h --- a/include/asm-generic/rmap.h Sun Feb 9 21:13:33 2003 +++ b/include/asm-generic/rmap.h Sun Feb 9 21:13:33 2003 @@ -3,7 +3,7 @@ /* * linux/include/asm-generic/rmap.h * - * Architecture dependant parts of the reverse mapping code, + * Architecture dependent parts of the reverse mapping code, * this version should work for most architectures with a * 'normal' page table layout. * diff -Nru a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h --- a/include/asm-generic/rtc.h Sun Feb 9 21:13:31 2003 +++ b/include/asm-generic/rtc.h Sun Feb 9 21:13:31 2003 @@ -147,7 +147,7 @@ yrs = 73; } #endif - /* These limits and adjustments are independant of + /* These limits and adjustments are independent of * whether the chip is in binary mode or not. */ if (yrs > 169) { diff -Nru a/include/asm-generic/topology.h b/include/asm-generic/topology.h --- a/include/asm-generic/topology.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-generic/topology.h Sun Feb 9 21:13:29 2003 @@ -29,23 +29,23 @@ /* Other architectures wishing to use this simple topology API should fill in the below functions as appropriate in their own file. */ -#ifndef __cpu_to_node -#define __cpu_to_node(cpu) (0) +#ifndef cpu_to_node +#define cpu_to_node(cpu) (0) #endif -#ifndef __memblk_to_node -#define __memblk_to_node(memblk) (0) +#ifndef memblk_to_node +#define memblk_to_node(memblk) (0) #endif -#ifndef __parent_node -#define __parent_node(node) (0) +#ifndef parent_node +#define parent_node(node) (0) #endif -#ifndef __node_to_first_cpu -#define __node_to_first_cpu(node) (0) +#ifndef node_to_cpumask +#define node_to_cpumask(node) (cpu_online_map) #endif -#ifndef __node_to_cpu_mask -#define __node_to_cpu_mask(node) (cpu_online_map) +#ifndef node_to_first_cpu +#define node_to_first_cpu(node) (0) #endif -#ifndef __node_to_memblk -#define __node_to_memblk(node) (0) +#ifndef node_to_memblk +#define node_to_memblk(node) (0) #endif /* Cross-node load balancing interval. */ diff -Nru a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h --- a/include/asm-generic/vmlinux.lds.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-generic/vmlinux.lds.h Sun Feb 9 21:13:28 2003 @@ -13,18 +13,32 @@ } \ \ /* Kernel symbol table: Normal symbols */ \ - __start___ksymtab = .; \ __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ + __start___ksymtab = .; \ *(__ksymtab) \ + __stop___ksymtab = .; \ } \ - __stop___ksymtab = .; \ \ /* Kernel symbol table: GPL-only symbols */ \ - __start___gpl_ksymtab = .; \ - __gpl_ksymtab : AT(ADDR(__gpl_ksymtab) - LOAD_OFFSET) { \ - *(__gpl_ksymtab) \ + __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ + __start___ksymtab_gpl = .; \ + *(__ksymtab_gpl) \ + __stop___ksymtab_gpl = .; \ + } \ + \ + /* Kernel symbol table: Normal symbols */ \ + __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ + __start___kcrctab = .; \ + *(__kcrctab) \ + __stop___kcrctab = .; \ + } \ + \ + /* Kernel symbol table: GPL-only symbols */ \ + __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \ + __start___kcrctab_gpl = .; \ + *(__kcrctab_gpl) \ + __stop___kcrctab_gpl = .; \ } \ - __stop___gpl_ksymtab = .; \ \ /* Kernel symbol table: strings */ \ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ diff -Nru a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h --- a/include/asm-i386/apicdef.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-i386/apicdef.h Sun Feb 9 21:13:32 2003 @@ -115,7 +115,7 @@ #define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) -#ifdef CONFIG_X86_NUMA +#ifdef CONFIG_NUMA #define MAX_IO_APICS 32 #else #define MAX_IO_APICS 8 diff -Nru a/include/asm-i386/cpu.h b/include/asm-i386/cpu.h --- a/include/asm-i386/cpu.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-i386/cpu.h Sun Feb 9 21:13:34 2003 @@ -17,7 +17,7 @@ struct node *parent = NULL; #ifdef CONFIG_NUMA - parent = &node_devices[__cpu_to_node(num)].node; + parent = &node_devices[cpu_to_node(num)].node; #endif /* CONFIG_NUMA */ return register_cpu(&cpu_devices[num].cpu, num, parent); diff -Nru a/include/asm-i386/edd.h b/include/asm-i386/edd.h --- a/include/asm-i386/edd.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-i386/edd.h Sun Feb 9 21:13:28 2003 @@ -165,7 +165,7 @@ struct edd_device_params params; } __attribute__ ((packed)); -extern struct edd_info edd[EDDNR]; +extern struct edd_info edd[EDDMAXNR]; extern unsigned char eddnr; #endif /*!__ASSEMBLY__ */ diff -Nru a/include/asm-i386/kmap_types.h b/include/asm-i386/kmap_types.h --- a/include/asm-i386/kmap_types.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-i386/kmap_types.h Sun Feb 9 21:13:34 2003 @@ -22,8 +22,8 @@ D(9) KM_PTE2, D(10) KM_IRQ0, D(11) KM_IRQ1, -D(12) KM_CRYPTO_USER, -D(13) KM_CRYPTO_SOFTIRQ, +D(12) KM_SOFTIRQ0, +D(13) KM_SOFTIRQ1, D(14) KM_TYPE_NR }; diff -Nru a/include/asm-i386/memblk.h b/include/asm-i386/memblk.h --- a/include/asm-i386/memblk.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-i386/memblk.h Sun Feb 9 21:13:32 2003 @@ -14,7 +14,7 @@ extern struct i386_memblk memblk_devices[MAX_NR_MEMBLKS]; static inline int arch_register_memblk(int num){ - int p_node = __memblk_to_node(num); + int p_node = memblk_to_node(num); return register_memblk(&memblk_devices[num].memblk, num, &node_devices[p_node].node); diff -Nru a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h --- a/include/asm-i386/mmzone.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-i386/mmzone.h Sun Feb 9 21:13:32 2003 @@ -57,25 +57,47 @@ #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_end_pfn(nid) \ +({ \ + pg_data_t *__pgdat = NODE_DATA(nid); \ + __pgdat->node_start_pfn + __pgdat->node_size; \ +}) -#define local_mapnr(kvaddr) \ - ( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) ) +#define local_mapnr(kvaddr) \ +({ \ + unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT; \ + (__pfn - node_start_pfn(pfn_to_nid(__pfn))); \ +}) -#define kern_addr_valid(kaddr) test_bit(local_mapnr(kaddr), \ - NODE_DATA(kvaddr_to_nid(kaddr))->valid_addr_bitmap) +#define kern_addr_valid(kaddr) \ +({ \ + unsigned long __kaddr = (unsigned long)(kaddr); \ + pg_data_t *__pgdat = NODE_DATA(kvaddr_to_nid(__kaddr)); \ + test_bit(local_mapnr(__kaddr), __pgdat->valid_addr_bitmap); \ +}) -#define pfn_to_page(pfn) (node_mem_map(pfn_to_nid(pfn)) + node_localnr(pfn, pfn_to_nid(pfn))) -#define page_to_pfn(page) ((page - page_zone(page)->zone_mem_map) + page_zone(page)->zone_start_pfn) +#define pfn_to_page(pfn) \ +({ \ + unsigned long __pfn = pfn; \ + int __node = pfn_to_nid(__pfn); \ + &node_mem_map(__node)[node_localnr(__pfn,__node)]; \ +}) + +#define page_to_pfn(pg) \ +({ \ + struct page *__page = pg; \ + struct zone *__zone = page_zone(__page); \ + (unsigned long)(__page - __zone->zone_mem_map) \ + + __zone->zone_start_pfn; \ +}) #define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) /* * pfn_valid should be made as fast as possible, and the current definition * is valid for machines that are NUMA, but still contiguous, which is what * is currently supported. A more generalised, but slower definition would * be something like this - mbligh: - * ( pfn_to_pgdat(pfn) && (pfn < node_end_pfn(pfn_to_nid(pfn))) ) + * ( pfn_to_pgdat(pfn) && ((pfn) < node_end_pfn(pfn_to_nid(pfn))) ) */ -#define pfn_valid(pfn) (pfn < num_physpages) +#define pfn_valid(pfn) ((pfn) < num_physpages) #endif /* CONFIG_DISCONTIGMEM */ #endif /* _ASM_MMZONE_H_ */ diff -Nru a/include/asm-i386/node.h b/include/asm-i386/node.h --- a/include/asm-i386/node.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-i386/node.h Sun Feb 9 21:13:30 2003 @@ -13,7 +13,7 @@ extern struct i386_node node_devices[MAX_NUMNODES]; static inline int arch_register_node(int num){ - int p_node = __parent_node(num); + int p_node = parent_node(num); struct node *parent = NULL; if (p_node != num) diff -Nru a/include/asm-i386/pgalloc.h b/include/asm-i386/pgalloc.h --- a/include/asm-i386/pgalloc.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-i386/pgalloc.h Sun Feb 9 21:13:28 2003 @@ -20,11 +20,11 @@ * Allocate and free page tables. */ -extern pgd_t *pgd_alloc(struct mm_struct *); -extern void pgd_free(pgd_t *pgd); +pgd_t *pgd_alloc(struct mm_struct *); +void pgd_free(pgd_t *pgd); -extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); -extern struct page *pte_alloc_one(struct mm_struct *, unsigned long); +pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long); +struct page *pte_alloc_one(struct mm_struct *, unsigned long); static inline void pte_free_kernel(pte_t *pte) { diff -Nru a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h --- a/include/asm-i386/pgtable-3level.h Sun Feb 9 21:13:35 2003 +++ b/include/asm-i386/pgtable-3level.h Sun Feb 9 21:13:35 2003 @@ -89,8 +89,17 @@ } #define pte_page(x) pfn_to_page(pte_pfn(x)) -#define pte_none(x) (!(x).pte_low && !(x).pte_high) -#define pte_pfn(x) (((x).pte_low >> PAGE_SHIFT) | ((x).pte_high << (32 - PAGE_SHIFT))) + +static inline int pte_none(pte_t pte) +{ + return !pte.pte_low && !pte.pte_high; +} + +static inline unsigned long pte_pfn(pte_t pte) +{ + return (pte.pte_low >> PAGE_SHIFT) | + (pte.pte_high << (32 - PAGE_SHIFT)); +} static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) { @@ -105,7 +114,5 @@ { return __pmd(((unsigned long long)page_nr << PAGE_SHIFT) | pgprot_val(pgprot)); } - -extern struct kmem_cache_s *pae_pgd_cachep; #endif /* _I386_PGTABLE_3LEVEL_H */ diff -Nru a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h --- a/include/asm-i386/pgtable.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-i386/pgtable.h Sun Feb 9 21:13:34 2003 @@ -41,22 +41,13 @@ #ifndef __ASSEMBLY__ #if CONFIG_X86_PAE # include - -/* - * Need to initialise the X86 PAE caches - */ -extern void pgtable_cache_init(void); - #else # include +#endif -/* - * No page table caches to initialise - */ -#define pgtable_cache_init() do { } while (0) +void pgtable_cache_init(void); #endif -#endif #define __beep() asm("movb $0x3,%al; outb %al,$0x61") @@ -242,7 +233,7 @@ ((pmd_val(pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT)) /* to find an entry in a page-table-directory. */ -#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) #define __pgd_offset(address) pgd_index(address) diff -Nru a/include/asm-i386/signal.h b/include/asm-i386/signal.h --- a/include/asm-i386/signal.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-i386/signal.h Sun Feb 9 21:13:29 2003 @@ -86,7 +86,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/asm-i386/topology.h b/include/asm-i386/topology.h --- a/include/asm-i386/topology.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-i386/topology.h Sun Feb 9 21:13:29 2003 @@ -34,32 +34,32 @@ extern volatile int cpu_2_node[]; /* Returns the number of the node containing CPU 'cpu' */ -static inline int __cpu_to_node(int cpu) +static inline int cpu_to_node(int cpu) { return cpu_2_node[cpu]; } /* Returns the number of the node containing MemBlk 'memblk' */ -#define __memblk_to_node(memblk) (memblk) +#define memblk_to_node(memblk) (memblk) /* Returns the number of the node containing Node 'node'. This architecture is flat, so it is a pretty simple function! */ -#define __parent_node(node) (node) +#define parent_node(node) (node) /* Returns a bitmask of CPUs on Node 'node'. */ -static inline unsigned long __node_to_cpu_mask(int node) +static inline unsigned long node_to_cpumask(int node) { return node_2_cpu_mask[node]; } /* Returns the number of the first CPU on Node 'node'. */ -static inline int __node_to_first_cpu(int node) +static inline int node_to_first_cpu(int node) { - return __ffs(__node_to_cpu_mask(node)); + return __ffs(node_to_cpumask(node)); } /* Returns the number of the first MemBlk on Node 'node' */ -#define __node_to_memblk(node) (node) +#define node_to_memblk(node) (node) /* Cross-node load balancing interval. */ #define NODE_BALANCE_RATE 100 diff -Nru a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h --- a/include/asm-i386/unistd.h Sun Feb 9 21:13:33 2003 +++ b/include/asm-i386/unistd.h Sun Feb 9 21:13:33 2003 @@ -255,6 +255,8 @@ #define __NR_io_getevents 247 #define __NR_io_submit 248 #define __NR_io_cancel 249 +#define __NR_fadvise64 250 + #define __NR_exit_group 252 #define __NR_lookup_dcookie 253 #define __NR_epoll_create 254 diff -Nru a/include/asm-ia64/asmmacro.h b/include/asm-ia64/asmmacro.h --- a/include/asm-ia64/asmmacro.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-ia64/asmmacro.h Sun Feb 9 21:13:29 2003 @@ -2,15 +2,22 @@ #define _ASM_IA64_ASMMACRO_H /* - * Copyright (C) 2000-2001 Hewlett-Packard Co + * Copyright (C) 2000-2001, 2003 Hewlett-Packard Co * David Mosberger-Tang */ +#include + #define ENTRY(name) \ .align 32; \ .proc name; \ name: +#define ENTRY_MIN_ALIGN(name) \ + .align 16; \ + .proc name; \ +name: + #define GLOBAL_ENTRY(name) \ .global name; \ ENTRY(name) @@ -37,19 +44,40 @@ .previous #if __GNUC__ >= 3 -# define EX(y,x...) \ - .xdata4 "__ex_table", @gprel(99f), @gprel(y); \ +# define EX(y,x...) \ + .xdata4 "__ex_table", 99f-., y-.; \ [99:] x -# define EXCLR(y,x...) \ - .xdata4 "__ex_table", @gprel(99f), @gprel(y)+4; \ +# define EXCLR(y,x...) \ + .xdata4 "__ex_table", 99f-., y-.+4; \ [99:] x #else -# define EX(y,x...) \ - .xdata4 "__ex_table", @gprel(99f), @gprel(y); \ +# define EX(y,x...) \ + .xdata4 "__ex_table", 99f-., y-.; \ 99: x -# define EXCLR(y,x...) \ - .xdata4 "__ex_table", @gprel(99f), @gprel(y)+4; \ +# define EXCLR(y,x...) \ + .xdata4 "__ex_table", 99f-., y-.+4; \ 99: x +#endif + +/* + * For now, we always put in the McKinley E9 workaround. On CPUs that don't need it, + * we'll patch out the work-around bundles with NOPs, so their impact is minimal. + */ +#define DO_MCKINLEY_E9_WORKAROUND +#ifdef DO_MCKINLEY_E9_WORKAROUND + .section "__mckinley_e9_bundles", "a" + .previous +/* workaround for Itanium 2 Errata 9: */ +# define MCKINLEY_E9_WORKAROUND \ + .xdata4 "__mckinley_e9_bundles", 1f-.; \ +1:{ .mib; \ + nop.m 0; \ + nop.i 0; \ + br.call.sptk.many b7=1f;; \ + }; \ +1: +#else +# define MCKINLEY_E9_WORKAROUND #endif #endif /* _ASM_IA64_ASMMACRO_H */ diff -Nru a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h --- a/include/asm-ia64/bitops.h Sun Feb 9 21:13:36 2003 +++ b/include/asm-ia64/bitops.h Sun Feb 9 21:13:36 2003 @@ -2,7 +2,7 @@ #define _ASM_IA64_BITOPS_H /* - * Copyright (C) 1998-2002 Hewlett-Packard Co + * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang * * 02/06/02 find_next_bit() and find_first_bit() added from Erich Focht's ia64 O(1) @@ -320,7 +320,7 @@ static inline unsigned long ia64_fls (unsigned long x) { - double d = x; + long double d = x; long exp; __asm__ ("getf.exp %0=%1" : "=r"(exp) : "f"(d)); diff -Nru a/include/asm-ia64/bugs.h b/include/asm-ia64/bugs.h --- a/include/asm-ia64/bugs.h Sun Feb 9 21:13:36 2003 +++ b/include/asm-ia64/bugs.h Sun Feb 9 21:13:36 2003 @@ -4,16 +4,14 @@ * Needs: * void check_bugs(void); * - * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang + * Copyright (C) 1998, 1999, 2003 Hewlett-Packard Co + * David Mosberger-Tang */ +#ifndef _ASM_IA64_BUGS_H +#define _ASM_IA64_BUGS_H #include -/* - * I don't know of any ia-64 bugs yet.. - */ -static void -check_bugs (void) -{ -} +extern void check_bugs (void); + +#endif /* _ASM_IA64_BUGS_H */ diff -Nru a/include/asm-ia64/compat.h b/include/asm-ia64/compat.h --- a/include/asm-ia64/compat.h Sun Feb 9 21:13:36 2003 +++ b/include/asm-ia64/compat.h Sun Feb 9 21:13:36 2003 @@ -14,11 +14,18 @@ typedef s32 compat_pid_t; typedef u16 compat_uid_t; typedef u16 compat_gid_t; +typedef u32 compat_uid32_t; +typedef u32 compat_gid32_t; typedef u16 compat_mode_t; typedef u32 compat_ino_t; typedef u16 compat_dev_t; typedef s32 compat_off_t; +typedef s64 compat_loff_t; typedef u16 compat_nlink_t; +typedef u16 compat_ipc_pid_t; +typedef s32 compat_daddr_t; +typedef u32 compat_caddr_t; +typedef __kernel_fsid_t compat_fsid_t; struct compat_timespec { compat_time_t tv_sec; @@ -54,11 +61,31 @@ }; struct compat_flock { - short l_type; - short l_whence; - compat_off_t l_start; - compat_off_t l_len; - compat_pid_t l_pid; + short l_type; + short l_whence; + compat_off_t l_start; + compat_off_t l_len; + compat_pid_t l_pid; }; + +struct compat_statfs { + int f_type; + int f_bsize; + int f_blocks; + int f_bfree; + int f_bavail; + int f_files; + int f_ffree; + compat_fsid_t f_fsid; + int f_namelen; /* SunOS ignores this field. */ + int f_spare[6]; +}; + +typedef u32 compat_old_sigset_t; /* at least 32 bits */ + +#define _COMPAT_NSIG 64 +#define _COMPAT_NSIG_BPW 32 + +typedef u32 compat_sigset_word; #endif /* _ASM_IA64_COMPAT_H */ diff -Nru a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h --- a/include/asm-ia64/elf.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-ia64/elf.h Sun Feb 9 21:13:34 2003 @@ -4,10 +4,12 @@ /* * ELF-specific definitions. * - * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co + * Copyright (C) 1998-1999, 2002-2003 Hewlett-Packard Co * David Mosberger-Tang */ +#include + #include #include @@ -88,6 +90,11 @@ relevant until we have real hardware to play with... */ #define ELF_PLATFORM 0 +/* + * This should go into linux/elf.h... + */ +#define AT_SYSINFO 32 + #ifdef __KERNEL__ struct elf64_hdr; extern void ia64_set_personality (struct elf64_hdr *elf_ex, int ibcs2_interpreter); @@ -99,7 +106,14 @@ #define ELF_CORE_COPY_TASK_REGS(tsk, elf_gregs) dump_task_regs(tsk, elf_gregs) #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) - +#ifdef CONFIG_FSYS +#define ARCH_DLINFO \ +do { \ + extern char syscall_via_epc[], __start_gate_section[]; \ + NEW_AUX_ENT(AT_SYSINFO, GATE_ADDR + (syscall_via_epc - __start_gate_section)); \ +} while (0) #endif + +#endif /* __KERNEL__ */ #endif /* _ASM_IA64_ELF_H */ diff -Nru a/include/asm-ia64/ia32.h b/include/asm-ia64/ia32.h --- a/include/asm-ia64/ia32.h Sun Feb 9 21:13:37 2003 +++ b/include/asm-ia64/ia32.h Sun Feb 9 21:13:37 2003 @@ -12,17 +12,6 @@ * 32 bit structures for IA32 support. */ -/* 32bit compatibility types */ -typedef unsigned short __kernel_ipc_pid_t32; -typedef unsigned int __kernel_uid32_t32; -typedef unsigned int __kernel_gid32_t32; -typedef unsigned short __kernel_umode_t32; -typedef short __kernel_nlink_t32; -typedef int __kernel_daddr_t32; -typedef unsigned int __kernel_caddr_t32; -typedef long __kernel_loff_t32; -typedef __kernel_fsid_t __kernel_fsid_t32; - #define IA32_PAGE_SHIFT 12 /* 4KB pages */ #define IA32_PAGE_SIZE (1UL << IA32_PAGE_SHIFT) #define IA32_PAGE_MASK (~(IA32_PAGE_SIZE - 1)) @@ -143,10 +132,6 @@ }; /* signal.h */ -#define _IA32_NSIG 64 -#define _IA32_NSIG_BPW 32 -#define _IA32_NSIG_WORDS (_IA32_NSIG / _IA32_NSIG_BPW) - #define IA32_SET_SA_HANDLER(ka,handler,restorer) \ ((ka)->sa.sa_handler = (__sighandler_t) \ (((unsigned long)(restorer) << 32) \ @@ -154,23 +139,17 @@ #define IA32_SA_HANDLER(ka) ((unsigned long) (ka)->sa.sa_handler & 0xffffffff) #define IA32_SA_RESTORER(ka) ((unsigned long) (ka)->sa.sa_handler >> 32) -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 */ }; @@ -212,19 +191,6 @@ unsigned int st_ctime_nsec; unsigned int st_ino_lo; unsigned int st_ino_hi; -}; - -struct statfs32 { - int f_type; - int f_bsize; - int f_blocks; - int f_bfree; - int f_bavail; - int f_files; - int f_ffree; - __kernel_fsid_t32 f_fsid; - int f_namelen; /* SunOS ignores this field. */ - int f_spare[6]; }; typedef union sigval32 { diff -Nru a/include/asm-ia64/intrinsics.h b/include/asm-ia64/intrinsics.h --- a/include/asm-ia64/intrinsics.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-ia64/intrinsics.h Sun Feb 9 21:13:32 2003 @@ -4,9 +4,11 @@ /* * Compiler-dependent intrinsics. * - * Copyright (C) 2002 Hewlett-Packard Co + * Copyright (C) 2002-2003 Hewlett-Packard Co * David Mosberger-Tang */ + +#include /* * Force an unresolved reference if someone tries to use diff -Nru a/include/asm-ia64/kmap_types.h b/include/asm-ia64/kmap_types.h --- a/include/asm-ia64/kmap_types.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-ia64/kmap_types.h Sun Feb 9 21:13:32 2003 @@ -21,8 +21,8 @@ D(8) KM_PTE1, D(9) KM_IRQ0, D(10) KM_IRQ1, -D(11) KM_CRYPTO_USER, -D(12) KM_CRYPTO_SOFTIRQ, +D(11) KM_SOFTIRQ0, +D(12) KM_SOFTIRQ1, D(13) KM_TYPE_NR }; diff -Nru a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h --- a/include/asm-ia64/mmu_context.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-ia64/mmu_context.h Sun Feb 9 21:13:29 2003 @@ -28,6 +28,36 @@ #include +#define MMU_CONTEXT_DEBUG 0 + +#if MMU_CONTEXT_DEBUG + +#include + +extern struct mmu_trace_entry { + char op; + u8 cpu; + u32 context; + void *mm; +} mmu_tbuf[1024]; + +extern volatile int mmu_tbuf_index; + +# define MMU_TRACE(_op,_cpu,_mm,_ctx) \ +do { \ + int i = __sync_fetch_and_add(&mmu_tbuf_index, 1) % ARRAY_SIZE(mmu_tbuf); \ + struct mmu_trace_entry e; \ + e.op = (_op); \ + e.cpu = (_cpu); \ + e.mm = (_mm); \ + e.context = (_ctx); \ + mmu_tbuf[i] = e; \ +} while (0) + +#else +# define MMU_TRACE(op,cpu,mm,ctx) do { ; } while (0) +#endif + struct ia64_ctx { spinlock_t lock; unsigned int next; /* next context number to use */ @@ -91,6 +121,7 @@ static inline int init_new_context (struct task_struct *p, struct mm_struct *mm) { + MMU_TRACE('N', smp_processor_id(), mm, 0); mm->context = 0; return 0; } @@ -99,6 +130,7 @@ destroy_context (struct mm_struct *mm) { /* Nothing to do. */ + MMU_TRACE('D', smp_processor_id(), mm, mm->context); } static inline void @@ -138,12 +170,17 @@ do { context = get_mmu_context(mm); + MMU_TRACE('A', smp_processor_id(), mm, context); reload_context(context); + MMU_TRACE('a', smp_processor_id(), mm, context); /* in the unlikely event of a TLB-flush by another thread, redo the load: */ } while (unlikely(context != mm->context)); } -#define deactivate_mm(tsk,mm) do { } while (0) +#define deactivate_mm(tsk,mm) \ +do { \ + MMU_TRACE('d', smp_processor_id(), mm, mm->context); \ +} while (0) /* * Switch from address space PREV to address space NEXT. diff -Nru a/include/asm-ia64/perfmon.h b/include/asm-ia64/perfmon.h --- a/include/asm-ia64/perfmon.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-ia64/perfmon.h Sun Feb 9 21:13:32 2003 @@ -40,6 +40,7 @@ #define PFM_FL_INHERIT_ALL 0x02 /* always clone pfm_context across fork() */ #define PFM_FL_NOTIFY_BLOCK 0x04 /* block task on user level notifications */ #define PFM_FL_SYSTEM_WIDE 0x08 /* create a system wide context */ +#define PFM_FL_EXCL_IDLE 0x20 /* exclude idle task from system wide session */ /* * PMC flags @@ -86,11 +87,12 @@ unsigned long reg_long_reset; /* reset after sampling buffer overflow (large) */ unsigned long reg_short_reset;/* reset after counter overflow (small) */ - unsigned long reg_reset_pmds[4]; /* which other counters to reset on overflow */ - unsigned long reg_random_seed; /* seed value when randomization is used */ - unsigned long reg_random_mask; /* bitmask used to limit random value */ + unsigned long reg_reset_pmds[4]; /* which other counters to reset on overflow */ + unsigned long reg_random_seed; /* seed value when randomization is used */ + unsigned long reg_random_mask; /* bitmask used to limit random value */ + unsigned long reg_last_reset_value;/* last value used to reset the PMD (PFM_READ_PMDS) */ - unsigned long reserved[14]; /* for future use */ + unsigned long reserved[13]; /* for future use */ } pfarg_reg_t; typedef struct { @@ -123,7 +125,7 @@ * Define the version numbers for both perfmon as a whole and the sampling buffer format. */ #define PFM_VERSION_MAJ 1U -#define PFM_VERSION_MIN 1U +#define PFM_VERSION_MIN 3U #define PFM_VERSION (((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff)) #define PFM_SMPL_VERSION_MAJ 1U @@ -156,13 +158,17 @@ unsigned long stamp; /* timestamp */ unsigned long ip; /* where did the overflow interrupt happened */ unsigned long regs; /* bitmask of which registers overflowed */ - unsigned long period; /* unused */ + unsigned long reserved; /* unused */ } perfmon_smpl_entry_t; -extern int perfmonctl(pid_t pid, int cmd, void *arg, int narg); +extern long perfmonctl(pid_t pid, int cmd, void *arg, int narg); #ifdef __KERNEL__ +typedef struct { + void (*handler)(int irq, void *arg, struct pt_regs *regs); +} pfm_intr_handler_desc_t; + extern void pfm_save_regs (struct task_struct *); extern void pfm_load_regs (struct task_struct *); @@ -174,9 +180,24 @@ extern int pfm_use_debug_registers(struct task_struct *); extern int pfm_release_debug_registers(struct task_struct *); extern int pfm_cleanup_smpl_buf(struct task_struct *); -extern void pfm_syst_wide_update_task(struct task_struct *, int); +extern void pfm_syst_wide_update_task(struct task_struct *, unsigned long info, int is_ctxswin); extern void pfm_ovfl_block_reset(void); -extern void perfmon_init_percpu(void); +extern void pfm_init_percpu(void); + +/* + * hooks to allow VTune/Prospect to cooperate with perfmon. + * (reserved for system wide monitoring modules only) + */ +extern int pfm_install_alternate_syswide_subsystem(pfm_intr_handler_desc_t *h); +extern int pfm_remove_alternate_syswide_subsystem(pfm_intr_handler_desc_t *h); + +/* + * describe the content of the local_cpu_date->pfm_syst_info field + */ +#define PFM_CPUINFO_SYST_WIDE 0x1 /* if set a system wide session exist */ +#define PFM_CPUINFO_DCR_PP 0x2 /* if set the system wide session has started */ +#define PFM_CPUINFO_EXCL_IDLE 0x4 /* the system wide session excludes the idle task */ + #endif /* __KERNEL__ */ diff -Nru a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h --- a/include/asm-ia64/processor.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-ia64/processor.h Sun Feb 9 21:13:30 2003 @@ -2,7 +2,7 @@ #define _ASM_IA64_PROCESSOR_H /* - * Copyright (C) 1998-2002 Hewlett-Packard Co + * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang * Stephane Eranian * Copyright (C) 1999 Asit Mallick @@ -223,7 +223,10 @@ struct siginfo; struct thread_struct { - __u64 flags; /* various thread flags (see IA64_THREAD_*) */ + __u32 flags; /* various thread flags (see IA64_THREAD_*) */ + /* writing on_ustack is performance-critical, so it's worth spending 8 bits on it... */ + __u8 on_ustack; /* executing on user-stacks? */ + __u8 pad[3]; __u64 ksp; /* kernel stack pointer */ __u64 map_base; /* base address for get_unmapped_area() */ __u64 task_size; /* limit for task size */ @@ -277,6 +280,7 @@ #define INIT_THREAD { \ .flags = 0, \ + .on_ustack = 0, \ .ksp = 0, \ .map_base = DEFAULT_MAP_BASE, \ .task_size = DEFAULT_TASK_SIZE, \ diff -Nru a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h --- a/include/asm-ia64/ptrace.h Sun Feb 9 21:13:33 2003 +++ b/include/asm-ia64/ptrace.h Sun Feb 9 21:13:33 2003 @@ -2,7 +2,7 @@ #define _ASM_IA64_PTRACE_H /* - * Copyright (C) 1998-2002 Hewlett-Packard Co + * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang * Stephane Eranian * @@ -218,6 +218,13 @@ # define ia64_task_regs(t) (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1) # define ia64_psr(regs) ((struct ia64_psr *) &(regs)->cr_ipsr) # define user_mode(regs) (((struct ia64_psr *) &(regs)->cr_ipsr)->cpl != 0) +# define user_stack(task,regs) ((long) regs - (long) task == IA64_STK_OFFSET - sizeof(*regs)) +# define fsys_mode(task,regs) \ + ({ \ + struct task_struct *_task = (task); \ + struct pt_regs *_regs = (regs); \ + !user_mode(_regs) && user_stack(_task, _regs); \ + }) struct task_struct; /* forward decl */ diff -Nru a/include/asm-ia64/signal.h b/include/asm-ia64/signal.h --- a/include/asm-ia64/signal.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-ia64/signal.h Sun Feb 9 21:13:29 2003 @@ -67,7 +67,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/asm-ia64/sn/sv.h b/include/asm-ia64/sn/sv.h --- a/include/asm-ia64/sn/sv.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-ia64/sn/sv.h Sun Feb 9 21:13:29 2003 @@ -99,7 +99,7 @@ * Set SV_WAIT_SIG in sv_wait_flags to let the sv_wait be interrupted by signals. * * timeout is how long to wait before giving up, or 0 to wait - * indefinately. It is given in jiffies, and is relative. + * indefinitely. It is given in jiffies, and is relative. * * The associated lock must be locked on entry. It is unlocked on return. * diff -Nru a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h --- a/include/asm-ia64/spinlock.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-ia64/spinlock.h Sun Feb 9 21:13:29 2003 @@ -74,6 +74,27 @@ #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } #define spin_lock_init(x) ((x)->lock = 0) +#define DEBUG_SPIN_LOCK 0 + +#if DEBUG_SPIN_LOCK + +#include + +#define _raw_spin_lock(x) \ +do { \ + unsigned long _timeout = 1000000000; \ + volatile unsigned int _old = 0, _new = 1, *_ptr = &((x)->lock); \ + do { \ + if (_timeout-- == 0) { \ + extern void dump_stack (void); \ + printk("kernel DEADLOCK at %s:%d?\n", __FILE__, __LINE__); \ + dump_stack(); \ + } \ + } while (__sync_val_compare_and_swap(_ptr, _old, _new) != _old); \ +} while (0) + +#else + /* * Streamlined test_and_set_bit(0, (x)). We use test-and-test-and-set * rather than a simple xchg to avoid writing the cache-line when @@ -94,6 +115,8 @@ "(p7) br.cond.spnt.few 1b\n" \ ";;\n" \ :: "r"(&(x)->lock) : "ar.ccv", "p7", "r2", "r29", "memory") + +#endif /* !DEBUG_SPIN_LOCK */ #define spin_is_locked(x) ((x)->lock != 0) #define _raw_spin_unlock(x) do { barrier(); ((spinlock_t *) x)->lock = 0; } while (0) diff -Nru a/include/asm-ia64/system.h b/include/asm-ia64/system.h --- a/include/asm-ia64/system.h Sun Feb 9 21:13:31 2003 +++ b/include/asm-ia64/system.h Sun Feb 9 21:13:31 2003 @@ -7,7 +7,7 @@ * on information published in the Processor Abstraction Layer * and the System Abstraction Layer manual. * - * Copyright (C) 1998-2002 Hewlett-Packard Co + * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang * Copyright (C) 1999 Asit Mallick * Copyright (C) 1999 Don Dugger @@ -17,6 +17,7 @@ #include #include #include +#include #define KERNEL_START (PAGE_OFFSET + 68*1024*1024) @@ -26,7 +27,6 @@ #ifndef __ASSEMBLY__ -#include #include #include @@ -117,62 +117,51 @@ */ /* For spinlocks etc */ +/* clearing psr.i is implicitly serialized (visible by next insn) */ +/* setting psr.i requires data serialization */ +#define __local_irq_save(x) __asm__ __volatile__ ("mov %0=psr;;" \ + "rsm psr.i;;" \ + : "=r" (x) :: "memory") +#define __local_irq_disable() __asm__ __volatile__ (";; rsm psr.i;;" ::: "memory") +#define __local_irq_restore(x) __asm__ __volatile__ ("cmp.ne p6,p7=%0,r0;;" \ + "(p6) ssm psr.i;" \ + "(p7) rsm psr.i;;" \ + "(p6) srlz.d" \ + :: "r" ((x) & IA64_PSR_I) \ + : "p6", "p7", "memory") + #ifdef CONFIG_IA64_DEBUG_IRQ extern unsigned long last_cli_ip; -# define local_irq_save(x) \ -do { \ - unsigned long ip, psr; \ - \ - __asm__ __volatile__ ("mov %0=psr;; rsm psr.i;;" : "=r" (psr) :: "memory"); \ - if (psr & (1UL << 14)) { \ - __asm__ ("mov %0=ip" : "=r"(ip)); \ - last_cli_ip = ip; \ - } \ - (x) = psr; \ -} while (0) +# define __save_ip() __asm__ ("mov %0=ip" : "=r" (last_cli_ip)) -# define local_irq_disable() \ -do { \ - unsigned long ip, psr; \ - \ - __asm__ __volatile__ ("mov %0=psr;; rsm psr.i;;" : "=r" (psr) :: "memory"); \ - if (psr & (1UL << 14)) { \ - __asm__ ("mov %0=ip" : "=r"(ip)); \ - last_cli_ip = ip; \ - } \ +# define local_irq_save(x) \ +do { \ + unsigned long psr; \ + \ + __local_irq_save(psr); \ + if (psr & IA64_PSR_I) \ + __save_ip(); \ + (x) = psr; \ } while (0) -# define local_irq_restore(x) \ -do { \ - unsigned long ip, old_psr, psr = (x); \ - \ - __asm__ __volatile__ ("mov %0=psr;" \ - "cmp.ne p6,p7=%1,r0;;" \ - "(p6) ssm psr.i;" \ - "(p7) rsm psr.i;;" \ - "(p6) srlz.d" \ - : "=r" (old_psr) : "r"((psr) & IA64_PSR_I) \ - : "p6", "p7", "memory"); \ - if ((old_psr & IA64_PSR_I) && !(psr & IA64_PSR_I)) { \ - __asm__ ("mov %0=ip" : "=r"(ip)); \ - last_cli_ip = ip; \ - } \ +# define local_irq_disable() do { unsigned long x; local_irq_save(x); } while (0) + +# define local_irq_restore(x) \ +do { \ + unsigned long old_psr, psr = (x); \ + \ + local_save_flags(old_psr); \ + __local_irq_restore(psr); \ + if ((old_psr & IA64_PSR_I) && !(psr & IA64_PSR_I)) \ + __save_ip(); \ } while (0) #else /* !CONFIG_IA64_DEBUG_IRQ */ - /* clearing of psr.i is implicitly serialized (visible by next insn) */ -# define local_irq_save(x) __asm__ __volatile__ ("mov %0=psr;; rsm psr.i;;" \ - : "=r" (x) :: "memory") -# define local_irq_disable() __asm__ __volatile__ (";; rsm psr.i;;" ::: "memory") -/* (potentially) setting psr.i requires data serialization: */ -# define local_irq_restore(x) __asm__ __volatile__ ("cmp.ne p6,p7=%0,r0;;" \ - "(p6) ssm psr.i;" \ - "(p7) rsm psr.i;;" \ - "srlz.d" \ - :: "r"((x) & IA64_PSR_I) \ - : "p6", "p7", "memory") +# define local_irq_save(x) __local_irq_save(x) +# define local_irq_disable() __local_irq_disable() +# define local_irq_restore(x) __local_irq_restore(x) #endif /* !CONFIG_IA64_DEBUG_IRQ */ #define local_irq_enable() __asm__ __volatile__ (";; ssm psr.i;; srlz.d" ::: "memory") @@ -216,8 +205,8 @@ extern void ia64_load_extra (struct task_struct *task); #ifdef CONFIG_PERFMON - DECLARE_PER_CPU(int, pfm_syst_wide); -# define PERFMON_IS_SYSWIDE() (get_cpu_var(pfm_syst_wide) != 0) + DECLARE_PER_CPU(unsigned long, pfm_syst_info); +# define PERFMON_IS_SYSWIDE() (get_cpu_var(pfm_syst_info) & 0x1) #else # define PERFMON_IS_SYSWIDE() (0) #endif diff -Nru a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h --- a/include/asm-ia64/tlb.h Sun Feb 9 21:13:31 2003 +++ b/include/asm-ia64/tlb.h Sun Feb 9 21:13:31 2003 @@ -1,7 +1,7 @@ #ifndef _ASM_IA64_TLB_H #define _ASM_IA64_TLB_H /* - * Copyright (C) 2002 Hewlett-Packard Co + * Copyright (C) 2002-2003 Hewlett-Packard Co * David Mosberger-Tang * * This file was derived from asm-generic/tlb.h. @@ -70,8 +70,7 @@ * freed pages that where gathered up to this point. */ static inline void -ia64_tlb_flush_mmu(struct mmu_gather *tlb, - unsigned long start, unsigned long end) +ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end) { unsigned int nr; @@ -197,8 +196,7 @@ * PTE, not just those pointing to (normal) physical memory. */ static inline void -__tlb_remove_tlb_entry(struct mmu_gather *tlb, - pte_t *ptep, unsigned long address) +__tlb_remove_tlb_entry (struct mmu_gather *tlb, pte_t *ptep, unsigned long address) { if (tlb->start_addr == ~0UL) tlb->start_addr = address; diff -Nru a/include/asm-ia64/tlbflush.h b/include/asm-ia64/tlbflush.h --- a/include/asm-ia64/tlbflush.h Sun Feb 9 21:13:35 2003 +++ b/include/asm-ia64/tlbflush.h Sun Feb 9 21:13:35 2003 @@ -47,19 +47,22 @@ static inline void flush_tlb_mm (struct mm_struct *mm) { + MMU_TRACE('F', smp_processor_id(), mm, mm->context); if (!mm) - return; + goto out; mm->context = 0; if (atomic_read(&mm->mm_users) == 0) - return; /* happens as a result of exit_mmap() */ + goto out; /* happens as a result of exit_mmap() */ #ifdef CONFIG_SMP smp_flush_tlb_mm(mm); #else local_finish_flush_tlb_mm(mm); #endif + out: + MMU_TRACE('f', smp_processor_id(), mm, mm->context); } extern void flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end); diff -Nru a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h --- a/include/asm-ia64/topology.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-ia64/topology.h Sun Feb 9 21:13:28 2003 @@ -21,25 +21,25 @@ /* * Returns the number of the node containing CPU 'cpu' */ -#define __cpu_to_node(cpu) (int)(cpu_to_node_map[cpu]) +#define cpu_to_node(cpu) (int)(cpu_to_node_map[cpu]) /* * Returns a bitmask of CPUs on Node 'node'. */ -#define __node_to_cpu_mask(node) (node_to_cpu_mask[node]) +#define node_to_cpumask(node) (node_to_cpumask[node]) #else -#define __cpu_to_node(cpu) (0) -#define __node_to_cpu_mask(node) (phys_cpu_present_map) +#define cpu_to_node(cpu) (0) +#define node_to_cpumask(node) (phys_cpu_present_map) #endif /* * Returns the number of the node containing MemBlk 'memblk' */ #ifdef CONFIG_ACPI_NUMA -#define __memblk_to_node(memblk) (node_memblk[memblk].nid) +#define memblk_to_node(memblk) (node_memblk[memblk].nid) #else -#define __memblk_to_node(memblk) (memblk) +#define memblk_to_node(memblk) (memblk) #endif /* @@ -47,18 +47,18 @@ * Not implemented here. Multi-level hierarchies detected with * the help of node_distance(). */ -#define __parent_node(nid) (nid) +#define parent_node(nid) (nid) /* * Returns the number of the first CPU on Node 'node'. */ -#define __node_to_first_cpu(node) (__ffs(__node_to_cpu_mask(node))) +#define node_to_first_cpu(node) (__ffs(node_to_cpumask(node))) /* * Returns the number of the first MemBlk on Node 'node' * Should be fixed when IA64 discontigmem goes in. */ -#define __node_to_memblk(node) (node) +#define node_to_memblk(node) (node) /* Cross-node load balancing interval. */ #define NODE_BALANCE_RATE 10 diff -Nru a/include/asm-ia64/uaccess.h b/include/asm-ia64/uaccess.h --- a/include/asm-ia64/uaccess.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-ia64/uaccess.h Sun Feb 9 21:13:30 2003 @@ -26,7 +26,7 @@ * associated and, if so, sets r8 to -EFAULT and clears r9 to 0 and * then resumes execution at the continuation point. * - * Copyright (C) 1998, 1999, 2001-2002 Hewlett-Packard Co + * Copyright (C) 1998, 1999, 2001-2003 Hewlett-Packard Co * David Mosberger-Tang */ @@ -128,38 +128,28 @@ /* We need to declare the __ex_table section before we can use it in .xdata. */ asm (".section \"__ex_table\", \"a\"\n\t.previous"); -#if __GNUC__ >= 3 -# define GAS_HAS_LOCAL_TAGS /* define if gas supports local tags a la [1:] */ -#endif - -#ifdef GAS_HAS_LOCAL_TAGS -# define _LL "[1:]" -#else -# define _LL "1:" -#endif - #define __get_user_64(addr) \ - asm ("\n"_LL"\tld8 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ - "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n" \ - _LL \ + asm ("\n[1:]\tld8 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ + "\t.xdata4 \"__ex_table\", 1b-., 1f-.+4\n" \ + "[1:]" \ : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err)); #define __get_user_32(addr) \ - asm ("\n"_LL"\tld4 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ - "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n" \ - _LL \ + asm ("\n[1:]\tld4 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ + "\t.xdata4 \"__ex_table\", 1b-., 1f-.+4\n" \ + "[1:]" \ : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err)); #define __get_user_16(addr) \ - asm ("\n"_LL"\tld2 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ - "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n" \ - _LL \ + asm ("\n[1:]\tld2 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ + "\t.xdata4 \"__ex_table\", 1b-., 1f-.+4\n" \ + "[1:]" \ : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err)); #define __get_user_8(addr) \ - asm ("\n"_LL"\tld1 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ - "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n" \ - _LL \ + asm ("\n[1:]\tld1 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n" \ + "\t.xdata4 \"__ex_table\", 1b-., 1f-.+4\n" \ + "[1:]" \ : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err)); extern void __put_user_unknown (void); @@ -201,30 +191,30 @@ */ #define __put_user_64(x,addr) \ asm volatile ( \ - "\n"_LL"\tst8 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ - "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n" \ - _LL \ + "\n[1:]\tst8 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ + "\t.xdata4 \"__ex_table\", 1b-., 1f-.\n" \ + "[1:]" \ : "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) #define __put_user_32(x,addr) \ asm volatile ( \ - "\n"_LL"\tst4 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ - "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n" \ - _LL \ + "\n[1:]\tst4 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ + "\t.xdata4 \"__ex_table\", 1b-., 1f-.\n" \ + "[1:]" \ : "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) #define __put_user_16(x,addr) \ asm volatile ( \ - "\n"_LL"\tst2 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ - "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n" \ - _LL \ + "\n[1:]\tst2 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ + "\t.xdata4 \"__ex_table\", 1b-., 1f-.\n" \ + "[1:]" \ : "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) #define __put_user_8(x,addr) \ asm volatile ( \ - "\n"_LL"\tst1 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ - "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n" \ - _LL \ + "\n[1:]\tst1 %1=%r2%P1\t// %0 gets overwritten by exception handler\n" \ + "\t.xdata4 \"__ex_table\", 1b-., 1f-.\n" \ + "[1:]" \ : "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err)) /* @@ -314,26 +304,22 @@ int cont; /* gp-relative continuation address; if bit 2 is set, r9 is set to 0 */ }; -struct exception_fixup { - unsigned long cont; /* continuation point (bit 2: clear r9 if set) */ -}; - -extern struct exception_fixup search_exception_table (unsigned long addr); -extern void handle_exception (struct pt_regs *regs, struct exception_fixup fixup); +extern void handle_exception (struct pt_regs *regs, const struct exception_table_entry *e); +extern const struct exception_table_entry *search_exception_tables (unsigned long addr); #ifdef GAS_HAS_LOCAL_TAGS -#define SEARCH_EXCEPTION_TABLE(regs) search_exception_table(regs->cr_iip + ia64_psr(regs)->ri); +# define SEARCH_EXCEPTION_TABLE(regs) search_exception_tables(regs->cr_iip + ia64_psr(regs)->ri) #else -#define SEARCH_EXCEPTION_TABLE(regs) search_exception_table(regs->cr_iip); +# define SEARCH_EXCEPTION_TABLE(regs) search_exception_tables(regs->cr_iip) #endif static inline int done_with_exception (struct pt_regs *regs) { - struct exception_fixup fix; - fix = SEARCH_EXCEPTION_TABLE(regs); - if (fix.cont) { - handle_exception(regs, fix); + const struct exception_table_entry *e; + e = SEARCH_EXCEPTION_TABLE(regs); + if (e) { + handle_exception(regs, e); return 1; } return 0; diff -Nru a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h --- a/include/asm-ia64/unistd.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-ia64/unistd.h Sun Feb 9 21:13:29 2003 @@ -4,7 +4,7 @@ /* * IA-64 Linux syscall numbers and inline-functions. * - * Copyright (C) 1998-2002 Hewlett-Packard Co + * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang */ @@ -223,8 +223,8 @@ #define __NR_sched_setaffinity 1231 #define __NR_sched_getaffinity 1232 #define __NR_set_tid_address 1233 -/* #define __NR_alloc_hugepages 1234 reusable */ -/* #define __NR_free_hugepages 1235 reusable */ +/* 1234 available for reuse */ +/* 1235 available for reuse */ #define __NR_exit_group 1236 #define __NR_lookup_dcookie 1237 #define __NR_io_setup 1238 diff -Nru a/include/asm-m68k/mac_psc.h b/include/asm-m68k/mac_psc.h --- a/include/asm-m68k/mac_psc.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-m68k/mac_psc.h Sun Feb 9 21:13:30 2003 @@ -158,7 +158,7 @@ * 0x3 = CD Audio * 0x4 = External Audio * - * The volume is definately not the general + * The volume is definitely not the general * output volume as it doesn't affect the * alert sound volume. */ diff -Nru a/include/asm-m68k/signal.h b/include/asm-m68k/signal.h --- a/include/asm-m68k/signal.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-m68k/signal.h Sun Feb 9 21:13:29 2003 @@ -85,7 +85,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/asm-m68knommu/signal.h b/include/asm-m68knommu/signal.h --- a/include/asm-m68knommu/signal.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-m68knommu/signal.h Sun Feb 9 21:13:32 2003 @@ -85,7 +85,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/asm-mips/isadep.h b/include/asm-mips/isadep.h --- a/include/asm-mips/isadep.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-mips/isadep.h Sun Feb 9 21:13:29 2003 @@ -1,5 +1,5 @@ /* - * Various ISA level dependant constants. + * Various ISA level dependent constants. * Most of the following constants reflect the different layout * of Coprocessor 0 registers. * diff -Nru a/include/asm-mips/ng1hw.h b/include/asm-mips/ng1hw.h --- a/include/asm-mips/ng1hw.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-mips/ng1hw.h Sun Feb 9 21:13:34 2003 @@ -1,6 +1,6 @@ /* $Id: ng1hw.h,v 1.4 1999/08/04 06:01:51 ulfc Exp $ * - * ng1hw.h: Tweaks the newport.h structures and definations to be compatible + * ng1hw.h: Tweaks the newport.h structures and definitions to be compatible * with IRIX. Quite ugly, but it works. * * Copyright (C) 1999 Ulf Carlsson (ulfc@thepuffingroup.com) diff -Nru a/include/asm-mips/signal.h b/include/asm-mips/signal.h --- a/include/asm-mips/signal.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-mips/signal.h Sun Feb 9 21:13:30 2003 @@ -80,7 +80,7 @@ #define SA_RESTART 0x10000000 #define SA_SIGINFO 0x00000008 #define SA_NODEFER 0x40000000 -#define SA_NOCLDWAIT 0x00010000 /* Not supported yet */ +#define SA_NOCLDWAIT 0x00010000 #define SA_NOCLDSTOP 0x00000001 #define SA_NOMASK SA_NODEFER diff -Nru a/include/asm-mips64/r10kcache.h b/include/asm-mips64/r10kcache.h --- a/include/asm-mips64/r10kcache.h Sun Feb 9 21:13:35 2003 +++ b/include/asm-mips64/r10kcache.h Sun Feb 9 21:13:35 2003 @@ -25,7 +25,7 @@ #define ic_lsize 64 #define dc_lsize 32 -/* These are configuration dependant. */ +/* These are configuration dependent. */ #define scache_size() ({ \ unsigned long __res; \ __res = (read_32bit_cp0_register(CP0_CONFIG) >> 16) & 3; \ diff -Nru a/include/asm-mips64/signal.h b/include/asm-mips64/signal.h --- a/include/asm-mips64/signal.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-mips64/signal.h Sun Feb 9 21:13:34 2003 @@ -80,7 +80,7 @@ #define SA_RESTART 0x10000000 #define SA_SIGINFO 0x00000008 #define SA_NODEFER 0x40000000 -#define SA_NOCLDWAIT 0x00010000 /* Not supported yet */ +#define SA_NOCLDWAIT 0x00010000 #define SA_NOCLDSTOP 0x00000001 #define SA_NOMASK SA_NODEFER diff -Nru a/include/asm-mips64/topology.h b/include/asm-mips64/topology.h --- a/include/asm-mips64/topology.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-mips64/topology.h Sun Feb 9 21:13:28 2003 @@ -3,6 +3,6 @@ #include -#define __cpu_to_node(cpu) (cputocnode(cpu)) +#define cpu_to_node(cpu) (cputocnode(cpu)) #endif /* _ASM_MIPS64_TOPOLOGY_H */ diff -Nru a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h --- a/include/asm-parisc/bitops.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-parisc/bitops.h Sun Feb 9 21:13:28 2003 @@ -257,7 +257,14 @@ * hweightN: returns the hamming weight (i.e. the number * of bits set) of a N-bit word */ - +#define hweight64(x) \ +({ \ + unsigned long __x = (x); \ + unsigned int __w; \ + __w = generic_hweight32((unsigned int) __x); \ + __w += generic_hweight32((unsigned int) (__x>>32)); \ + __w; \ +}) #define hweight32(x) generic_hweight32(x) #define hweight16(x) generic_hweight16(x) #define hweight8(x) generic_hweight8(x) diff -Nru a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h --- a/include/asm-parisc/compat.h Sun Feb 9 21:13:37 2003 +++ b/include/asm-parisc/compat.h Sun Feb 9 21:13:37 2003 @@ -72,4 +72,24 @@ compat_pid_t l_pid; }; +struct compat_statfs { + s32 f_type; + s32 f_bsize; + s32 f_blocks; + s32 f_bfree; + s32 f_bavail; + s32 f_files; + s32 f_ffree; + __kernel_fsid_t f_fsid; + s32 f_namelen; + s32 f_spare[6]; +}; + +typedef u32 compat_old_sigset_t; /* at least 32 bits */ + +#define _COMPAT_NSIG 64 +#define _COMPAT_NSIG_BPW BITS_PER_LONG + +typedef u32 compat_sigset_word; + #endif /* _ASM_PARISC_COMPAT_H */ diff -Nru a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h --- a/include/asm-parisc/dma-mapping.h Sun Feb 9 21:13:31 2003 +++ b/include/asm-parisc/dma-mapping.h Sun Feb 9 21:13:31 2003 @@ -203,7 +203,6 @@ struct parisc_device; struct ioc; void * ccio_get_iommu(const struct parisc_device *dev); -struct pci_dev * ccio_get_fake(const struct parisc_device *dev); int ccio_request_resource(const struct parisc_device *dev, struct resource *res); int ccio_allocate_resource(const struct parisc_device *dev, @@ -213,7 +212,6 @@ void *alignf_data); #else /* !CONFIG_IOMMU_CCIO */ #define ccio_get_iommu(dev) NULL -#define ccio_get_fake(dev) NULL #define ccio_request_resource(dev, res) request_resource(&iomem_resource, res) #define ccio_allocate_resource(dev, res, size, min, max, align, alignf, data) \ allocate_resource(&iomem_resource, res, size, min, max, \ diff -Nru a/include/asm-parisc/module.h b/include/asm-parisc/module.h --- a/include/asm-parisc/module.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-parisc/module.h Sun Feb 9 21:13:29 2003 @@ -7,10 +7,14 @@ #define Elf_Shdr Elf64_Shdr #define Elf_Sym Elf64_Sym #define Elf_Ehdr Elf64_Ehdr +#define Elf_Addr Elf64_Addr +#define Elf_Rela Elf64_Rela #else #define Elf_Shdr Elf32_Shdr #define Elf_Sym Elf32_Sym #define Elf_Ehdr Elf32_Ehdr +#define Elf_Addr Elf32_Addr +#define Elf_Rela Elf32_Rela #endif #define module_map(x) vmalloc(x) @@ -20,6 +24,10 @@ struct mod_arch_specific { + unsigned long got_offset; + unsigned long fdesc_offset, fdesc_count; + unsigned long stub_offset; + unsigned long stub_count; }; #endif /* _ASM_PARISC_MODULE_H */ diff -Nru a/include/asm-parisc/signal.h b/include/asm-parisc/signal.h --- a/include/asm-parisc/signal.h Sun Feb 9 21:13:36 2003 +++ b/include/asm-parisc/signal.h Sun Feb 9 21:13:36 2003 @@ -64,7 +64,7 @@ #define SA_SIGINFO 0x00000010 #define SA_NODEFER 0x00000020 #define SA_RESTART 0x00000040 -#define SA_NOCLDWAIT 0x00000080 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000080 #define _SA_SIGGFAULT 0x00000100 /* HPUX */ #define SA_NOMASK SA_NODEFER diff -Nru a/include/asm-parisc/smp.h b/include/asm-parisc/smp.h --- a/include/asm-parisc/smp.h Sun Feb 9 21:13:35 2003 +++ b/include/asm-parisc/smp.h Sun Feb 9 21:13:35 2003 @@ -12,6 +12,7 @@ #define PDC_OS_BOOT_RENDEZVOUS_HI 0x28 #ifndef ASSEMBLY +#include #include /* for NR_CPUS */ typedef unsigned long address_t; @@ -53,7 +54,7 @@ #define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) #define cpu_possible(cpu) (cpu_present_mask & (1<<(cpu))) - + extern inline unsigned int num_online_cpus(void) { return hweight32(cpu_online_map); diff -Nru a/include/asm-ppc/io.h b/include/asm-ppc/io.h --- a/include/asm-ppc/io.h Sun Feb 9 21:13:35 2003 +++ b/include/asm-ppc/io.h Sun Feb 9 21:13:35 2003 @@ -36,7 +36,7 @@ #define _IO_BASE isa_io_base #define _ISA_MEM_BASE isa_mem_base #define PCI_DRAM_OFFSET pci_dram_offset -#endif /* Platform-dependant I/O */ +#endif /* Platform-dependent I/O */ extern unsigned long isa_io_base; extern unsigned long isa_mem_base; diff -Nru a/include/asm-ppc/kmap_types.h b/include/asm-ppc/kmap_types.h --- a/include/asm-ppc/kmap_types.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-ppc/kmap_types.h Sun Feb 9 21:13:34 2003 @@ -14,8 +14,8 @@ KM_PTE1, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff -Nru a/include/asm-ppc/signal.h b/include/asm-ppc/signal.h --- a/include/asm-ppc/signal.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-ppc/signal.h Sun Feb 9 21:13:29 2003 @@ -78,7 +78,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/asm-ppc/system.h b/include/asm-ppc/system.h --- a/include/asm-ppc/system.h Sun Feb 9 21:13:31 2003 +++ b/include/asm-ppc/system.h Sun Feb 9 21:13:31 2003 @@ -22,7 +22,7 @@ * mb() prevents loads and stores being reordered across this point. * rmb() prevents loads being reordered across this point. * wmb() prevents stores being reordered across this point. - * read_barrier_depends() prevents data-dependant loads being reordered + * read_barrier_depends() prevents data-dependent loads being reordered * across this point (nop on PPC). * * We can use the eieio instruction for wmb, but since it doesn't diff -Nru a/include/asm-ppc64/compat.h b/include/asm-ppc64/compat.h --- a/include/asm-ppc64/compat.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-ppc64/compat.h Sun Feb 9 21:13:29 2003 @@ -77,4 +77,11 @@ int f_spare[6]; }; +typedef u32 compat_old_sigset_t; + +#define _COMPAT_NSIG 64 +#define _COMPAT_NSIG_BPW 32 + +typedef u32 compat_sigset_word; + #endif /* _ASM_PPC64_COMPAT_H */ diff -Nru a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h --- a/include/asm-ppc64/elf.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-ppc64/elf.h Sun Feb 9 21:13:34 2003 @@ -86,10 +86,15 @@ #ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) \ -do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ - set_thread_flag(TIF_32BIT); \ +do { \ + unsigned long new_flags = 0; \ + if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ + new_flags = _TIF_32BIT; \ + if ((current_thread_info()->flags & _TIF_32BIT) \ + != new_flags) \ + set_thread_flag(TIF_ABI_PENDING); \ else \ - clear_thread_flag(TIF_32BIT); \ + clear_thread_flag(TIF_ABI_PENDING); \ if (ibcs2) \ set_personality(PER_SVR4); \ else if (current->personality != PER_LINUX32) \ @@ -130,5 +135,77 @@ NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \ NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \ } while (0) + +/* PowerPC64 relocations defined by the ABIs */ +#define R_PPC64_NONE R_PPC_NONE +#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address. */ +#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned. */ +#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address. */ +#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address. */ +#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */ +#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ +#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned. */ +#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN +#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN +#define R_PPC64_REL24 R_PPC_REL24 /* PC relative 26 bit, word aligned. */ +#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit. */ +#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN +#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN +#define R_PPC64_GOT16 R_PPC_GOT16 +#define R_PPC64_GOT16_LO R_PPC_GOT16_LO +#define R_PPC64_GOT16_HI R_PPC_GOT16_HI +#define R_PPC64_GOT16_HA R_PPC_GOT16_HA + +#define R_PPC64_COPY R_PPC_COPY +#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT +#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT +#define R_PPC64_RELATIVE R_PPC_RELATIVE + +#define R_PPC64_UADDR32 R_PPC_UADDR32 +#define R_PPC64_UADDR16 R_PPC_UADDR16 +#define R_PPC64_REL32 R_PPC_REL32 +#define R_PPC64_PLT32 R_PPC_PLT32 +#define R_PPC64_PLTREL32 R_PPC_PLTREL32 +#define R_PPC64_PLT16_LO R_PPC_PLT16_LO +#define R_PPC64_PLT16_HI R_PPC_PLT16_HI +#define R_PPC64_PLT16_HA R_PPC_PLT16_HA + +#define R_PPC64_SECTOFF R_PPC_SECTOFF +#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO +#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI +#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA +#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2. */ +#define R_PPC64_ADDR64 38 /* doubleword64 S + A. */ +#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A). */ +#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A). */ +#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A). */ +#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A). */ +#define R_PPC64_UADDR64 43 /* doubleword64 S + A. */ +#define R_PPC64_REL64 44 /* doubleword64 S + A - P. */ +#define R_PPC64_PLT64 45 /* doubleword64 L + A. */ +#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P. */ +#define R_PPC64_TOC16 47 /* half16* S + A - .TOC. */ +#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.). */ +#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.). */ +#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.). */ +#define R_PPC64_TOC 51 /* doubleword64 .TOC. */ +#define R_PPC64_PLTGOT16 52 /* half16* M + A. */ +#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A). */ +#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A). */ +#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A). */ + +#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2. */ +#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2. */ +#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2. */ +#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2. */ +#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2. */ +#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2. */ +#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2. */ +#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2. */ +#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2. */ +#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2. */ +#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2. */ +/* Keep this the last entry. */ +#define R_PPC64_NUM 67 #endif /* __PPC64_ELF_H */ diff -Nru a/include/asm-ppc64/kmap_types.h b/include/asm-ppc64/kmap_types.h --- a/include/asm-ppc64/kmap_types.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-ppc64/kmap_types.h Sun Feb 9 21:13:32 2003 @@ -14,8 +14,8 @@ KM_PTE1, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff -Nru a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h --- a/include/asm-ppc64/ppc32.h Sun Feb 9 21:13:31 2003 +++ b/include/asm-ppc64/ppc32.h Sun Feb 9 21:13:31 2003 @@ -94,32 +94,22 @@ } _sifields; } siginfo_t32; -#define __old_sigset_t32 old_sigset_t32 #define __old_sigaction32 old_sigaction32 -typedef unsigned int __old_sigset_t32; struct __old_sigaction32 { unsigned sa_handler; - __old_sigset_t32 sa_mask; + compat_old_sigset_t sa_mask; unsigned int sa_flags; unsigned sa_restorer; /* not used by Linux/SPARC yet */ }; -#define _PPC32_NSIG 64 -#define _PPC32_NSIG_BPW 32 -#define _PPC32_NSIG_WORDS (_PPC32_NSIG / _PPC32_NSIG_BPW) - -typedef struct { - unsigned int sig[_PPC32_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 struct sigaltstack_32 { diff -Nru a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h --- a/include/asm-ppc64/processor.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-ppc64/processor.h Sun Feb 9 21:13:28 2003 @@ -725,17 +725,17 @@ #define spin_lock_prefetch(x) prefetchw(x) -#define cpu_has_largepage() (__is_processor(PV_POWER4) || \ - __is_processor(PV_POWER4p)) +#define cpu_has_largepage() (processor_type() == PV_POWER4 || \ + processor_type() == PV_POWER4p) -#define cpu_has_slb() (__is_processor(PV_POWER4) || \ - __is_processor(PV_POWER4p)) +#define cpu_has_slb() (processor_type() == PV_POWER4 || \ + processor_type() == PV_POWER4p) -#define cpu_has_tlbiel() (__is_processor(PV_POWER4) || \ - __is_processor(PV_POWER4p)) +#define cpu_has_tlbiel() (processor_type() == PV_POWER4 || \ + processor_type() == PV_POWER4p) -#define cpu_has_noexecute() (__is_processor(PV_POWER4) || \ - __is_processor(PV_POWER4p)) +#define cpu_has_noexecute() (processor_type() == PV_POWER4 || \ + processor_type() == PV_POWER4p) #endif /* ASSEMBLY */ diff -Nru a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h --- a/include/asm-ppc64/signal.h Sun Feb 9 21:13:31 2003 +++ b/include/asm-ppc64/signal.h Sun Feb 9 21:13:31 2003 @@ -73,7 +73,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h --- a/include/asm-ppc64/system.h Sun Feb 9 21:13:37 2003 +++ b/include/asm-ppc64/system.h Sun Feb 9 21:13:37 2003 @@ -25,7 +25,7 @@ * mb() prevents loads and stores being reordered across this point. * rmb() prevents loads being reordered across this point. * wmb() prevents stores being reordered across this point. - * read_barrier_depends() prevents data-dependant loads being reordered + * read_barrier_depends() prevents data-dependent loads being reordered * across this point (nop on PPC). * * We can use the eieio instruction for wmb, but since it doesn't @@ -105,11 +105,18 @@ !(flags & MSR_EE); \ }) -static __inline__ int __is_processor(unsigned long pv) +static inline int __is_processor(unsigned long pv) { - unsigned long pvr; - asm volatile("mfspr %0, 0x11F" : "=r" (pvr)); - return(PVR_VER(pvr) == pv); + unsigned long pvr; + asm("mfspr %0, 0x11F" : "=r" (pvr)); + return(PVR_VER(pvr) == pv); +} + +static inline int processor_type(void) +{ + unsigned long pvr; + asm ("mfspr %0, 0x11F" : "=r" (pvr)); + return(PVR_VER(pvr)); } /* @@ -189,7 +196,7 @@ static __inline__ unsigned long __cmpxchg_u32(volatile int *p, int old, int new) { - int prev; + unsigned int prev; __asm__ __volatile__ ( EIEIO_ON_SMP @@ -211,7 +218,7 @@ static __inline__ unsigned long __cmpxchg_u64(volatile long *p, unsigned long old, unsigned long new) { - int prev; + unsigned long prev; __asm__ __volatile__ ( EIEIO_ON_SMP diff -Nru a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h --- a/include/asm-ppc64/thread_info.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-ppc64/thread_info.h Sun Feb 9 21:13:29 2003 @@ -85,6 +85,7 @@ TIF_NEED_RESCHED */ #define TIF_32BIT 5 /* 32 bit binary */ #define TIF_RUN_LIGHT 6 /* iSeries run light */ +#define TIF_ABI_PENDING 7 /* 32/64 bit switch needed */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1< #endif /* CONFIG_NUMA */ diff -Nru a/include/asm-ppc64/uaccess.h b/include/asm-ppc64/uaccess.h --- a/include/asm-ppc64/uaccess.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-ppc64/uaccess.h Sun Feb 9 21:13:32 2003 @@ -131,7 +131,7 @@ */ #define __put_user_asm(x, addr, err, op) \ __asm__ __volatile__( \ - "1: "op" %1,0(%2)\n" \ + "1: "op" %1,0(%2) # put_user\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ "3: li %0,%3\n" \ @@ -179,7 +179,7 @@ #define __get_user_asm(x, addr, err, op) \ __asm__ __volatile__( \ - "1: "op" %1,0(%2)\n" \ + "1: "op" %1,0(%2) # get_user\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ "3: li %0,%3\n" \ diff -Nru a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h --- a/include/asm-ppc64/unistd.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-ppc64/unistd.h Sun Feb 9 21:13:28 2003 @@ -242,6 +242,7 @@ #define __NR_io_getevents 229 #define __NR_io_submit 230 #define __NR_io_cancel 231 +/* 223 + 224 currently unused */ #define __NR_exit_group 234 #define __NR_lookup_dcookie 235 #define __NR_sys_epoll_create 236 @@ -249,178 +250,6 @@ #define __NR_sys_epoll_wait 238 #define __NR_remap_file_pages 239 -#define __NR(n) #n - - -#define __syscall_return(type) \ - return (__sc_err & 0x10000000 ? errno = __sc_ret, __sc_ret = -1 : 0), \ - (type) __sc_ret - -#define __syscall_clobbers \ - "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" - -#define _syscall0(type,name) \ -type name(void) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0) \ - : __syscall_clobbers); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0) \ - : __syscall_clobbers); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1, type2 arg2) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4) \ - : __syscall_clobbers); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1, type2 arg2, type3 arg3) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_5 = (unsigned long) (arg3); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4), \ - "r" (__sc_5) \ - : __syscall_clobbers); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_5 = (unsigned long) (arg3); \ - __sc_6 = (unsigned long) (arg4); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4), \ - "r" (__sc_5), \ - "r" (__sc_6) \ - : __syscall_clobbers); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - register unsigned long __sc_7 __asm__ ("r7"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_5 = (unsigned long) (arg3); \ - __sc_6 = (unsigned long) (arg4); \ - __sc_7 = (unsigned long) (arg5); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4), \ - "r" (__sc_5), \ - "r" (__sc_6), \ - "r" (__sc_7) \ - : __syscall_clobbers); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - - #ifdef __KERNEL_SYSCALLS__ /* @@ -434,17 +263,15 @@ /* * System call prototypes. */ -#define __NR__exit __NR_exit -static inline _syscall0(pid_t,setsid) -static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) -static inline _syscall3(int,read,int,fd,char *,buf,off_t,count) -static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count) -static inline _syscall1(int,dup,int,fd) -static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) -static inline _syscall3(int,open,const char *,file,int,flag,int,mode) -static inline _syscall1(int,close,int,fd) -static inline _syscall1(int,_exit,int,exitcode) -static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) +extern pid_t setsid(void); +extern int write(int fd, const char *buf, off_t count); +extern int read(int fd, char *buf, off_t count); +extern off_t lseek(int fd, off_t offset, int count); +extern int dup(int fd); +extern int execve(const char *file, char **argv, char **envp); +extern int open(const char *file, int flag, int mode); +extern int close(int fd); +extern pid_t waitpid(pid_t pid, int *wait_stat, int options); #endif /* __KERNEL_SYSCALLS__ */ diff -Nru a/include/asm-s390/kmap_types.h b/include/asm-s390/kmap_types.h --- a/include/asm-s390/kmap_types.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-s390/kmap_types.h Sun Feb 9 21:13:28 2003 @@ -14,8 +14,8 @@ KM_PTE1, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff -Nru a/include/asm-s390/signal.h b/include/asm-s390/signal.h --- a/include/asm-s390/signal.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-s390/signal.h Sun Feb 9 21:13:34 2003 @@ -94,7 +94,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/asm-s390x/signal.h b/include/asm-s390x/signal.h --- a/include/asm-s390x/signal.h Sun Feb 9 21:13:33 2003 +++ b/include/asm-s390x/signal.h Sun Feb 9 21:13:33 2003 @@ -94,7 +94,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/asm-sh/signal.h b/include/asm-sh/signal.h --- a/include/asm-sh/signal.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-sh/signal.h Sun Feb 9 21:13:32 2003 @@ -73,7 +73,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/asm-sparc/delay.h b/include/asm-sparc/delay.h --- a/include/asm-sparc/delay.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-sparc/delay.h Sun Feb 9 21:13:30 2003 @@ -21,5 +21,6 @@ /* This is too messy with inline asm on the Sparc. */ extern void udelay(unsigned long usecs); +extern void ndelay(unsigned long usecs); #endif /* defined(__SPARC_DELAY_H) */ diff -Nru a/include/asm-sparc/ide.h b/include/asm-sparc/ide.h --- a/include/asm-sparc/ide.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-sparc/ide.h Sun Feb 9 21:13:32 2003 @@ -83,7 +83,7 @@ #define ide_ack_intr(hwif) (1) /* XXX Known to be broken. Axboe will fix the problems this - * XXX has by making seperate IN/OUT macros for IDE_DATA + * XXX has by making separate IN/OUT macros for IDE_DATA * XXX register and rest of IDE regs and also using * XXX ide_ioreg_t instead of u32 for ports. -DaveM */ diff -Nru a/include/asm-sparc/kmap_types.h b/include/asm-sparc/kmap_types.h --- a/include/asm-sparc/kmap_types.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-sparc/kmap_types.h Sun Feb 9 21:13:29 2003 @@ -13,8 +13,8 @@ KM_PTE1, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff -Nru a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h --- a/include/asm-sparc/mman.h Sun Feb 9 21:13:36 2003 +++ b/include/asm-sparc/mman.h Sun Feb 9 21:13:36 2003 @@ -21,7 +21,7 @@ #define MAP_LOCKED 0x100 /* lock the mapping */ #define _MAP_NEW 0x80000000 /* Binary compatibility is fun... */ -#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_GROWSDOWN 0x0200 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ diff -Nru a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h --- a/include/asm-sparc/signal.h Sun Feb 9 21:13:33 2003 +++ b/include/asm-sparc/signal.h Sun Feb 9 21:13:33 2003 @@ -140,7 +140,7 @@ #define SA_INTERRUPT 0x10 #define SA_NOMASK 0x20 #define SA_SHIRQ 0x40 -#define SA_NOCLDWAIT 0x100 /* not supported yet */ +#define SA_NOCLDWAIT 0x100 #define SA_SIGINFO 0x200 #define SIG_BLOCK 0x01 /* for blocking signals */ diff -Nru a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h --- a/include/asm-sparc/smp.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-sparc/smp.h Sun Feb 9 21:13:29 2003 @@ -48,7 +48,6 @@ * Private routines/data */ -extern int smp_found_cpus; extern unsigned char boot_cpu_id; extern unsigned long cpu_present_map; #define cpu_online_map cpu_present_map diff -Nru a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h --- a/include/asm-sparc64/compat.h Sun Feb 9 21:13:33 2003 +++ b/include/asm-sparc64/compat.h Sun Feb 9 21:13:33 2003 @@ -77,4 +77,11 @@ int f_spare[6]; }; +typedef u32 compat_old_sigset_t; + +#define _COMPAT_NSIG 64 +#define _COMPAT_NSIG_BPW 32 + +typedef u32 compat_sigset_word; + #endif /* _ASM_SPARC64_COMPAT_H */ diff -Nru a/include/asm-sparc64/delay.h b/include/asm-sparc64/delay.h --- a/include/asm-sparc64/delay.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-sparc64/delay.h Sun Feb 9 21:13:34 2003 @@ -45,6 +45,19 @@ __delay(usecs * HZ); } +extern __inline__ void __ndelay(unsigned long usecs, unsigned long lps) +{ + usecs *= 0x0000000000000005UL; /* 2**32 / 10000 */ + + __asm__ __volatile__( +" mulx %1, %2, %0\n" +" srlx %0, 32, %0\n" + : "=r" (usecs) + : "r" (usecs), "r" (lps)); + + __delay(usecs * HZ); +} + #ifdef CONFIG_SMP #define __udelay_val cpu_data[smp_processor_id()].udelay_val #else @@ -52,6 +65,7 @@ #endif #define udelay(usecs) __udelay((usecs),__udelay_val) +#define ndelay(usecs) __ndelay((usecs),__udelay_val) #endif /* !__ASSEMBLY__ */ diff -Nru a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h --- a/include/asm-sparc64/elf.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-sparc64/elf.h Sun Feb 9 21:13:30 2003 @@ -111,6 +111,8 @@ if ((current_thread_info()->flags & _TIF_32BIT) \ != new_flags) \ set_thread_flag(TIF_ABI_PENDING); \ + else \ + clear_thread_flag(TIF_ABI_PENDING); \ /* flush_thread will update pgd cache */ \ if (ibcs2) \ set_personality(PER_SVR4); \ diff -Nru a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h --- a/include/asm-sparc64/ide.h Sun Feb 9 21:13:31 2003 +++ b/include/asm-sparc64/ide.h Sun Feb 9 21:13:31 2003 @@ -80,7 +80,7 @@ #define ide_ack_intr(hwif) (1) /* XXX Known to be broken. Axboe will fix the problems this - * XXX has by making seperate IN/OUT macros for IDE_DATA + * XXX has by making separate IN/OUT macros for IDE_DATA * XXX register and rest of IDE regs and also using * XXX ide_ioreg_t instead of u32 for ports. -DaveM */ diff -Nru a/include/asm-sparc64/kmap_types.h b/include/asm-sparc64/kmap_types.h --- a/include/asm-sparc64/kmap_types.h Sun Feb 9 21:13:36 2003 +++ b/include/asm-sparc64/kmap_types.h Sun Feb 9 21:13:36 2003 @@ -17,8 +17,8 @@ KM_PTE1, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff -Nru a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h --- a/include/asm-sparc64/mman.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-sparc64/mman.h Sun Feb 9 21:13:32 2003 @@ -21,7 +21,7 @@ #define MAP_LOCKED 0x100 /* lock the mapping */ #define _MAP_NEW 0x80000000 /* Binary compatibility is fun... */ -#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_GROWSDOWN 0x0200 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ diff -Nru a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h --- a/include/asm-sparc64/signal.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-sparc64/signal.h Sun Feb 9 21:13:30 2003 @@ -88,27 +88,21 @@ #define _NSIG_BPW 64 #define _NSIG_WORDS (__NEW_NSIG / _NSIG_BPW) -#define _NSIG_BPW32 32 -#define _NSIG_WORDS32 (__NEW_NSIG / _NSIG_BPW32) - #define SIGRTMIN 32 #define SIGRTMAX (__NEW_NSIG - 1) #if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__) #define _NSIG __NEW_NSIG #define __new_sigset_t sigset_t -#define __new_sigset_t32 sigset_t32 #define __new_sigaction sigaction #define __new_sigaction32 sigaction32 #define __old_sigset_t old_sigset_t -#define __old_sigset_t32 old_sigset_t32 #define __old_sigaction old_sigaction #define __old_sigaction32 old_sigaction32 #else #define _NSIG __OLD_NSIG #define NSIG _NSIG #define __old_sigset_t sigset_t -#define __old_sigset_t32 sigset_t32 #define __old_sigaction sigaction #define __old_sigaction32 sigaction32 #endif @@ -116,16 +110,11 @@ #ifndef __ASSEMBLY__ typedef unsigned long __old_sigset_t; /* at least 32 bits */ -typedef unsigned int __old_sigset_t32; typedef struct { unsigned long sig[_NSIG_WORDS]; } __new_sigset_t; -typedef struct { - unsigned int sig[_NSIG_WORDS32]; -} __new_sigset_t32; - /* A SunOS sigstack */ struct sigstack { /* XXX 32-bit pointers pinhead XXX */ @@ -156,7 +145,7 @@ #define SA_INTERRUPT 0x10 #define SA_NOMASK 0x20 #define SA_SHIRQ 0x40 -#define SA_NOCLDWAIT 0x100 /* not supported yet */ +#define SA_NOCLDWAIT 0x100 #define SA_SIGINFO 0x200 @@ -213,14 +202,14 @@ __new_sigset_t sa_mask; }; +#ifdef __KERNEL__ struct __new_sigaction32 { unsigned sa_handler; unsigned int sa_flags; unsigned sa_restorer; /* not used by Linux/SPARC yet */ - __new_sigset_t32 sa_mask; + compat_sigset_t sa_mask; }; -#ifdef __KERNEL__ struct k_sigaction { struct __new_sigaction sa; void *ka_restorer; @@ -234,12 +223,14 @@ void (*sa_restorer)(void); /* not used by Linux/SPARC yet */ }; +#ifdef __KERNEL__ struct __old_sigaction32 { unsigned sa_handler; - __old_sigset_t32 sa_mask; + compat_old_sigset_t sa_mask; unsigned int sa_flags; unsigned sa_restorer; /* not used by Linux/SPARC yet */ }; +#endif typedef struct sigaltstack { void *ss_sp; diff -Nru a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h --- a/include/asm-sparc64/unistd.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-sparc64/unistd.h Sun Feb 9 21:13:29 2003 @@ -252,8 +252,8 @@ #endif /* #define __NR_oldstat 232 Linux Specific */ #define __NR_stime 233 /* Linux Specific */ -#define __NR_alloc_hugepages 234 /* Linux Specific */ -#define __NR_free_hugepages 235 /* Linux Specific */ +/* #define __NR_UNUSED 234 */ +/* #define __NR_UNUSED 235 */ #define __NR__llseek 236 /* Linux Specific */ #define __NR_mlock 237 #define __NR_munlock 238 diff -Nru a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h --- a/include/asm-um/archparam-i386.h Sun Feb 9 21:13:35 2003 +++ b/include/asm-um/archparam-i386.h Sun Feb 9 21:13:35 2003 @@ -48,7 +48,7 @@ /* fake once used fs and gs selectors? */ \ pr_reg[9] = PT_REGS_DS(regs); \ pr_reg[10] = PT_REGS_DS(regs); \ - pr_reg[11] = regs->regs.syscall; \ + pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \ pr_reg[12] = PT_REGS_IP(regs); \ pr_reg[13] = PT_REGS_CS(regs); \ pr_reg[14] = PT_REGS_EFLAGS(regs); \ diff -Nru a/include/asm-um/bug.h b/include/asm-um/bug.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-um/bug.h Sun Feb 9 21:13:37 2003 @@ -0,0 +1,18 @@ +#ifndef __UM_BUG_H +#define __UM_BUG_H + +#ifndef __ASSEMBLY__ + +#define BUG() do { \ + panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ +} while (0) + +#define PAGE_BUG(page) do { \ + BUG(); \ +} while (0) + +extern int foo; + +#endif + +#endif diff -Nru a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-um/common.lds.S Sun Feb 9 21:13:37 2003 @@ -0,0 +1,86 @@ + .fini : { *(.fini) } =0x9090 + _etext = .; + PROVIDE (etext = .); + + . = ALIGN(4096); + _sdata = .; + PROVIDE (sdata = .); + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + RODATA + + __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + + __start___gpl_ksymtab = .; /* Kernel symbol table: GPL-only symbols */ + __gpl_ksymtab : { *(__gpl_ksymtab) } + __stop___gpl_ksymtab = .; + + __start___kallsyms = .; /* All kernel symbols */ + __kallsyms : { *(__kallsyms) } + __stop___kallsyms = .; + + .unprotected : { *(.unprotected) } + . = ALIGN(4096); + PROVIDE (_unprotected_end = .); + + . = ALIGN(4096); + __uml_setup_start = .; + .uml.setup.init : { *(.uml.setup.init) } + __uml_setup_end = .; + + __uml_help_start = .; + .uml.help.init : { *(.uml.help.init) } + __uml_help_end = .; + + __uml_postsetup_start = .; + .uml.postsetup.init : { *(.uml.postsetup.init) } + __uml_postsetup_end = .; + + __setup_start = .; + .init.setup : { *(.init.setup) } + __setup_end = .; + + __start___param = .; + __param : { *(__param) } + __stop___param = .; + + . = ALIGN(32); + __per_cpu_start = . ; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = . ; + + __initcall_start = .; + .initcall.init : { + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + } + __initcall_end = .; + + __uml_initcall_start = .; + .uml.initcall.init : { *(.uml.initcall.init) } + __uml_initcall_end = .; + __init_end = .; + + __exitcall_begin = .; + .exitcall : { *(.exitcall.exit) } + __exitcall_end = .; + + __uml_exitcall_begin = .; + .uml.exitcall : { *(.uml.exitcall.exit) } + __uml_exitcall_end = .; + + . = ALIGN(4096); + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; diff -Nru a/include/asm-um/current.h b/include/asm-um/current.h --- a/include/asm-um/current.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-um/current.h Sun Feb 9 21:13:28 2003 @@ -13,7 +13,8 @@ #include "linux/config.h" #include "asm/page.h" -#define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & (PAGE_MASK << 2)) +#define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \ + (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER)) #define current ({ int dummy; \ ((struct thread_info *) CURRENT_THREAD(dummy))->task; }) diff -Nru a/include/asm-um/module.h b/include/asm-um/module.h --- a/include/asm-um/module.h Sun Feb 9 21:13:33 2003 +++ b/include/asm-um/module.h Sun Feb 9 21:13:33 2003 @@ -1,6 +1,13 @@ #ifndef __UM_MODULE_H #define __UM_MODULE_H -#include "asm/arch/module.h" +/* UML is simple */ +struct mod_arch_specific +{ +}; + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr #endif diff -Nru a/include/asm-um/page.h b/include/asm-um/page.h --- a/include/asm-um/page.h Sun Feb 9 21:13:32 2003 +++ b/include/asm-um/page.h Sun Feb 9 21:13:32 2003 @@ -4,9 +4,8 @@ struct page; #include "asm/arch/page.h" +#include "asm/bug.h" -#undef BUG -#undef PAGE_BUG #undef __pa #undef __va #undef pfn_to_page @@ -22,20 +21,6 @@ #define PAGE_OFFSET (uml_physmem) #define KERNELBASE PAGE_OFFSET - -#ifndef __ASSEMBLY__ - -extern void stop(void); - -#define BUG() do { \ - panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ -} while (0) - -#define PAGE_BUG(page) do { \ - BUG(); \ -} while (0) - -#endif /* __ASSEMBLY__ */ #define __va_space (8*1024*1024) diff -Nru a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h --- a/include/asm-um/pgtable.h Sun Feb 9 21:13:37 2003 +++ b/include/asm-um/pgtable.h Sun Feb 9 21:13:37 2003 @@ -14,6 +14,9 @@ extern pgd_t swapper_pg_dir[1024]; +extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt, + pte_t *pte_out); + /* zero page used for uninitialized stuff */ extern unsigned long *empty_zero_page; diff -Nru a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h --- a/include/asm-um/processor-generic.h Sun Feb 9 21:13:29 2003 +++ b/include/asm-um/processor-generic.h Sun Feb 9 21:13:29 2003 @@ -80,21 +80,21 @@ #define INIT_THREAD \ { \ - forking: 0, \ - kernel_stack: 0, \ - nsyscalls: 0, \ - regs: EMPTY_REGS, \ - cr2: 0, \ - err: 0, \ - fault_addr: NULL, \ - prev_sched: NULL, \ - temp_stack: 0, \ - exec_buf: NULL, \ - arch: INIT_ARCH_THREAD, \ - request: { 0 } \ + .forking = 0, \ + .kernel_stack = 0, \ + .nsyscalls = 0, \ + .regs = EMPTY_REGS, \ + .cr2 = 0, \ + .err = 0, \ + .fault_addr = NULL, \ + .prev_sched = NULL, \ + .temp_stack = 0, \ + .exec_buf = NULL, \ + .arch = INIT_ARCH_THREAD, \ + .request = { 0 } \ } -#define INIT_THREAD_SIZE (4 * PAGE_SIZE) +#define INIT_THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE) typedef struct { unsigned long seg; diff -Nru a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h --- a/include/asm-um/processor-i386.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-um/processor-i386.h Sun Feb 9 21:13:28 2003 @@ -14,8 +14,8 @@ int debugregs_seq; }; -#define INIT_ARCH_THREAD { debugregs : { [ 0 ... 7 ] = 0 }, \ - debugregs_seq : 0 } +#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \ + .debugregs_seq = 0 } #include "asm/arch/user.h" diff -Nru a/include/asm-um/ptrace-generic.h b/include/asm-um/ptrace-generic.h --- a/include/asm-um/ptrace-generic.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-um/ptrace-generic.h Sun Feb 9 21:13:34 2003 @@ -9,7 +9,7 @@ #ifndef __ASSEMBLY__ #include "linux/config.h" -#include "skas_ptrace.h" + #include "asm/current.h" #define pt_regs pt_regs_subarch @@ -23,9 +23,10 @@ #undef instruction_pointer #include "sysdep/ptrace.h" +#include "skas_ptrace.h" struct pt_regs { - struct uml_pt_regs regs; + union uml_pt_regs regs; }; #define EMPTY_REGS { regs : EMPTY_UML_PT_REGS } diff -Nru a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h --- a/include/asm-um/ptrace-i386.h Sun Feb 9 21:13:33 2003 +++ b/include/asm-um/ptrace-i386.h Sun Feb 9 21:13:33 2003 @@ -6,6 +6,7 @@ #ifndef __UM_PTRACE_I386_H #define __UM_PTRACE_I386_H +#include "sysdep/ptrace.h" #include "asm/ptrace-generic.h" #define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) @@ -29,7 +30,7 @@ #define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r) #define PT_FIX_EXEC_STACK(sp) do ; while(0) -#define user_mode(r) ((r)->regs.is_user) +#define user_mode(r) UPT_IS_USER(&(r)->regs) #endif diff -Nru a/include/asm-um/ucontext.h b/include/asm-um/ucontext.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-um/ucontext.h Sun Feb 9 21:13:37 2003 @@ -0,0 +1,6 @@ +#ifndef _ASM_UM_UCONTEXT_H +#define _ASM_UM_UCONTEXT_H + +#include "asm/arch/ucontext.h" + +#endif diff -Nru a/include/asm-v850/pci.h b/include/asm-v850/pci.h --- a/include/asm-v850/pci.h Sun Feb 9 21:13:30 2003 +++ b/include/asm-v850/pci.h Sun Feb 9 21:13:30 2003 @@ -36,7 +36,7 @@ pci_unmap_single (struct pci_dev *pdev, dma_addr_t dma_addr, size_t size, int dir); -/* Make physical memory consistant for a single streaming mode DMA +/* Make physical memory consistent for a single streaming mode DMA translation after a transfer. If you perform a pci_map_single() but wish to interrogate the diff -Nru a/include/asm-v850/signal.h b/include/asm-v850/signal.h --- a/include/asm-v850/signal.h Sun Feb 9 21:13:31 2003 +++ b/include/asm-v850/signal.h Sun Feb 9 21:13:31 2003 @@ -88,7 +88,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/asm-x86_64/compat.h b/include/asm-x86_64/compat.h --- a/include/asm-x86_64/compat.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-x86_64/compat.h Sun Feb 9 21:13:34 2003 @@ -81,4 +81,11 @@ int f_spare[6]; }; +typedef u32 compat_old_sigset_t; /* at least 32 bits */ + +#define _COMPAT_NSIG 64 +#define _COMPAT_NSIG_BPW 32 + +typedef u32 compat_sigset_word; + #endif /* _ASM_X86_64_COMPAT_H */ diff -Nru a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-x86_64/dma-mapping.h Sun Feb 9 21:13:38 2003 @@ -0,0 +1,6 @@ +#ifndef _ASM_X8664_DMA_MAPPING_H +#define _ASM_X8664_DMA_MAPPING_H + +#include + +#endif diff -Nru a/include/asm-x86_64/kmap_types.h b/include/asm-x86_64/kmap_types.h --- a/include/asm-x86_64/kmap_types.h Sun Feb 9 21:13:34 2003 +++ b/include/asm-x86_64/kmap_types.h Sun Feb 9 21:13:34 2003 @@ -11,8 +11,8 @@ KM_BIO_DST_IRQ, KM_IRQ0, KM_IRQ1, - KM_CRYPTO_USER, - KM_CRYPTO_SOFTIRQ, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff -Nru a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h --- a/include/asm-x86_64/proto.h Sun Feb 9 21:13:35 2003 +++ b/include/asm-x86_64/proto.h Sun Feb 9 21:13:35 2003 @@ -1,6 +1,8 @@ #ifndef _ASM_X8664_PROTO_H #define _ASM_X8664_PROTO_H 1 +#include + /* misc architecture specific prototypes */ struct cpuinfo_x86; diff -Nru a/include/asm-x86_64/signal.h b/include/asm-x86_64/signal.h --- a/include/asm-x86_64/signal.h Sun Feb 9 21:13:28 2003 +++ b/include/asm-x86_64/signal.h Sun Feb 9 21:13:28 2003 @@ -93,7 +93,7 @@ * Unix names RESETHAND and NODEFER respectively. */ #define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 /* not supported yet */ +#define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 diff -Nru a/include/linux/acpi.h b/include/linux/acpi.h --- a/include/linux/acpi.h Sun Feb 9 21:13:28 2003 +++ b/include/linux/acpi.h Sun Feb 9 21:13:28 2003 @@ -31,11 +31,8 @@ #include -/* - * Yes this is ugly, but moving all of ACPI's private headers to include/acpi - * isn't the right answer either. Please just ignore it for now. - */ -#include "../../drivers/acpi/include/acpi.h" +#include +#include #include @@ -351,10 +348,10 @@ char * __acpi_map_table (unsigned long phys_addr, unsigned long size); unsigned long acpi_find_rsdp (void); -int acpi_boot_init (char *cmdline); +int acpi_boot_init (void); int acpi_numa_init (void); -int acpi_table_init (char *cmdline); +int acpi_table_init (void); int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler); int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header); int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler); diff -Nru a/include/linux/agp_backend.h b/include/linux/agp_backend.h --- a/include/linux/agp_backend.h Sun Feb 9 21:13:35 2003 +++ b/include/linux/agp_backend.h Sun Feb 9 21:13:35 2003 @@ -160,7 +160,7 @@ * an u32 argument of the type of memory to be allocated. * Every agp bridge device will allow you to allocate * AGP_NORMAL_MEMORY which maps to physical ram. Any other - * type is device dependant. + * type is device dependent. * * It returns NULL whenever memory is unavailable. * diff -Nru a/include/linux/apm_bios.h b/include/linux/apm_bios.h --- a/include/linux/apm_bios.h Sun Feb 9 21:13:32 2003 +++ b/include/linux/apm_bios.h Sun Feb 9 21:13:32 2003 @@ -45,7 +45,7 @@ #define APM_BIOS_DISENGAGED 0x0010 /* - * Data for APM that is persistant across module unload/load + * Data for APM that is persistent across module unload/load */ struct apm_info { struct apm_bios_info bios; diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h --- a/include/linux/blkdev.h Sun Feb 9 21:13:29 2003 +++ b/include/linux/blkdev.h Sun Feb 9 21:13:29 2003 @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include #include @@ -188,6 +190,14 @@ unplug_fn *unplug_fn; merge_bvec_fn *merge_bvec_fn; + /* + * Auto-unplugging state + */ + struct timer_list unplug_timer; + int unplug_thresh; /* After this many requests */ + unsigned long unplug_delay; /* After this many jiffies */ + struct work_struct unplug_work; + struct backing_dev_info backing_dev_info; /* @@ -287,12 +297,12 @@ * BLK_BOUNCE_ANY : don't bounce anything * BLK_BOUNCE_ISA : bounce pages above ISA DMA boundary */ -#define BLK_BOUNCE_HIGH (blk_max_low_pfn << PAGE_SHIFT) -#define BLK_BOUNCE_ANY (blk_max_pfn << PAGE_SHIFT) +#define BLK_BOUNCE_HIGH ((u64)blk_max_low_pfn << PAGE_SHIFT) +#define BLK_BOUNCE_ANY ((u64)blk_max_pfn << PAGE_SHIFT) #define BLK_BOUNCE_ISA (ISA_DMA_THRESHOLD) extern int init_emergency_isa_pool(void); -inline void blk_queue_bounce(request_queue_t *q, struct bio **bio); +extern void blk_queue_bounce(request_queue_t *q, struct bio **bio); #define rq_for_each_bio(bio, rq) \ if ((rq->bio)) \ diff -Nru a/include/linux/buffer_head.h b/include/linux/buffer_head.h --- a/include/linux/buffer_head.h Sun Feb 9 21:13:28 2003 +++ b/include/linux/buffer_head.h Sun Feb 9 21:13:28 2003 @@ -10,6 +10,7 @@ #include #include #include +#include #include enum bh_state_bits { @@ -154,7 +155,7 @@ void __invalidate_buffers(kdev_t dev, int); int sync_blockdev(struct block_device *bdev); void __wait_on_buffer(struct buffer_head *); -void sleep_on_buffer(struct buffer_head *bh); +wait_queue_head_t *bh_waitq_head(struct buffer_head *bh); void wake_up_buffer(struct buffer_head *bh); int fsync_bdev(struct block_device *); int fsync_super(struct super_block *); diff -Nru a/include/linux/crypto.h b/include/linux/crypto.h --- a/include/linux/crypto.h Sun Feb 9 21:13:30 2003 +++ b/include/linux/crypto.h Sun Feb 9 21:13:30 2003 @@ -131,9 +131,13 @@ int (*cit_setkey)(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen); int (*cit_encrypt)(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg); + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes); int (*cit_decrypt)(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg); + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes); void (*cit_xor_block)(u8 *dst, const u8 *src); }; @@ -274,19 +278,21 @@ } static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, - unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - return tfm->crt_cipher.cit_encrypt(tfm, sg, nsg); + return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes); } static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm, - struct scatterlist *sg, - unsigned int nsg) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); - return tfm->crt_cipher.cit_decrypt(tfm, sg, nsg); + return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes); } static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm, diff -Nru a/include/linux/elf.h b/include/linux/elf.h --- a/include/linux/elf.h Sun Feb 9 21:13:29 2003 +++ b/include/linux/elf.h Sun Feb 9 21:13:29 2003 @@ -519,6 +519,174 @@ #define EF_ALPHA_32BIT 1 /* All addresses are below 2GB */ +/* HPPA specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ +#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ +#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ +#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ +#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch + prediction. */ +#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ +#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ + +/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ + +#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ +#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ +#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ + +/* Additional section indeces. */ + +#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared + symbols in ANSI C. */ +#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ +#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ +#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ +#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ +#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ + +#define STT_HP_OPAQUE (STT_LOOS + 0x1) +#define STT_HP_STUB (STT_LOOS + 0x2) + +/* HPPA relocs. */ + +#define R_PARISC_NONE 0 /* No reloc. */ +#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ +#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ +#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ +#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ +#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ +#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ +#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ +#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ +#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ +#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ +#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ +#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ +#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ +#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ +#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ +#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ +#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ +#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ +#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ +#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ +#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ +#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ +#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ +#define R_PARISC_FPTR64 64 /* 64 bits function address. */ +#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ +#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ +#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ +#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ +#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ +#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ +#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ +#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ +#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ +#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ +#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ +#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ +#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ +#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ +#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ +#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ +#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ +#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ +#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ +#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LORESERVE 128 +#define R_PARISC_COPY 128 /* Copy relocation. */ +#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ +#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ +#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ +#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ +#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ +#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ +#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ +#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ +#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_HIRESERVE 255 + +/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ + +#define PT_HP_TLS (PT_LOOS + 0x0) +#define PT_HP_CORE_NONE (PT_LOOS + 0x1) +#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) +#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) +#define PT_HP_CORE_COMM (PT_LOOS + 0x4) +#define PT_HP_CORE_PROC (PT_LOOS + 0x5) +#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) +#define PT_HP_CORE_STACK (PT_LOOS + 0x7) +#define PT_HP_CORE_SHM (PT_LOOS + 0x8) +#define PT_HP_CORE_MMF (PT_LOOS + 0x9) +#define PT_HP_PARALLEL (PT_LOOS + 0x10) +#define PT_HP_FASTBIND (PT_LOOS + 0x11) +#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) +#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) +#define PT_HP_STACK (PT_LOOS + 0x14) + +#define PT_PARISC_ARCHEXT 0x70000000 +#define PT_PARISC_UNWIND 0x70000001 + +/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ + +#define PF_PARISC_SBP 0x08000000 + +#define PF_HP_PAGE_SIZE 0x00100000 +#define PF_HP_FAR_SHARED 0x00200000 +#define PF_HP_NEAR_SHARED 0x00400000 +#define PF_HP_CODE 0x01000000 +#define PF_HP_MODIFY 0x02000000 +#define PF_HP_LAZYSWAP 0x04000000 +#define PF_HP_SBP 0x08000000 + typedef struct elf32_rel { Elf32_Addr r_offset; diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h --- a/include/linux/ext3_jbd.h Sun Feb 9 21:13:29 2003 +++ b/include/linux/ext3_jbd.h Sun Feb 9 21:13:29 2003 @@ -28,7 +28,7 @@ * indirection blocks, the group and superblock summaries, and the data * block to complete the transaction. */ -#define EXT3_SINGLEDATA_TRANS_BLOCKS 8 +#define EXT3_SINGLEDATA_TRANS_BLOCKS 8U /* Extended attributes may touch two data buffers, two bitmap buffers, * and two group and summaries. */ @@ -58,7 +58,7 @@ * start off at the maximum transaction size and grow the transaction * optimistically as we go. */ -#define EXT3_MAX_TRANS_DATA 64 +#define EXT3_MAX_TRANS_DATA 64U /* We break up a large truncate or write transaction once the handle's * buffer credits gets this low, we need either to extend the @@ -67,7 +67,7 @@ * one block, plus two quota updates. Quota allocations are not * needed. */ -#define EXT3_RESERVE_TRANS_BLOCKS 12 +#define EXT3_RESERVE_TRANS_BLOCKS 12U #define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 diff -Nru a/include/linux/fadvise.h b/include/linux/fadvise.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/fadvise.h Sun Feb 9 21:13:38 2003 @@ -0,0 +1,11 @@ +#ifndef FADVISE_H_INCLUDED +#define FADVISE_H_INCLUDED + +#define POSIX_FADV_NORMAL 0 /* No further special treatment. */ +#define POSIX_FADV_RANDOM 1 /* Expect random page references. */ +#define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */ +#define POSIX_FADV_WILLNEED 3 /* Will need these pages. */ +#define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ +#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ + +#endif /* FADVISE_H_INCLUDED */ diff -Nru a/include/linux/fs.h b/include/linux/fs.h --- a/include/linux/fs.h Sun Feb 9 21:13:30 2003 +++ b/include/linux/fs.h Sun Feb 9 21:13:30 2003 @@ -332,8 +332,6 @@ struct list_head hash; atomic_t count; dev_t dev; - atomic_t openers; - struct semaphore sem; }; struct block_device { @@ -371,9 +369,10 @@ struct timespec i_ctime; unsigned int i_blkbits; unsigned long i_blksize; - unsigned long i_blocks; unsigned long i_version; + unsigned long i_blocks; unsigned short i_bytes; + spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ struct semaphore i_sem; struct inode_operations *i_op; struct file_operations *i_fop; /* former ->i_op->default_file_ops */ @@ -400,7 +399,7 @@ void *i_security; __u32 i_generation; union { - void *generic_ip; + void *generic_ip; } u; }; @@ -412,39 +411,6 @@ void *security; }; -static inline void inode_add_bytes(struct inode *inode, loff_t bytes) -{ - inode->i_blocks += bytes >> 9; - bytes &= 511; - inode->i_bytes += bytes; - if (inode->i_bytes >= 512) { - inode->i_blocks++; - inode->i_bytes -= 512; - } -} - -static inline void inode_sub_bytes(struct inode *inode, loff_t bytes) -{ - inode->i_blocks -= bytes >> 9; - bytes &= 511; - if (inode->i_bytes < bytes) { - inode->i_blocks--; - inode->i_bytes += 512; - } - inode->i_bytes -= bytes; -} - -static inline loff_t inode_get_bytes(struct inode *inode) -{ - return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; -} - -static inline void inode_set_bytes(struct inode *inode, loff_t bytes) -{ - inode->i_blocks = bytes >> 9; - inode->i_bytes = bytes & 511; -} - /* * Track a single file's readahead state */ @@ -1134,7 +1100,9 @@ extern int __check_disk_change(dev_t); extern int invalidate_inodes(struct super_block *); extern int invalidate_device(kdev_t, int); -extern void invalidate_inode_pages(struct address_space *mapping); +unsigned long invalidate_mapping_pages(struct address_space *mapping, + pgoff_t start, pgoff_t end); +unsigned long invalidate_inode_pages(struct address_space *mapping); extern void invalidate_inode_pages2(struct address_space *mapping); extern void write_inode_now(struct inode *, int); extern int filemap_fdatawrite(struct address_space *); @@ -1277,6 +1245,10 @@ extern struct inode_operations page_symlink_inode_operations; extern void generic_fillattr(struct inode *, struct kstat *); extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); +void inode_add_bytes(struct inode *inode, loff_t bytes); +void inode_sub_bytes(struct inode *inode, loff_t bytes); +loff_t inode_get_bytes(struct inode *inode); +void inode_set_bytes(struct inode *inode, loff_t bytes); extern int vfs_readdir(struct file *, filldir_t, void *); diff -Nru a/include/linux/gfp.h b/include/linux/gfp.h --- a/include/linux/gfp.h Sun Feb 9 21:13:30 2003 +++ b/include/linux/gfp.h Sun Feb 9 21:13:30 2003 @@ -14,20 +14,17 @@ /* Action modifiers - doesn't change the zoning */ #define __GFP_WAIT 0x10 /* Can wait and reschedule? */ #define __GFP_HIGH 0x20 /* Should access emergency pools? */ -#define __GFP_IO 0x40 /* Can start low memory physical IO? */ -#define __GFP_HIGHIO 0x80 /* Can start high mem physical IO? */ -#define __GFP_FS 0x100 /* Can call down to low-level FS? */ -#define __GFP_COLD 0x200 /* Cache-cold page required */ -#define __GFP_NOWARN 0x400 /* Suppress page allocation failure warning */ +#define __GFP_IO 0x40 /* Can start physical IO? */ +#define __GFP_FS 0x80 /* Can call down to low-level FS? */ +#define __GFP_COLD 0x100 /* Cache-cold page required */ +#define __GFP_NOWARN 0x200 /* Suppress page allocation failure warning */ -#define GFP_NOHIGHIO ( __GFP_WAIT | __GFP_IO) -#define GFP_NOIO ( __GFP_WAIT) -#define GFP_NOFS ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO) #define GFP_ATOMIC (__GFP_HIGH) -#define GFP_USER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS) -#define GFP_HIGHUSER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS | __GFP_HIGHMEM) -#define GFP_KERNEL ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS) -#define GFP_KSWAPD ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS) +#define GFP_NOIO (__GFP_WAIT) +#define GFP_NOFS (__GFP_WAIT | __GFP_IO) +#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS) +#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS) +#define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HIGHMEM) /* Flag - indicates that the buffer will be suitable for DMA. Ignored on some platforms, used as appropriate on others */ diff -Nru a/include/linux/hugetlb.h b/include/linux/hugetlb.h --- a/include/linux/hugetlb.h Sun Feb 9 21:13:32 2003 +++ b/include/linux/hugetlb.h Sun Feb 9 21:13:32 2003 @@ -18,19 +18,34 @@ void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long); int hugetlb_prefault(struct address_space *, struct vm_area_struct *); void huge_page_release(struct page *); -void hugetlb_release_key(struct hugetlb_key *); int hugetlb_report_meminfo(char *); int is_hugepage_mem_enough(size_t); +struct page *follow_huge_addr(struct mm_struct *mm, struct vm_area_struct *vma, + unsigned long address, int write); +struct vm_area_struct *hugepage_vma(struct mm_struct *mm, + unsigned long address); +struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, + pmd_t *pmd, int write); +int pmd_huge(pmd_t pmd); extern int htlbpage_max; +static inline void +mark_mm_hugetlb(struct mm_struct *mm, struct vm_area_struct *vma) +{ + if (is_vm_hugetlb_page(vma)) + mm->used_hugetlb = 1; +} + #else /* !CONFIG_HUGETLB_PAGE */ + static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) { return 0; } -#define follow_hugetlb_page(m,v,p,vs,a,b,i) ({ BUG(); 0; }) +#define follow_hugetlb_page(m,v,p,vs,a,b,i) ({ BUG(); 0; }) +#define follow_huge_addr(mm, vma, addr, write) 0 #define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; }) #define hugetlb_prefault(mapping, vma) ({ BUG(); 0; }) #define zap_hugepage_range(vma, start, len) BUG() @@ -38,6 +53,14 @@ #define huge_page_release(page) BUG() #define is_hugepage_mem_enough(size) 0 #define hugetlb_report_meminfo(buf) 0 +#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 pmd_huge(x) 0 + +#ifndef HPAGE_MASK +#define HPAGE_MASK 0 /* Keep the compiler happy */ +#endif #endif /* !CONFIG_HUGETLB_PAGE */ diff -Nru a/include/linux/init_task.h b/include/linux/init_task.h --- a/include/linux/init_task.h Sun Feb 9 21:13:29 2003 +++ b/include/linux/init_task.h Sun Feb 9 21:13:29 2003 @@ -45,9 +45,13 @@ #define INIT_SIGNALS(sig) { \ .count = ATOMIC_INIT(1), \ + .shared_pending = { NULL, &sig.shared_pending.head, {{0}}}, \ +} + +#define INIT_SIGHAND(sighand) { \ + .count = ATOMIC_INIT(1), \ .action = { {{0,}}, }, \ .siglock = SPIN_LOCK_UNLOCKED, \ - .shared_pending = { NULL, &sig.shared_pending.head, {{0}}}, \ } /* @@ -90,7 +94,8 @@ .thread = INIT_THREAD, \ .fs = &init_fs, \ .files = &init_files, \ - .sig = &init_signals, \ + .signal = &init_signals, \ + .sighand = &init_sighand, \ .pending = { NULL, &tsk.pending.head, {{0}}}, \ .blocked = {{0}}, \ .alloc_lock = SPIN_LOCK_UNLOCKED, \ diff -Nru a/include/linux/isdnif.h b/include/linux/isdnif.h --- a/include/linux/isdnif.h Sun Feb 9 21:13:28 2003 +++ b/include/linux/isdnif.h Sun Feb 9 21:13:28 2003 @@ -62,7 +62,7 @@ /* */ /* The proceed command holds a incoming call in a state to leave processes */ /* enough time to check whether ist should be accepted. */ -/* The PROT_IO Command extends the interface to make protocol dependant */ +/* The PROT_IO Command extends the interface to make protocol dependent */ /* features available (call diversion, call waiting...). */ /* */ /* The PROT_IO Command is executed with the desired driver id and the arg */ diff -Nru a/include/linux/jbd.h b/include/linux/jbd.h --- a/include/linux/jbd.h Sun Feb 9 21:13:35 2003 +++ b/include/linux/jbd.h Sun Feb 9 21:13:35 2003 @@ -63,7 +63,38 @@ #define JFS_MIN_JOURNAL_BLOCKS 1024 #ifdef __KERNEL__ + +/** + * typedef handle_t - The handle_t type represents a single atomic update being performed by some process. + * + * All filesystem modifications made by the process go + * through this handle. Recursive operations (such as quota operations) + * are gathered into a single update. + * + * The buffer credits field is used to account for journaled buffers + * being modified by the running process. To ensure that there is + * enough log space for all outstanding operations, we need to limit the + * number of outstanding buffers possible at any time. When the + * operation completes, any buffer credits not used are credited back to + * the transaction, so that at all times we know how many buffers the + * outstanding updates on a transaction might possibly touch. + * + * This is an opaque datatype. + **/ typedef struct handle_s handle_t; /* Atomic operation type */ + + +/** + * typedef journal_t - The journal_t maintains all of the journaling state information for a single filesystem. + * + * journal_t is linked to from the fs superblock structure. + * + * We use the journal_t to keep track of all outstanding transaction + * activity on the filesystem, and to manage the state of the log + * writing process. + * + * This is an opaque datatype. + **/ typedef struct journal_s journal_t; /* Journal control structure */ #endif @@ -252,6 +283,20 @@ } #define HAVE_JOURNAL_CALLBACK_STATUS +/** + * struct journal_callback - Base structure for callback information. + * @jcb_list: list information for other callbacks attached to the same handle. + * @jcb_func: Function to call with this callback structure. + * + * This struct is a 'seed' structure for a using with your own callback + * structs. If you are using callbacks you must allocate one of these + * or another struct of your own definition which has this struct + * as it's first element and pass it to journal_callback_set(). + * + * This is used internally by jbd to maintain callback information. + * + * See journal_callback_set for more information. + **/ struct journal_callback { struct list_head jcb_list; void (*jcb_func)(struct journal_callback *jcb, int error); @@ -260,18 +305,21 @@ struct jbd_revoke_table_s; -/* The handle_t type represents a single atomic update being performed - * by some process. All filesystem modifications made by the process go - * through this handle. Recursive operations (such as quota operations) - * are gathered into a single update. - * - * The buffer credits field is used to account for journaled buffers - * being modified by the running process. To ensure that there is - * enough log space for all outstanding operations, we need to limit the - * number of outstanding buffers possible at any time. When the - * operation completes, any buffer credits not used are credited back to - * the transaction, so that at all times we know how many buffers the - * outstanding updates on a transaction might possibly touch. */ +/** + * struct handle_s - The handle_s type is the concrete type associated with handle_t. + * @h_transaction: Which compound transaction is this update a part of? + * @h_buffer_credits: Number of remaining buffers we are allowed to dirty. + * @h_ref: Reference count on this handle + * @h_jcb: List of application registered callbacks for this handle. + * @h_err: Field for caller's use to track errors through large fs operations + * @h_sync: flag for sync-on-close + * @h_jdata: flag to force data journaling + * @h_aborted: flag indicating fatal error on handle + **/ + +/* Docbook can't yet cope with the bit fields, but will leave the documentation + * in so it can be fixed later. + */ struct handle_s { @@ -284,8 +332,8 @@ /* Reference count on this handle */ int h_ref; - /* Field for caller's use to track errors through large fs - operations */ + /* Field for caller's use to track errors through large fs */ + /* operations */ int h_err; /* List of application registered callbacks for this handle. @@ -412,21 +460,58 @@ struct list_head t_jcb; }; - -/* The journal_t maintains all of the journaling state information for a - * single filesystem. It is linked to from the fs superblock structure. - * - * We use the journal_t to keep track of all outstanding transaction - * activity on the filesystem, and to manage the state of the log - * writing process. */ +/** + * struct journal_s - The journal_s type is the concrete type associated with journal_t. + * @j_flags: General journaling state flags + * @j_errno: Is there an outstanding uncleared error on the journal (from a prior abort)? + * @j_sb_buffer: First part of superblock buffer + * @j_superblock: Second part of superblock buffer + * @j_format_version: Version of the superblock format + * @j_barrier_count: Number of processes waiting to create a barrier lock + * @j_barrier: The barrier lock itself + * @j_running_transaction: The current running transaction.. + * @j_committing_transaction: the transaction we are pushing to disk + * @j_checkpoint_transactions: a linked circular list of all transactions waiting for checkpointing + * @j_wait_transaction_locked: Wait queue for waiting for a locked transaction to start committing, or for a barrier lock to be released + * @j_wait_logspace: Wait queue for waiting for checkpointing to complete + * @j_wait_done_commit: Wait queue for waiting for commit to complete + * @j_wait_checkpoint: Wait queue to trigger checkpointing + * @j_wait_commit: Wait queue to trigger commit + * @j_wait_updates: Wait queue to wait for updates to complete + * @j_checkpoint_sem: Semaphore for locking against concurrent checkpoints + * @j_sem: The main journal lock, used by lock_journal() + * @j_head: Journal head - identifies the first unused block in the journal + * @j_tail: Journal tail - identifies the oldest still-used block in the journal. + * @j_free: Journal free - how many free blocks are there in the journal? + * @j_first: The block number of the first usable block + * @j_last: The block number one beyond the last usable block + * @j_dev: Device where we store the journal + * @j_blocksize: blocksize for the location where we store the journal. + * @j_blk_offset: starting block offset for into the device where we store the journal + * @j_fs_dev: Device which holds the client fs. For internal journal this will be equal to j_dev + * @j_maxlen: Total maximum capacity of the journal region on disk. + * @j_inode: Optional inode where we store the journal. If present, all journal block numbers are mapped into this inode via bmap(). + * @j_tail_sequence: Sequence number of the oldest transaction in the log + * @j_transaction_sequence: Sequence number of the next transaction to grant + * @j_commit_sequence: Sequence number of the most recently committed transaction + * @j_commit_request: Sequence number of the most recent transaction wanting commit + * @j_uuid: Uuid of client object. + * @j_task: Pointer to the current commit thread for this journal + * @j_max_transaction_buffers: Maximum number of metadata buffers to allow in a single compound commit transaction + * @j_commit_interval: What is the maximum transaction lifetime before we begin a commit? + * @j_commit_timer: The timer used to wakeup the commit thread + * @j_commit_timer_active: Timer flag + * @j_all_journals: Link all journals together - system-wide + * @j_revoke: The revoke table - maintains the list of revoked blocks in the current transaction. + **/ struct journal_s { /* General journaling state flags */ unsigned long j_flags; - /* Is there an outstanding uncleared error on the journal (from - * a prior abort)? */ + /* Is there an outstanding uncleared error on the journal (from */ + /* a prior abort)? */ int j_errno; /* The superblock buffer */ @@ -448,13 +533,13 @@ /* ... the transaction we are pushing to disk ... */ transaction_t * j_committing_transaction; - /* ... and a linked circular list of all transactions waiting - * for checkpointing. */ + /* ... and a linked circular list of all transactions waiting */ + /* for checkpointing. */ /* Protected by journal_datalist_lock */ transaction_t * j_checkpoint_transactions; - /* Wait queue for waiting for a locked transaction to start - committing, or for a barrier lock to be released */ + /* Wait queue for waiting for a locked transaction to start */ + /* committing, or for a barrier lock to be released */ wait_queue_head_t j_wait_transaction_locked; /* Wait queue for waiting for checkpointing to complete */ @@ -481,33 +566,33 @@ /* Journal head: identifies the first unused block in the journal. */ unsigned long j_head; - /* Journal tail: identifies the oldest still-used block in the - * journal. */ + /* Journal tail: identifies the oldest still-used block in the */ + /* journal. */ unsigned long j_tail; /* Journal free: how many free blocks are there in the journal? */ unsigned long j_free; - /* Journal start and end: the block numbers of the first usable - * block and one beyond the last usable block in the journal. */ + /* Journal start and end: the block numbers of the first usable */ + /* block and one beyond the last usable block in the journal. */ unsigned long j_first, j_last; - /* Device, blocksize and starting block offset for the location - * where we store the journal. */ + /* Device, blocksize and starting block offset for the location */ + /* where we store the journal. */ struct block_device * j_dev; int j_blocksize; unsigned int j_blk_offset; - /* Device which holds the client fs. For internal journal this - * will be equal to j_dev. */ + /* Device which holds the client fs. For internal journal this */ + /* will be equal to j_dev. */ struct block_device * j_fs_dev; /* Total maximum capacity of the journal region on disk. */ unsigned int j_maxlen; - /* Optional inode where we store the journal. If present, all - * journal block numbers are mapped into this inode via - * bmap(). */ + /* Optional inode where we store the journal. If present, all */ + /* journal block numbers are mapped into this inode via */ + /* bmap(). */ struct inode * j_inode; /* Sequence number of the oldest transaction in the log */ @@ -519,23 +604,23 @@ /* Sequence number of the most recent transaction wanting commit */ tid_t j_commit_request; - /* Journal uuid: identifies the object (filesystem, LVM volume - * etc) backed by this journal. This will eventually be - * replaced by an array of uuids, allowing us to index multiple - * devices within a single journal and to perform atomic updates - * across them. */ + /* Journal uuid: identifies the object (filesystem, LVM volume */ + /* etc) backed by this journal. This will eventually be */ + /* replaced by an array of uuids, allowing us to index multiple */ + /* devices within a single journal and to perform atomic updates */ + /* across them. */ __u8 j_uuid[16]; /* Pointer to the current commit thread for this journal */ struct task_struct * j_task; - /* Maximum number of metadata buffers to allow in a single - * compound commit transaction */ + /* Maximum number of metadata buffers to allow in a single */ + /* compound commit transaction */ int j_max_transaction_buffers; - /* What is the maximum transaction lifetime before we begin a - * commit? */ + /* What is the maximum transaction lifetime before we begin a */ + /* commit? */ unsigned long j_commit_interval; /* The timer used to wakeup the commit thread: */ @@ -545,8 +630,8 @@ /* Link all journals together - system-wide */ struct list_head j_all_journals; - /* The revoke table: maintains the list of revoked blocks in the - current transaction. */ + /* The revoke table: maintains the list of revoked blocks in the */ + /* current transaction. */ struct jbd_revoke_table_s *j_revoke; }; diff -Nru a/include/linux/jiffies.h b/include/linux/jiffies.h --- a/include/linux/jiffies.h Sun Feb 9 21:13:28 2003 +++ b/include/linux/jiffies.h Sun Feb 9 21:13:28 2003 @@ -2,14 +2,37 @@ #define _LINUX_JIFFIES_H #include +#include +#include +#include #include /* for HZ */ /* * The 64-bit value is not volatile - you MUST NOT read it - * without holding read_lock_irq(&xtime_lock) + * without holding read_lock_irq(&xtime_lock). + * get_jiffies_64() will do this for you as appropriate. */ extern u64 jiffies_64; extern unsigned long volatile jiffies; + +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 +} + /* * These inlines deal with timer wrapping correctly. You are diff -Nru a/include/linux/mm.h b/include/linux/mm.h --- a/include/linux/mm.h Sun Feb 9 21:13:28 2003 +++ b/include/linux/mm.h Sun Feb 9 21:13:28 2003 @@ -208,24 +208,55 @@ * Also, many kernel routines increase the page count before a critical * routine so they can be sure the page doesn't go away from under them. */ -#define get_page(p) atomic_inc(&(p)->count) -#define __put_page(p) atomic_dec(&(p)->count) #define put_page_testzero(p) \ ({ \ BUG_ON(page_count(page) == 0); \ atomic_dec_and_test(&(p)->count); \ }) + #define page_count(p) atomic_read(&(p)->count) #define set_page_count(p,v) atomic_set(&(p)->count, v) +#define __put_page(p) atomic_dec(&(p)->count) extern void FASTCALL(__page_cache_release(struct page *)); +#ifdef CONFIG_HUGETLB_PAGE + +static inline void get_page(struct page *page) +{ + if (PageCompound(page)) + page = (struct page *)page->lru.next; + atomic_inc(&page->count); +} + static inline void put_page(struct page *page) { + if (PageCompound(page)) { + page = (struct page *)page->lru.next; + if (page->lru.prev) { /* destructor? */ + (*(void (*)(struct page *))page->lru.prev)(page); + return; + } + } if (!PageReserved(page) && put_page_testzero(page)) __page_cache_release(page); } +#else /* CONFIG_HUGETLB_PAGE */ + +static inline void get_page(struct page *page) +{ + atomic_inc(&page->count); +} + +static inline void put_page(struct page *page) +{ + if (!PageReserved(page) && put_page_testzero(page)) + __page_cache_release(page); +} + +#endif /* CONFIG_HUGETLB_PAGE */ + /* * Multiple processes may "see" the same page. E.g. for untouched * mappings of /dev/null, all processes see the same page full of @@ -491,7 +522,9 @@ extern unsigned long do_brk(unsigned long, unsigned long); -static inline void __vma_unlink(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev) +static inline void +__vma_unlink(struct mm_struct *mm, struct vm_area_struct *vma, + struct vm_area_struct *prev) { prev->vm_next = vma->vm_next; rb_erase(&vma->vm_rb, &mm->mm_rb); @@ -499,7 +532,8 @@ mm->mmap_cache = prev; } -static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags) +static inline int +can_vma_merge(struct vm_area_struct *vma, unsigned long vm_flags) { if (!vma->vm_file && vma->vm_flags == vm_flags) return 1; diff -Nru a/include/linux/mmzone.h b/include/linux/mmzone.h --- a/include/linux/mmzone.h Sun Feb 9 21:13:28 2003 +++ b/include/linux/mmzone.h Sun Feb 9 21:13:28 2003 @@ -257,7 +257,7 @@ #include /* Returns the number of the current Node. */ -#define numa_node_id() (__cpu_to_node(smp_processor_id())) +#define numa_node_id() (cpu_to_node(smp_processor_id())) #ifndef CONFIG_DISCONTIGMEM extern struct pglist_data contig_page_data; diff -Nru a/include/linux/module.h b/include/linux/module.h --- a/include/linux/module.h Sun Feb 9 21:13:35 2003 +++ b/include/linux/module.h Sun Feb 9 21:13:35 2003 @@ -33,12 +33,19 @@ #endif #define MODULE_NAME_LEN (64 - sizeof(unsigned long)) + struct kernel_symbol { unsigned long value; const char *name; }; +struct modversion_info +{ + unsigned long crc; + char name[MODULE_NAME_LEN]; +}; + /* These are either module local, or the kernel's dummy ones. */ extern int init_module(void); extern void cleanup_module(void); @@ -92,7 +99,7 @@ */ #define MODULE_LICENSE(license) \ static const char __module_license[] \ - __attribute__((section(".init.license"))) = license + __attribute__((section(".init.license"), unused)) = license #else /* !MODULE */ @@ -119,6 +126,7 @@ unsigned int num_syms; const struct kernel_symbol *syms; + const unsigned long *crcs; }; /* Given an address, look for it in the exception tables */ @@ -134,29 +142,52 @@ #ifdef CONFIG_MODULES + /* Get/put a kernel symbol (calls must be symmetric) */ void *__symbol_get(const char *symbol); void *__symbol_get_gpl(const char *symbol); #define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) +#ifdef __GENKSYMS__ + +/* genksyms doesn't handle GPL-only symbols yet */ +#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL + +#else + +#ifdef CONFIG_MODVERSIONS +/* Mark the CRC weak since genksyms apparently decides not to + * generate a checksums for some symbols */ +#define __CRC_SYMBOL(sym, sec) \ + extern void *__crc_##sym __attribute__((weak)); \ + static const unsigned long __kcrctab_##sym \ + __attribute__((section("__kcrctab" sec), unused)) \ + = (unsigned long) &__crc_##sym; +#else +#define __CRC_SYMBOL(sym, sec) +#endif + /* For every exported symbol, place a struct in the __ksymtab section */ -#define EXPORT_SYMBOL(sym) \ +#define __EXPORT_SYMBOL(sym, sec) \ + __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ __attribute__((section("__ksymtab_strings"))) \ = MODULE_SYMBOL_PREFIX #sym; \ static const struct kernel_symbol __ksymtab_##sym \ - __attribute__((section("__ksymtab"))) \ + __attribute__((section("__ksymtab" sec), unused)) \ = { (unsigned long)&sym, __kstrtab_##sym } -#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym) +#define EXPORT_SYMBOL(sym) \ + __EXPORT_SYMBOL(sym, "") #define EXPORT_SYMBOL_GPL(sym) \ - static const char __kstrtab_##sym[] \ - __attribute__((section("__ksymtab_strings"))) \ - = MODULE_SYMBOL_PREFIX #sym; \ - static const struct kernel_symbol __ksymtab_##sym \ - __attribute__((section("__gpl_ksymtab"))) \ - = { (unsigned long)&sym, __kstrtab_##sym } + __EXPORT_SYMBOL(sym, "_gpl") + +#endif + +/* We don't mangle the actual symbol anymore, so no need for + * special casing EXPORT_SYMBOL_NOVERS */ +#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym) struct module_ref { @@ -344,7 +375,7 @@ } /* Get/put a kernel symbol (calls should be symmetric) */ -#define symbol_get(x) (&(x)) +#define symbol_get(x) ({ extern typeof(x) x __attribute__((weak)); &(x); }) #define symbol_put(x) do { } while(0) #define symbol_put_addr(x) do { } while(0) diff -Nru a/include/linux/page-flags.h b/include/linux/page-flags.h --- a/include/linux/page-flags.h Sun Feb 9 21:13:34 2003 +++ b/include/linux/page-flags.h Sun Feb 9 21:13:34 2003 @@ -72,7 +72,8 @@ #define PG_direct 16 /* ->pte_chain points directly at pte */ #define PG_mappedtodisk 17 /* Has blocks allocated on-disk */ -#define PG_reclaim 18 /* To be recalimed asap */ +#define PG_reclaim 18 /* To be reclaimed asap */ +#define PG_compound 19 /* Part of a compound page */ /* * Global page accounting. One instance per CPU. Only unsigned longs are @@ -97,15 +98,20 @@ unsigned long pswpin; /* swap reads */ unsigned long pswpout; /* swap writes */ unsigned long pgalloc; /* page allocations */ + unsigned long pgfree; /* page freeings */ unsigned long pgactivate; /* pages moved inactive->active */ unsigned long pgdeactivate; /* pages moved active->inactive */ unsigned long pgfault; /* faults (major+minor) */ unsigned long pgmajfault; /* faults (major only) */ + unsigned long pgscan; /* pages scanned by page reclaim */ unsigned long pgrefill; /* inspected in refill_inactive_zone */ unsigned long pgsteal; /* total pages reclaimed */ + unsigned long pginodesteal; /* pages reclaimed via inode freeing */ unsigned long kswapd_steal; /* pages reclaimed by kswapd */ + + unsigned long kswapd_inodesteal;/* reclaimed via kswapd inode freeing */ unsigned long pageoutrun; /* kswapd's calls to page reclaim */ unsigned long allocstall; /* direct reclaim calls */ unsigned long pgrotated; /* pages rotated to tail of the LRU */ @@ -245,6 +251,10 @@ #define SetPageReclaim(page) set_bit(PG_reclaim, &(page)->flags) #define ClearPageReclaim(page) clear_bit(PG_reclaim, &(page)->flags) #define TestClearPageReclaim(page) test_and_clear_bit(PG_reclaim, &(page)->flags) + +#define PageCompound(page) test_bit(PG_compound, &(page)->flags) +#define SetPageCompound(page) set_bit(PG_compound, &(page)->flags) +#define ClearPageCompound(page) clear_bit(PG_compound, &(page)->flags) /* * The PageSwapCache predicate doesn't use a PG_flag at this time, diff -Nru a/include/linux/pci.h b/include/linux/pci.h --- a/include/linux/pci.h Sun Feb 9 21:13:32 2003 +++ b/include/linux/pci.h Sun Feb 9 21:13:32 2003 @@ -671,6 +671,37 @@ extern struct pci_dev *isa_bridge; #endif +/* Some worker functions that PCI Hotplug drivers find useful */ +struct pci_dev_wrapped { + struct pci_dev *dev; + void *data; +}; + +struct pci_bus_wrapped { + struct pci_bus *bus; + void *data; +}; + +struct pci_visit { + int (* pre_visit_pci_bus) (struct pci_bus_wrapped *, + struct pci_dev_wrapped *); + int (* post_visit_pci_bus) (struct pci_bus_wrapped *, + struct pci_dev_wrapped *); + + int (* pre_visit_pci_dev) (struct pci_dev_wrapped *, + struct pci_bus_wrapped *); + int (* visit_pci_dev) (struct pci_dev_wrapped *, + struct pci_bus_wrapped *); + int (* post_visit_pci_dev) (struct pci_dev_wrapped *, + struct pci_bus_wrapped *); +}; + +extern int pci_visit_dev(struct pci_visit *fn, + struct pci_dev_wrapped *wrapped_dev, + struct pci_bus_wrapped *wrapped_parent); +extern int pci_is_dev_in_use(struct pci_dev *dev); +extern int pci_remove_device_safe(struct pci_dev *dev); + #endif /* CONFIG_PCI */ /* Include architecture-dependent settings and functions */ diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h --- a/include/linux/pci_ids.h Sun Feb 9 21:13:31 2003 +++ b/include/linux/pci_ids.h Sun Feb 9 21:13:31 2003 @@ -582,7 +582,10 @@ #define PCI_DEVICE_ID_SI_7016 0x7016 #define PCI_VENDOR_ID_HP 0x103c -#define PCI_DEVICE_ID_HP_DONNER_GFX 0x1008 +#define PCI_DEVICE_ID_HP_VISUALIZE_EG 0x1005 +#define PCI_DEVICE_ID_HP_VISUALIZE_FX6 0x1006 +#define PCI_DEVICE_ID_HP_VISUALIZE_FX4 0x1008 +#define PCI_DEVICE_ID_HP_VISUALIZE_FX2 0x100a #define PCI_DEVICE_ID_HP_TACHYON 0x1028 #define PCI_DEVICE_ID_HP_TACHLITE 0x1029 #define PCI_DEVICE_ID_HP_J2585A 0x1030 @@ -591,6 +594,7 @@ #define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049 #define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A #define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B +#define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b #define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223 #define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226 #define PCI_DEVICE_ID_HP_DIVA_POWERBAR 0x1227 @@ -1661,6 +1665,9 @@ #define PCI_DEVICE_ID_TIGON3_5702FE 0x164d #define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 #define PCI_DEVICE_ID_TIGON3_5703X 0x16a7 +#define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 +#define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6 +#define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7 #define PCI_DEVICE_ID_BCM4401 0x4401 #define PCI_VENDOR_ID_SYBA 0x1592 diff -Nru a/include/linux/ptrace.h b/include/linux/ptrace.h --- a/include/linux/ptrace.h Sun Feb 9 21:13:29 2003 +++ b/include/linux/ptrace.h Sun Feb 9 21:13:29 2003 @@ -26,6 +26,8 @@ /* 0x4200-0x4300 are reserved for architecture-independent additions. */ #define PTRACE_SETOPTIONS 0x4200 #define PTRACE_GETEVENTMSG 0x4201 +#define PTRACE_GETSIGINFO 0x4202 +#define PTRACE_SETSIGINFO 0x4203 /* options set using PTRACE_SETOPTIONS */ #define PTRACE_O_TRACESYSGOOD 0x00000001 @@ -33,12 +35,16 @@ #define PTRACE_O_TRACEVFORK 0x00000004 #define PTRACE_O_TRACECLONE 0x00000008 #define PTRACE_O_TRACEEXEC 0x00000010 +#define PTRACE_O_TRACEVFORKDONE 0x00000020 +#define PTRACE_O_TRACEEXIT 0x00000040 /* Wait extended result codes for the above trace options. */ #define PTRACE_EVENT_FORK 1 #define PTRACE_EVENT_VFORK 2 #define PTRACE_EVENT_CLONE 3 #define PTRACE_EVENT_EXEC 4 +#define PTRACE_EVENT_VFORK_DONE 5 +#define PTRACE_EVENT_EXIT 6 #include #include diff -Nru a/include/linux/quota.h b/include/linux/quota.h --- a/include/linux/quota.h Sun Feb 9 21:13:34 2003 +++ b/include/linux/quota.h Sun Feb 9 21:13:34 2003 @@ -280,7 +280,8 @@ struct quota_info { unsigned int flags; /* Flags for diskquotas on this device */ struct semaphore dqio_sem; /* lock device while I/O in progress */ - struct rw_semaphore dqoff_sem; /* serialize quota_off() and quota_on() on device and ops using quota_info struct, pointers from inode to dquots */ + struct semaphore dqonoff_sem; /* Serialize quotaon & quotaoff */ + struct rw_semaphore dqptr_sem; /* serialize ops using quota_info struct, pointers from inode to dquots */ struct file *files[MAXQUOTAS]; /* fp's to quotafiles */ struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */ diff -Nru a/include/linux/sched.h b/include/linux/sched.h --- a/include/linux/sched.h Sun Feb 9 21:13:29 2003 +++ b/include/linux/sched.h Sun Feb 9 21:13:29 2003 @@ -201,7 +201,9 @@ unsigned long swap_address; unsigned dumpable:1; - +#ifdef CONFIG_HUGETLB_PAGE + int used_hugetlb; +#endif /* Architecture-specific MM context */ mm_context_t context; @@ -218,10 +220,21 @@ extern int mmlist_nr; -struct signal_struct { +struct sighand_struct { atomic_t count; struct k_sigaction action[_NSIG]; spinlock_t siglock; +}; + +/* + * NOTE! "signal_struct" does not have it's own + * locking, because a shared signal_struct always + * implies a shared sighand_struct, so locking + * sighand_struct is always a proper superset of + * the locking of signal_struct. + */ +struct signal_struct { + atomic_t count; /* current thread group signal load-balancing target: */ task_t *curr_target; @@ -233,6 +246,9 @@ int group_exit; int group_exit_code; struct task_struct *group_exit_task; + + /* thread group stop support, overloads group_exit_code too */ + int group_stop_count; }; /* @@ -343,7 +359,7 @@ unsigned long it_real_incr, it_prof_incr, it_virt_incr; struct timer_list real_timer; unsigned long utime, stime, cutime, cstime; - unsigned long start_time; + u64 start_time; /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap; /* process credentials */ @@ -373,7 +389,8 @@ /* namespace */ struct namespace *namespace; /* signal handlers */ - struct signal_struct *sig; + struct signal_struct *signal; + struct sighand_struct *sighand; sigset_t blocked, real_blocked; struct sigpending pending; @@ -400,6 +417,7 @@ struct backing_dev_info *backing_dev_info; unsigned long ptrace_message; + siginfo_t *last_siginfo; /* For ptrace use. */ }; extern void __put_task_struct(struct task_struct *tsk); @@ -440,6 +458,8 @@ #define PT_TRACE_VFORK 0x00000020 #define PT_TRACE_CLONE 0x00000040 #define PT_TRACE_EXEC 0x00000080 +#define PT_TRACE_VFORK_DONE 0x00000100 +#define PT_TRACE_EXIT 0x00000200 #if CONFIG_SMP extern void set_cpus_allowed(task_t *p, unsigned long new_mask); @@ -483,6 +503,8 @@ extern struct mm_struct init_mm; extern struct task_struct *find_task_by_pid(int pid); +extern void set_special_pids(pid_t session, pid_t pgrp); +extern void __set_special_pids(pid_t session, pid_t pgrp); /* per-UID process charging. */ extern struct user_struct * alloc_uid(uid_t); @@ -506,7 +528,6 @@ extern void proc_caches_init(void); extern void flush_signals(struct task_struct *); extern void flush_signal_handlers(struct task_struct *); -extern void sig_exit(int, int, struct siginfo *); extern int dequeue_signal(sigset_t *mask, siginfo_t *info); extern void block_all_signals(int (*notifier)(void *priv), void *priv, sigset_t *mask); @@ -523,7 +544,7 @@ extern void force_sig(int, struct task_struct *); extern void force_sig_specific(int, struct task_struct *); extern int send_sig(int, struct task_struct *, int); -extern int __broadcast_thread_group(struct task_struct *p, int sig); +extern void zap_other_threads(struct task_struct *p); extern int kill_pg(pid_t, int, int); extern int kill_sl(pid_t, int, int); extern int kill_proc(pid_t, int, int); @@ -585,9 +606,13 @@ extern void exit_mm(struct task_struct *); extern void exit_files(struct task_struct *); +extern void exit_signal(struct task_struct *); +extern void __exit_signal(struct task_struct *); extern void exit_sighand(struct task_struct *); extern void __exit_sighand(struct task_struct *); +extern NORET_TYPE void do_group_exit(int); + extern void reparent_to_init(void); extern void daemonize(void); extern task_t *child_reaper; @@ -755,10 +780,12 @@ /* Reevaluate whether the task has signals pending delivery. This is required every time the blocked sigset_t changes. - callers must hold sig->siglock. */ + callers must hold sighand->siglock. */ extern FASTCALL(void recalc_sigpending_tsk(struct task_struct *t)); extern void recalc_sigpending(void); + +extern void signal_wake_up(struct task_struct *t, int resume_stopped); /* * Wrappers for p->thread_info->cpu access. No-op on UP. diff -Nru a/include/linux/sdla_x25.h b/include/linux/sdla_x25.h --- a/include/linux/sdla_x25.h Sun Feb 9 21:13:32 2003 +++ b/include/linux/sdla_x25.h Sun Feb 9 21:13:32 2003 @@ -157,7 +157,7 @@ #define X25RES_PROTO_VIOLATION 0x41 /* protocol violation occured */ #define X25RES_PKT_TIMEOUT 0x42 /* X.25 packet time out */ #define X25RES_PKT_RETRY_LIMIT 0x43 /* X.25 packet retry limit exceeded */ -/*----- Command-dependant results -----*/ +/*----- Command-dependent results -----*/ #define X25RES_LINK_DISC 0x00 /* HDLC_LINK_STATUS */ #define X25RES_LINK_IN_ABM 0x01 /* HDLC_LINK_STATUS */ #define X25RES_NO_DATA 0x01 /* HDLC_READ/READ_TRACE_DATA*/ diff -Nru a/include/linux/security.h b/include/linux/security.h --- a/include/linux/security.h Sun Feb 9 21:13:34 2003 +++ b/include/linux/security.h Sun Feb 9 21:13:34 2003 @@ -31,7 +31,8 @@ #include #include #include - +#include +#include /* * These functions are in security/capability.c and are used @@ -48,6 +49,20 @@ extern void cap_task_kmod_set_label (void); extern void cap_task_reparent_to_init (struct task_struct *p); +static inline int cap_netlink_send (struct sk_buff *skb) +{ + NETLINK_CB (skb).eff_cap = current->cap_effective; + return 0; +} + +static inline int cap_netlink_recv (struct sk_buff *skb) +{ + if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN)) + return -EPERM; + return 0; +} + + /* * Values used in the task_security_ops calls */ @@ -63,16 +78,13 @@ /* setfsuid or setfsgid, id0 == fsuid or fsgid */ #define LSM_SETID_FS 8 - -#ifdef CONFIG_SECURITY - /* forward declares to avoid warnings */ -struct sk_buff; -struct net_device; struct nfsctl_arg; struct sched_param; struct swap_info_struct; +#ifdef CONFIG_SECURITY + /** * struct security_operations - main security structure * @@ -586,6 +598,149 @@ * is being reparented to the init task. * @p contains the task_struct for the kernel thread. * + * Security hooks for Netlink messaging. + * + * @netlink_send: + * Save security information for a netlink message so that permission + * checking can be performed when the message is processed. The security + * information can be saved using the eff_cap field of the + * netlink_skb_parms structure. + * @skb contains the sk_buff structure for the netlink message. + * Return 0 if the information was successfully saved. + * @netlink_recv: + * Check permission before processing the received netlink message in + * @skb. + * @skb contains the sk_buff structure for the netlink message. + * Return 0 if permission is granted. + * + * Security hooks for Unix domain networking. + * + * @unix_stream_connect: + * Check permissions before establishing a Unix domain stream connection + * between @sock and @other. + * @sock contains the socket structure. + * @other contains the peer socket structure. + * Return 0 if permission is granted. + * @unix_may_send: + * Check permissions before connecting or sending datagrams from @sock to + * @other. + * @sock contains the socket structure. + * @sock contains the peer socket structure. + * Return 0 if permission is granted. + * + * The @unix_stream_connect and @unix_may_send hooks were necessary because + * Linux provides an alternative to the conventional file name space for Unix + * domain sockets. Whereas binding and connecting to sockets in the file name + * space is mediated by the typical file permissions (and caught by the mknod + * and permission hooks in inode_security_ops), binding and connecting to + * sockets in the abstract name space is completely unmediated. Sufficient + * control of Unix domain sockets in the abstract name space isn't possible + * using only the socket layer hooks, since we need to know the actual target + * socket, which is not looked up until we are inside the af_unix code. + * + * Security hooks for socket operations. + * + * @socket_create: + * Check permissions prior to creating a new socket. + * @family contains the requested protocol family. + * @type contains the requested communications type. + * @protocol contains the requested protocol. + * Return 0 if permission is granted. + * @socket_post_create: + * This hook allows a module to update or allocate a per-socket security + * structure. Note that the security field was not added directly to the + * socket structure, but rather, the socket security information is stored + * in the associated inode. Typically, the inode alloc_security hook will + * allocate and and attach security information to + * sock->inode->i_security. This hook may be used to update the + * sock->inode->i_security field with additional information that wasn't + * available when the inode was allocated. + * @sock contains the newly created socket structure. + * @family contains the requested protocol family. + * @type contains the requested communications type. + * @protocol contains the requested protocol. + * @socket_bind: + * Check permission before socket protocol layer bind operation is + * performed and the socket @sock is bound to the address specified in the + * @address parameter. + * @sock contains the socket structure. + * @address contains the address to bind to. + * @addrlen contains the length of address. + * Return 0 if permission is granted. + * @socket_connect: + * Check permission before socket protocol layer connect operation + * attempts to connect socket @sock to a remote address, @address. + * @sock contains the socket structure. + * @address contains the address of remote endpoint. + * @addrlen contains the length of address. + * Return 0 if permission is granted. + * @socket_listen: + * Check permission before socket protocol layer listen operation. + * @sock contains the socket structure. + * @backlog contains the maximum length for the pending connection queue. + * Return 0 if permission is granted. + * @socket_accept: + * Check permission before accepting a new connection. Note that the new + * socket, @newsock, has been created and some information copied to it, + * but the accept operation has not actually been performed. + * @sock contains the listening socket structure. + * @newsock contains the newly created server socket for connection. + * Return 0 if permission is granted. + * @socket_post_accept: + * This hook allows a security module to copy security + * information into the newly created socket's inode. + * @sock contains the listening socket structure. + * @newsock contains the newly created server socket for connection. + * @socket_sendmsg: + * Check permission before transmitting a message to another socket. + * @sock contains the socket structure. + * @msg contains the message to be transmitted. + * @size contains the size of message. + * Return 0 if permission is granted. + * @socket_recvmsg: + * Check permission before receiving a message from a socket. + * @sock contains the socket structure. + * @msg contains the message structure. + * @size contains the size of message structure. + * @flags contains the operational flags. + * Return 0 if permission is granted. + * @socket_getsockname: + * Check permission before the local address (name) of the socket object + * @sock is retrieved. + * @sock contains the socket structure. + * Return 0 if permission is granted. + * @socket_getpeername: + * Check permission before the remote address (name) of a socket object + * @sock is retrieved. + * @sock contains the socket structure. + * Return 0 if permission is granted. + * @socket_getsockopt: + * Check permissions before retrieving the options associated with socket + * @sock. + * @sock contains the socket structure. + * @level contains the protocol level to retrieve option from. + * @optname contains the name of option to retrieve. + * Return 0 if permission is granted. + * @socket_setsockopt: + * Check permissions before setting the options associated with socket + * @sock. + * @sock contains the socket structure. + * @level contains the protocol level to set options for. + * @optname contains the name of the option to set. + * Return 0 if permission is granted. + * @socket_shutdown: + * Checks permission before all or part of a connection on the socket + * @sock is shut down. + * @sock contains the socket structure. + * @how contains the flag indicating how future sends and receives are handled. + * Return 0 if permission is granted. + * @socket_sock_rcv_skb: + * Check permissions on incoming network packets. This hook is distinct + * from Netfilter's IP input hooks since it is the first time that the + * incoming sk_buff @skb has been associated with a particular socket, @sk. + * @sk contains the sock (not socket) associated with the incoming sk_buff. + * @skb contains the incoming network data. + * * Security hooks affecting all System V IPC operations. * * @ipc_permission: @@ -947,11 +1102,42 @@ int (*sem_semop) (struct sem_array * sma, struct sembuf * sops, unsigned nsops, int alter); + int (*netlink_send) (struct sk_buff * skb); + int (*netlink_recv) (struct sk_buff * skb); + /* allow module stacking */ int (*register_security) (const char *name, struct security_operations *ops); int (*unregister_security) (const char *name, struct security_operations *ops); + +#ifdef CONFIG_SECURITY_NETWORK + int (*unix_stream_connect) (struct socket * sock, + struct socket * other, struct sock * newsk); + int (*unix_may_send) (struct socket * sock, struct socket * other); + + int (*socket_create) (int family, int type, int protocol); + void (*socket_post_create) (struct socket * sock, int family, + int type, int protocol); + int (*socket_bind) (struct socket * sock, + struct sockaddr * address, int addrlen); + int (*socket_connect) (struct socket * sock, + struct sockaddr * address, int addrlen); + int (*socket_listen) (struct socket * sock, int backlog); + int (*socket_accept) (struct socket * sock, struct socket * newsock); + void (*socket_post_accept) (struct socket * sock, + struct socket * newsock); + int (*socket_sendmsg) (struct socket * sock, + struct msghdr * msg, int size); + int (*socket_recvmsg) (struct socket * sock, + struct msghdr * msg, int size, int flags); + int (*socket_getsockname) (struct socket * sock); + int (*socket_getpeername) (struct socket * sock); + int (*socket_getsockopt) (struct socket * sock, int level, int optname); + int (*socket_setsockopt) (struct socket * sock, int level, int optname); + int (*socket_shutdown) (struct socket * sock, int how); + int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb); +#endif /* CONFIG_SECURITY_NETWORK */ }; /* global variables */ @@ -1543,6 +1729,16 @@ return security_ops->sem_semop(sma, sops, nsops, alter); } +static inline int security_netlink_send(struct sk_buff * skb) +{ + return security_ops->netlink_send(skb); +} + +static inline int security_netlink_recv(struct sk_buff * skb) +{ + return security_ops->netlink_recv(skb); +} + /* prototypes */ extern int security_scaffolding_startup (void); extern int register_security (struct security_operations *ops); @@ -2104,7 +2300,228 @@ return 0; } +/* + * The netlink capability defaults need to be used inline by default + * (rather than hooking into the capability module) to reduce overhead + * in the networking code. + */ +static inline int security_netlink_send (struct sk_buff *skb) +{ + return cap_netlink_send (skb); +} + +static inline int security_netlink_recv (struct sk_buff *skb) +{ + return cap_netlink_recv (skb); +} + #endif /* CONFIG_SECURITY */ + +#ifdef CONFIG_SECURITY_NETWORK +static inline int security_unix_stream_connect(struct socket * sock, + struct socket * other, + struct sock * newsk) +{ + return security_ops->unix_stream_connect(sock, other, newsk); +} + + +static inline int security_unix_may_send(struct socket * sock, + struct socket * other) +{ + return security_ops->unix_may_send(sock, other); +} + +static inline int security_socket_create (int family, int type, int protocol) +{ + return security_ops->socket_create(family, type, protocol); +} + +static inline void security_socket_post_create(struct socket * sock, + int family, + int type, + int protocol) +{ + security_ops->socket_post_create(sock, family, type, protocol); +} + +static inline int security_socket_bind(struct socket * sock, + struct sockaddr * address, + int addrlen) +{ + return security_ops->socket_bind(sock, address, addrlen); +} + +static inline int security_socket_connect(struct socket * sock, + struct sockaddr * address, + int addrlen) +{ + return security_ops->socket_connect(sock, address, addrlen); +} + +static inline int security_socket_listen(struct socket * sock, int backlog) +{ + return security_ops->socket_listen(sock, backlog); +} + +static inline int security_socket_accept(struct socket * sock, + struct socket * newsock) +{ + return security_ops->socket_accept(sock, newsock); +} + +static inline void security_socket_post_accept(struct socket * sock, + struct socket * newsock) +{ + security_ops->socket_post_accept(sock, newsock); +} + +static inline int security_socket_sendmsg(struct socket * sock, + struct msghdr * msg, int size) +{ + return security_ops->socket_sendmsg(sock, msg, size); +} + +static inline int security_socket_recvmsg(struct socket * sock, + struct msghdr * msg, int size, + int flags) +{ + return security_ops->socket_recvmsg(sock, msg, size, flags); +} + +static inline int security_socket_getsockname(struct socket * sock) +{ + return security_ops->socket_getsockname(sock); +} + +static inline int security_socket_getpeername(struct socket * sock) +{ + return security_ops->socket_getpeername(sock); +} + +static inline int security_socket_getsockopt(struct socket * sock, + int level, int optname) +{ + return security_ops->socket_getsockopt(sock, level, optname); +} + +static inline int security_socket_setsockopt(struct socket * sock, + int level, int optname) +{ + return security_ops->socket_setsockopt(sock, level, optname); +} + +static inline int security_socket_shutdown(struct socket * sock, int how) +{ + return security_ops->socket_shutdown(sock, how); +} + +static inline int security_sock_rcv_skb (struct sock * sk, + struct sk_buff * skb) +{ + return security_ops->socket_sock_rcv_skb (sk, skb); +} +#else /* CONFIG_SECURITY_NETWORK */ +static inline int security_unix_stream_connect(struct socket * sock, + struct socket * other, + struct sock * newsk) +{ + return 0; +} + +static inline int security_unix_may_send(struct socket * sock, + struct socket * other) +{ + return 0; +} + +static inline int security_socket_create (int family, int type, int protocol) +{ + return 0; +} + +static inline void security_socket_post_create(struct socket * sock, + int family, + int type, + int protocol) +{ +} + +static inline int security_socket_bind(struct socket * sock, + struct sockaddr * address, + int addrlen) +{ + return 0; +} + +static inline int security_socket_connect(struct socket * sock, + struct sockaddr * address, + int addrlen) +{ + return 0; +} + +static inline int security_socket_listen(struct socket * sock, int backlog) +{ + return 0; +} + +static inline int security_socket_accept(struct socket * sock, + struct socket * newsock) +{ + return 0; +} + +static inline void security_socket_post_accept(struct socket * sock, + struct socket * newsock) +{ +} + +static inline int security_socket_sendmsg(struct socket * sock, + struct msghdr * msg, int size) +{ + return 0; +} + +static inline int security_socket_recvmsg(struct socket * sock, + struct msghdr * msg, int size, + int flags) +{ + return 0; +} + +static inline int security_socket_getsockname(struct socket * sock) +{ + return 0; +} + +static inline int security_socket_getpeername(struct socket * sock) +{ + return 0; +} + +static inline int security_socket_getsockopt(struct socket * sock, + int level, int optname) +{ + return 0; +} + +static inline int security_socket_setsockopt(struct socket * sock, + int level, int optname) +{ + return 0; +} + +static inline int security_socket_shutdown(struct socket * sock, int how) +{ + return 0; +} +static inline int security_sock_rcv_skb (struct sock * sk, + struct sk_buff * skb) +{ + return 0; +} +#endif /* CONFIG_SECURITY_NETWORK */ #endif /* ! __LINUX_SECURITY_H */ diff -Nru a/include/linux/seqlock.h b/include/linux/seqlock.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/seqlock.h Sun Feb 9 21:13:37 2003 @@ -0,0 +1,124 @@ +#ifndef __LINUX_SEQLOCK_H +#define __LINUX_SEQLOCK_H +/* + * Reader/writer consistent mechanism without starving writers. This type of + * lock for data where the reader wants a consitent set of information + * and is willing to retry if the information changes. Readers never + * block but they may have to retry if a writer is in + * progress. Writers do not wait for readers. + * + * This is not as cache friendly as brlock. Also, this will not work + * for data that contains pointers, because any writer could + * invalidate a pointer that a reader was following. + * + * Expected reader usage: + * do { + * seq = read_seqbegin(&foo); + * ... + * } while (read_seqretry(&foo, seq)); + * + * + * On non-SMP the spin locks disappear but the writer still needs + * to increment the sequence variables because an interrupt routine could + * change the state of the data. + * + * Based on x86_64 vsyscall gettimeofday + * by Keith Owens and Andrea Arcangeli + */ + +#include +#include +#include + +typedef struct { + unsigned sequence; + spinlock_t lock; +} seqlock_t; + +/* + * These macros triggered gcc-3.x compile-time problems. We think these are + * OK now. Be cautious. + */ +#define SEQLOCK_UNLOCKED { 0, SPIN_LOCK_UNLOCKED } +#define seqlock_init(x) do { *(x) = (seqlock_t) SEQLOCK_UNLOCKED; } while (0) + + +/* Lock out other writers and update the count. + * Acts like a normal spin_lock/unlock. + * Don't need preempt_disable() because that is in the spin_lock already. + */ +static inline void write_seqlock(seqlock_t *sl) +{ + spin_lock(&sl->lock); + ++sl->sequence; + smp_wmb(); +} + +static inline void write_sequnlock(seqlock_t *sl) +{ + smp_wmb(); + sl->sequence++; + spin_unlock(&sl->lock); +} + +static inline int write_tryseqlock(seqlock_t *sl) +{ + int ret = spin_trylock(&sl->lock); + + if (ret) { + ++sl->sequence; + smp_wmb(); + } + return ret; +} + +/* Start of read calculation -- fetch last complete writer token */ +static inline unsigned read_seqbegin(const seqlock_t *sl) +{ + unsigned ret = sl->sequence; + smp_rmb(); + return ret; +} + +/* Test if reader processed invalid data. + * If initial values is odd, + * then writer had already started when section was entered + * If sequence value changed + * then writer changed data while in section + * + * Using xor saves one conditional branch. + */ +static inline int read_seqretry(const seqlock_t *sl, unsigned iv) +{ + smp_rmb(); + return (iv & 1) | (sl->sequence ^ iv); +} + +/* + * Possible sw/hw IRQ protected versions of the interfaces. + */ +#define write_seqlock_irqsave(lock, flags) \ + do { local_irq_save(flags); write_seqlock(lock); } while (0) +#define write_seqlock_irq(lock) \ + do { local_irq_disable(); write_seqlock(lock); } while (0) +#define write_seqlock_bh(lock) \ + do { local_bh_disable(); write_seqlock(lock); } while (0) + +#define write_sequnlock_irqrestore(lock, flags) \ + do { write_sequnlock(lock); local_irq_restore(flags); } while(0) +#define write_sequnlock_irq(lock) \ + do { write_sequnlock(lock); local_irq_enable(); } while(0) +#define write_sequnlock_bh(lock) \ + do { write_sequnlock(lock); local_bh_enable(); } while(0) + +#define read_seqbegin_irqsave(lock, flags) \ + ({ local_irq_save(flags); read_seqbegin(lock); }) + +#define read_seqretry_irqrestore(lock, iv, flags) \ + ({ \ + int ret = read_seqretry(lock, iv); \ + local_irq_restore(flags); \ + ret; \ + }) + +#endif /* __LINUX_SEQLOCK_H */ diff -Nru a/include/linux/signal.h b/include/linux/signal.h --- a/include/linux/signal.h Sun Feb 9 21:13:29 2003 +++ b/include/linux/signal.h Sun Feb 9 21:13:29 2003 @@ -204,6 +204,7 @@ } extern long do_sigpending(void *, unsigned long); +extern int sigprocmask(int, sigset_t *, sigset_t *); #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER struct pt_regs; diff -Nru a/include/linux/slab.h b/include/linux/slab.h --- a/include/linux/slab.h Sun Feb 9 21:13:37 2003 +++ b/include/linux/slab.h Sun Feb 9 21:13:37 2003 @@ -17,13 +17,12 @@ /* flags for kmem_cache_alloc() */ #define SLAB_NOFS GFP_NOFS #define SLAB_NOIO GFP_NOIO -#define SLAB_NOHIGHIO GFP_NOHIGHIO #define SLAB_ATOMIC GFP_ATOMIC #define SLAB_USER GFP_USER #define SLAB_KERNEL GFP_KERNEL #define SLAB_DMA GFP_DMA -#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_FS|__GFP_COLD|__GFP_NOWARN) +#define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|__GFP_COLD|__GFP_NOWARN) #define SLAB_NO_GROW 0x00001000UL /* don't grow a cache */ /* flags to pass to kmem_cache_create(). @@ -72,7 +71,8 @@ extern kmem_cache_t *filp_cachep; extern kmem_cache_t *dquot_cachep; extern kmem_cache_t *fs_cachep; -extern kmem_cache_t *sigact_cachep; +extern kmem_cache_t *signal_cachep; +extern kmem_cache_t *sighand_cachep; extern kmem_cache_t *bio_cachep; #endif /* __KERNEL__ */ diff -Nru a/include/linux/spinlock.h b/include/linux/spinlock.h --- a/include/linux/spinlock.h Sun Feb 9 21:13:32 2003 +++ b/include/linux/spinlock.h Sun Feb 9 21:13:32 2003 @@ -37,30 +37,120 @@ #ifdef CONFIG_SMP #include -/* - * !CONFIG_SMP and spin_lock_init not previously defined - * (e.g. by including include/asm/spinlock.h) - */ -#elif !defined(spin_lock_init) +#else -#ifndef CONFIG_PREEMPT +#if !defined(CONFIG_PREEMPT) && !defined(CONFIG_DEBUG_SPINLOCK) # define atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic) # define ATOMIC_DEC_AND_LOCK #endif +#ifdef CONFIG_DEBUG_SPINLOCK + +#define SPINLOCK_MAGIC 0x1D244B3C +typedef struct { + unsigned long magic; + volatile unsigned long lock; + volatile unsigned int babble; + const char *module; + char *owner; + int oline; +} spinlock_t; +#define SPIN_LOCK_UNLOCKED (spinlock_t) { SPINLOCK_MAGIC, 0, 10, __FILE__ , NULL, 0} + +#define spin_lock_init(x) \ + do { \ + (x)->magic = SPINLOCK_MAGIC; \ + (x)->lock = 0; \ + (x)->babble = 5; \ + (x)->module = __FILE__; \ + (x)->owner = NULL; \ + (x)->oline = 0; \ + } while (0) + +#define CHECK_LOCK(x) \ + do { \ + if ((x)->magic != SPINLOCK_MAGIC) { \ + printk(KERN_ERR "%s:%d: spin_is_locked on uninitialized spinlock %p.\n", \ + __FILE__, __LINE__, (x)); \ + } \ + } while(0) + +#define _raw_spin_lock(x) \ + do { \ + CHECK_LOCK(x); \ + if ((x)->lock&&(x)->babble) { \ + printk("%s:%d: spin_lock(%s:%p) already locked by %s/%d\n", \ + __FILE__,__LINE__, (x)->module, \ + (x), (x)->owner, (x)->oline); \ + (x)->babble--; \ + } \ + (x)->lock = 1; \ + (x)->owner = __FILE__; \ + (x)->oline = __LINE__; \ + } while (0) + +/* without debugging, spin_is_locked on UP always says + * FALSE. --> printk if already locked. */ +#define spin_is_locked(x) \ + ({ \ + CHECK_LOCK(x); \ + if ((x)->lock&&(x)->babble) { \ + printk("%s:%d: spin_is_locked(%s:%p) already locked by %s/%d\n", \ + __FILE__,__LINE__, (x)->module, \ + (x), (x)->owner, (x)->oline); \ + (x)->babble--; \ + } \ + 0; \ + }) + +/* without debugging, spin_trylock on UP always says + * TRUE. --> printk if already locked. */ +#define _raw_spin_trylock(x) \ + ({ \ + CHECK_LOCK(x); \ + if ((x)->lock&&(x)->babble) { \ + printk("%s:%d: spin_trylock(%s:%p) already locked by %s/%d\n", \ + __FILE__,__LINE__, (x)->module, \ + (x), (x)->owner, (x)->oline); \ + (x)->babble--; \ + } \ + (x)->lock = 1; \ + (x)->owner = __FILE__; \ + (x)->oline = __LINE__; \ + 1; \ + }) + +#define spin_unlock_wait(x) \ + do { \ + CHECK_LOCK(x); \ + if ((x)->lock&&(x)->babble) { \ + printk("%s:%d: spin_unlock_wait(%s:%p) owned by %s/%d\n", \ + __FILE__,__LINE__, (x)->module, (x), \ + (x)->owner, (x)->oline); \ + (x)->babble--; \ + }\ + } while (0) + +#define _raw_spin_unlock(x) \ + do { \ + CHECK_LOCK(x); \ + if (!(x)->lock&&(x)->babble) { \ + printk("%s:%d: spin_unlock(%s:%p) not locked\n", \ + __FILE__,__LINE__, (x)->module, (x));\ + (x)->babble--; \ + } \ + (x)->lock = 0; \ + } while (0) +#else /* * gcc versions before ~2.95 have a nasty bug with empty initializers. */ #if (__GNUC__ > 2) typedef struct { } spinlock_t; - typedef struct { } rwlock_t; #define SPIN_LOCK_UNLOCKED (spinlock_t) { } - #define RW_LOCK_UNLOCKED (rwlock_t) { } #else typedef struct { int gcc_is_buggy; } spinlock_t; - typedef struct { int gcc_is_buggy; } rwlock_t; #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } - #define RW_LOCK_UNLOCKED (rwlock_t) { 0 } #endif /* @@ -72,6 +162,18 @@ #define _raw_spin_trylock(lock) ((void)(lock), 1) #define spin_unlock_wait(lock) do { (void)(lock); } while(0) #define _raw_spin_unlock(lock) do { (void)(lock); } while(0) +#endif /* CONFIG_DEBUG_SPINLOCK */ + +/* RW spinlocks: No debug version */ + +#if (__GNUC__ > 2) + typedef struct { } rwlock_t; + #define RW_LOCK_UNLOCKED (rwlock_t) { } +#else + typedef struct { int gcc_is_buggy; } rwlock_t; + #define RW_LOCK_UNLOCKED (rwlock_t) { 0 } +#endif + #define rwlock_init(lock) do { (void)(lock); } while(0) #define _raw_read_lock(lock) do { (void)(lock); } while(0) #define _raw_read_unlock(lock) do { (void)(lock); } while(0) diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h --- a/include/linux/sysctl.h Sun Feb 9 21:13:32 2003 +++ b/include/linux/sysctl.h Sun Feb 9 21:13:32 2003 @@ -305,7 +305,8 @@ NET_IPV4_ICMP_RATELIMIT=89, NET_IPV4_ICMP_RATEMASK=90, NET_TCP_TW_REUSE=91, - NET_TCP_FRTO=92 + NET_TCP_FRTO=92, + NET_TCP_LOW_LATENCY=93 }; enum { diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h --- a/include/linux/sysfs.h Sun Feb 9 21:13:31 2003 +++ b/include/linux/sysfs.h Sun Feb 9 21:13:31 2003 @@ -30,6 +30,9 @@ extern int sysfs_create_file(struct kobject *, struct attribute *); +extern int +sysfs_update_file(struct kobject *, struct attribute *); + extern void sysfs_remove_file(struct kobject *, struct attribute *); diff -Nru a/include/linux/time.h b/include/linux/time.h --- a/include/linux/time.h Sun Feb 9 21:13:33 2003 +++ b/include/linux/time.h Sun Feb 9 21:13:33 2003 @@ -25,6 +25,7 @@ #ifdef __KERNEL__ #include +#include /* * Change timeval to jiffies, trying to avoid the @@ -120,7 +121,7 @@ } extern struct timespec xtime; -extern rwlock_t xtime_lock; +extern seqlock_t xtime_lock; static inline unsigned long get_seconds(void) { diff -Nru a/include/linux/times.h b/include/linux/times.h --- a/include/linux/times.h Sun Feb 9 21:13:28 2003 +++ b/include/linux/times.h Sun Feb 9 21:13:28 2003 @@ -2,7 +2,30 @@ #define _LINUX_TIMES_H #ifdef __KERNEL__ +#include +#include + +#if (HZ % USER_HZ)==0 # define jiffies_to_clock_t(x) ((x) / (HZ / USER_HZ)) +#else +# define jiffies_to_clock_t(x) ((clock_t) jiffies_64_to_clock_t((u64) x)) +#endif + +static inline u64 jiffies_64_to_clock_t(u64 x) +{ +#if (HZ % USER_HZ)==0 + do_div(x, HZ / USER_HZ); +#else + /* + * There are better ways that don't overflow early, + * but even this doesn't overflow in hundreds of years + * in 64 bits, so.. + */ + x *= USER_HZ; + do_div(x, HZ); +#endif + return x; +} #endif struct tms { diff -Nru a/include/linux/types.h b/include/linux/types.h --- a/include/linux/types.h Sun Feb 9 21:13:35 2003 +++ b/include/linux/types.h Sun Feb 9 21:13:35 2003 @@ -4,10 +4,12 @@ #ifdef __KERNEL__ #include +#define BITS_TO_LONGS(bits) \ + (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG) #define DECLARE_BITMAP(name,bits) \ - unsigned long name[((bits)+BITS_PER_LONG-1)/BITS_PER_LONG] + unsigned long name[BITS_TO_LONGS(bits)] #define CLEAR_BITMAP(name,bits) \ - memset(name, 0, ((bits)+BITS_PER_LONG-1)/8) + memset(name, 0, BITS_TO_LONGS(bits)*sizeof(unsigned long)) #endif #include diff -Nru a/include/linux/usb.h b/include/linux/usb.h --- a/include/linux/usb.h Sun Feb 9 21:13:31 2003 +++ b/include/linux/usb.h Sun Feb 9 21:13:31 2003 @@ -554,7 +554,6 @@ #define URB_NO_FSBR 0x0020 /* UHCI-specific */ #define URB_ZERO_PACKET 0x0040 /* Finish bulk OUTs with short packet */ #define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */ -#define URB_TIMEOUT_KILLED 0x1000 /* only set by HCD! */ struct usb_iso_packet_descriptor { unsigned int offset; diff -Nru a/include/linux/xfrm.h b/include/linux/xfrm.h --- a/include/linux/xfrm.h Sun Feb 9 21:13:29 2003 +++ b/include/linux/xfrm.h Sun Feb 9 21:13:29 2003 @@ -163,6 +163,7 @@ struct xfrm_usersa_id { xfrm_address_t saddr; __u32 spi; + __u16 family; __u8 proto; }; diff -Nru a/include/net/ip.h b/include/net/ip.h --- a/include/net/ip.h Sun Feb 9 21:13:34 2003 +++ b/include/net/ip.h Sun Feb 9 21:13:34 2003 @@ -96,7 +96,7 @@ extern int ip_fragment(struct sk_buff *skb, int (*out)(struct sk_buff*)); extern int ip_do_nat(struct sk_buff *skb); extern void ip_send_check(struct iphdr *ip); -extern int ip_queue_xmit(struct sk_buff *skb); +extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok); extern void ip_init(void); extern int ip_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, diff -Nru a/include/net/sock.h b/include/net/sock.h --- a/include/net/sock.h Sun Feb 9 21:13:34 2003 +++ b/include/net/sock.h Sun Feb 9 21:13:34 2003 @@ -44,6 +44,7 @@ #include #include /* struct sk_buff */ +#include #ifdef CONFIG_FILTER #include @@ -458,28 +459,45 @@ #ifdef CONFIG_FILTER /** - * sk_filter - run a packet through a socket filter + * __sk_filter - run a packet through a socket filter + * @sk: sock associated with &sk_buff * @skb: buffer to filter - * @filter: filter to apply + * @needlock: set to 1 if the sock is not locked by caller. * * Run the filter code and then cut skb->data to correct size returned by * sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller * than pkt_len we keep whole skb->data. This is the socket level * wrapper to sk_run_filter. It returns 0 if the packet should - * be accepted or 1 if the packet should be tossed. + * be accepted or -EPERM if the packet should be tossed. + * + * This function should not be called directly, use sk_filter instead + * to ensure that the LSM security check is also performed. */ - -static inline int sk_filter(struct sk_buff *skb, struct sk_filter *filter) + +static inline int __sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) { - int pkt_len; + int err = 0; - pkt_len = sk_run_filter(skb, filter->insns, filter->len); - if(!pkt_len) - return 1; /* Toss Packet */ - else - skb_trim(skb, pkt_len); + if (sk->filter) { + struct sk_filter *filter; + + if (needlock) + bh_lock_sock(sk); + + filter = sk->filter; + if (filter) { + int pkt_len = sk_run_filter(skb, filter->insns, + filter->len); + if (!pkt_len) + err = -EPERM; + else + skb_trim(skb, pkt_len); + } - return 0; + if (needlock) + bh_unlock_sock(sk); + } + return err; } /** @@ -506,8 +524,26 @@ atomic_add(sk_filter_len(fp), &sk->omem_alloc); } +#else + +static inline int __sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) +{ + return 0; +} + #endif /* CONFIG_FILTER */ +static inline int sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) +{ + int err; + + err = security_sock_rcv_skb(sk, skb); + if (err) + return err; + + return __sk_filter(sk, skb, needlock); +} + /* * Socket reference counting postulates. * @@ -712,36 +748,31 @@ static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) { + int err = 0; + /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces number of warnings when compiling with -W --ANK */ - if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) - return -ENOMEM; - -#ifdef CONFIG_FILTER - if (sk->filter) { - int err = 0; - struct sk_filter *filter; - - /* It would be deadlock, if sock_queue_rcv_skb is used - with socket lock! We assume that users of this - function are lock free. - */ - bh_lock_sock(sk); - if ((filter = sk->filter) != NULL && sk_filter(skb, filter)) - err = -EPERM; - bh_unlock_sock(sk); - if (err) - return err; /* Toss packet */ + if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) { + err = -ENOMEM; + goto out; } -#endif /* CONFIG_FILTER */ + + /* It would be deadlock, if sock_queue_rcv_skb is used + with socket lock! We assume that users of this + function are lock free. + */ + err = sk_filter(sk, skb, 1); + if (err) + goto out; skb->dev = NULL; skb_set_owner_r(skb, sk); skb_queue_tail(&sk->receive_queue, skb); if (!sk->dead) sk->data_ready(sk,skb->len); - return 0; +out: + return err; } static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) diff -Nru a/include/net/tcp.h b/include/net/tcp.h --- a/include/net/tcp.h Sun Feb 9 21:13:29 2003 +++ b/include/net/tcp.h Sun Feb 9 21:13:29 2003 @@ -474,6 +474,7 @@ extern int sysctl_tcp_adv_win_scale; extern int sysctl_tcp_tw_reuse; extern int sysctl_tcp_frto; +extern int sysctl_tcp_low_latency; extern atomic_t tcp_memory_allocated; extern atomic_t tcp_sockets_allocated; @@ -566,7 +567,8 @@ */ struct tcp_func { - int (*queue_xmit) (struct sk_buff *skb); + int (*queue_xmit) (struct sk_buff *skb, + int ipfragok); void (*send_check) (struct sock *sk, struct tcphdr *th, @@ -1348,7 +1350,7 @@ { struct tcp_opt *tp = tcp_sk(sk); - if (tp->ucopy.task) { + if (!sysctl_tcp_low_latency && tp->ucopy.task) { __skb_queue_tail(&tp->ucopy.prequeue, skb); tp->ucopy.memory += skb->truesize; if (tp->ucopy.memory > sk->rcvbuf) { diff -Nru a/include/net/xfrm.h b/include/net/xfrm.h --- a/include/net/xfrm.h Sun Feb 9 21:13:30 2003 +++ b/include/net/xfrm.h Sun Feb 9 21:13:30 2003 @@ -105,7 +105,6 @@ u16 family; xfrm_address_t saddr; int header_len; - int trailer_len; } props; struct xfrm_lifetime_cfg lft; diff -Nru a/include/scsi/scsi.h b/include/scsi/scsi.h --- a/include/scsi/scsi.h Sun Feb 9 21:13:37 2003 +++ b/include/scsi/scsi.h Sun Feb 9 21:13:37 2003 @@ -104,7 +104,26 @@ /* - * Status codes + * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft + * T10/1561-D Revision 4 Draft dated 7th November 2002. + */ +#define SAM_STAT_GOOD 0x00 +#define SAM_STAT_CHECK_CONDITION 0x02 +#define SAM_STAT_CONDITION_MET 0x04 +#define SAM_STAT_BUSY 0x08 +#define SAM_STAT_IMMEDIATE 0x10 +#define SAM_STAT_IMMEDIATE_CONDITION_MET 0x14 +#define SAM_STAT_RESERVATION_CONFLICT 0x18 +#define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */ +#define SAM_STAT_TASK_SET_FULL 0x28 +#define SAM_STAT_ACA_ACTIVE 0x30 +#define SAM_STAT_TASK_ABORTED 0x40 + +/* + * Status codes. These are deprecated as they are shifted 1 bit right + * from those found in the SCSI standards. This causes confusion for + * applications that are ported to several OSes. Prefer SAM Status codes + * above. */ #define GOOD 0x00 diff -Nru a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h --- a/include/sound/ac97_codec.h Sun Feb 9 21:13:32 2003 +++ b/include/sound/ac97_codec.h Sun Feb 9 21:13:32 2003 @@ -196,6 +196,8 @@ #define AC97_CXR_SPDIF_AC3 0x2 /* specific - ALC */ +#define AC97_ALC650_SURR_DAC_VOL 0x64 +#define AC97_ALC650_LFE_DAC_VOL 0x66 #define AC97_ALC650_MULTICH 0x6a #define AC97_ALC650_CLOCK 0x7a @@ -235,8 +237,6 @@ unsigned short (*read) (ac97_t *ac97, unsigned short reg); void (*wait) (ac97_t *ac97); void (*init) (ac97_t *ac97); - snd_info_entry_t *proc_entry; - snd_info_entry_t *proc_regs_entry; void *private_data; void (*private_free) (ac97_t *ac97); /* --- */ diff -Nru a/include/sound/ad1848.h b/include/sound/ad1848.h --- a/include/sound/ad1848.h Sun Feb 9 21:13:30 2003 +++ b/include/sound/ad1848.h Sun Feb 9 21:13:30 2003 @@ -22,7 +22,6 @@ * */ -#include "control.h" #include "pcm.h" /* IO ports */ @@ -162,28 +161,44 @@ ad1848_t ** chip); int snd_ad1848_pcm(ad1848_t * chip, int device, snd_pcm_t **rpcm); +const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction); int snd_ad1848_mixer(ad1848_t * chip); void snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs); +/* exported mixer stuffs */ +enum { AD1848_MIX_SINGLE, AD1848_MIX_DOUBLE, AD1848_MIX_CAPTURE }; + +#define AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) \ + ((reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24)) +#define AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) \ + ((left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22)) + +int snd_ad1848_add_ctl(ad1848_t *chip, const char *name, int index, int type, unsigned long value); + +/* for ease of use */ +struct ad1848_mix_elem { + const char *name; + int index; + int type; + unsigned long private_value; +}; + #define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_ad1848_info_single, \ - .get = snd_ad1848_get_single, .put = snd_ad1848_put_single, \ - .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } - -int snd_ad1848_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo); -int snd_ad1848_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol); -int snd_ad1848_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol); +{ .name = xname, \ + .index = xindex, \ + .type = AD1848_MIX_SINGLE, \ + .private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) } #define AD1848_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ - .info = snd_ad1848_info_double, \ - .get = snd_ad1848_get_double, .put = snd_ad1848_put_double, \ - .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } - -int snd_ad1848_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo); -int snd_ad1848_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol); -int snd_ad1848_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol); +{ .name = xname, \ + .index = xindex, \ + .type = AD1848_MIX_DOUBLE, \ + .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) } + +static inline int snd_ad1848_add_ctl_elem(ad1848_t *chip, const struct ad1848_mix_elem *c) +{ + return snd_ad1848_add_ctl(chip, c->name, c->index, c->type, c->private_value); +} #ifdef CONFIG_SND_DEBUG void snd_ad1848_debug(ad1848_t *chip); diff -Nru a/include/sound/ak4531_codec.h b/include/sound/ak4531_codec.h --- a/include/sound/ak4531_codec.h Sun Feb 9 21:13:30 2003 +++ b/include/sound/ak4531_codec.h Sun Feb 9 21:13:30 2003 @@ -68,7 +68,6 @@ struct _snd_ak4531 { void (*write) (ak4531_t *ak4531, unsigned short reg, unsigned short val); - snd_info_entry_t *proc_entry; void *private_data; void (*private_free) (ak4531_t *ak4531); /* --- */ diff -Nru a/include/sound/core.h b/include/sound/core.h --- a/include/sound/core.h Sun Feb 9 21:13:37 2003 +++ b/include/sound/core.h Sun Feb 9 21:13:37 2003 @@ -55,6 +55,7 @@ SNDRV_DEV_TIMER, SNDRV_DEV_SEQUENCER, SNDRV_DEV_HWDEP, + SNDRV_DEV_INFO, SNDRV_DEV_LOWLEVEL = (2*SNDRV_DEV_TYPE_RANGE_SIZE) } snd_device_type_t; @@ -281,6 +282,8 @@ void *snd_malloc_pci_pages(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr); void *snd_malloc_pci_pages_fallback(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr, unsigned long *res_size); void snd_free_pci_pages(struct pci_dev *pci, unsigned long size, void *ptr, dma_addr_t dma_addr); +void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *dma_addr); +#define snd_free_pci_page(pci,ptr,addr) snd_free_pci_pages(pci,PAGE_SIZE,ptr,addr) #endif #ifdef CONFIG_SBUS void *snd_malloc_sbus_pages(struct sbus_dev *sdev, unsigned long size, dma_addr_t *dma_addr); @@ -343,7 +346,7 @@ void snd_dma_program(unsigned long dma, unsigned long addr, unsigned int size, unsigned short mode); void snd_dma_disable(unsigned long dma); -unsigned int snd_dma_residue(unsigned long dma); +unsigned int snd_dma_pointer(unsigned long dma, unsigned int size); /* misc.c */ @@ -354,13 +357,17 @@ #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) void snd_verbose_printd(const char *file, int line, const char *format, ...); #endif -#if defined(CONFIG_SND_DEBUG) && !defined(CONFIG_SND_VERBOSE_PRINTK) -void snd_printd(const char *format, ...); -#endif /* --- */ #ifdef CONFIG_SND_VERBOSE_PRINTK +/** + * snd_printk - printk wrapper + * @fmt: format string + * + * Works like print() but prints the file and the line of the caller + * when configured with CONFIG_SND_VERBOSE_PRINTK. + */ #define snd_printk(fmt, args...) \ snd_verbose_printk(__FILE__, __LINE__, fmt ,##args) #else @@ -373,15 +380,45 @@ #define __ASTRING__(x) #x #ifdef CONFIG_SND_VERBOSE_PRINTK +/** + * snd_printd - debug printk + * @format: format string + * + * Compiled only when Works like snd_printk() for debugging purpose. + * Ignored when CONFIG_SND_DEBUG is not set. + */ #define snd_printd(fmt, args...) \ snd_verbose_printd(__FILE__, __LINE__, fmt ,##args) +#else +#define snd_printd(fmt, args...) \ + printk(fmt ,##args) #endif +/** + * snd_assert - run-time assersion macro + * @expr: expression + * @args...: the action + * + * This macro checks the expression in run-time and invokes the commands + * given in the rest arguments if the assertion is failed. + * When CONFIG_SND_DEBUG is not set, the expression is executed but + * not checked. + */ #define snd_assert(expr, args...) do {\ if (!(expr)) {\ snd_printk("BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\ args;\ }\ } while (0) +/** + * snd_runtime_check - run-time assersion macro + * @expr: expression + * @args...: the action + * + * This macro checks the expression in run-time and invokes the commands + * given in the rest arguments if the assertion is failed. + * Unlike snd_assert(), the action commands are executed even if + * CONFIG_SND_DEBUG is not set but without any error messages. + */ #define snd_runtime_check(expr, args...) do {\ if (!(expr)) {\ snd_printk("ERROR (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\ @@ -398,6 +435,13 @@ #endif /* CONFIG_SND_DEBUG */ #ifdef CONFIG_SND_DEBUG_DETECT +/** + * snd_printdd - debug printk + * @format: format string + * + * Compiled only when Works like snd_printk() for debugging purpose. + * Ignored when CONFIG_SND_DEBUG_DETECT is not set. + */ #define snd_printdd(format, args...) snd_printk(format, ##args) #else #define snd_printdd(format, args...) /* nothing */ diff -Nru a/include/sound/cs46xx.h b/include/sound/cs46xx.h --- a/include/sound/cs46xx.h Sun Feb 9 21:13:30 2003 +++ b/include/sound/cs46xx.h Sun Feb 9 21:13:30 2003 @@ -1673,7 +1673,6 @@ unsigned long remap_addr; unsigned long size; struct resource *resource; - void *proc_entry; } snd_cs46xx_region_t; struct _snd_cs46xx { @@ -1726,7 +1725,6 @@ spinlock_t reg_lock; unsigned int midcr; unsigned int uartm; - snd_info_entry_t *proc_entry; int amplifier; void (*amplifier_ctrl)(cs46xx_t *, int); diff -Nru a/include/sound/cs46xx_dsp_scb_types.h b/include/sound/cs46xx_dsp_scb_types.h --- a/include/sound/cs46xx_dsp_scb_types.h Sun Feb 9 21:13:32 2003 +++ b/include/sound/cs46xx_dsp_scb_types.h Sun Feb 9 21:13:32 2003 @@ -248,12 +248,12 @@ insure that the fractional error is always positive) */ - long outTripletsPerFrame; + u32 outTripletsPerFrame; /* 16b.16b integer.frac accumulated number of output triplets since the start of group */ - long accumOutTriplets; + u32 accumOutTriplets; } mix2_ostream_spb_t; /* SCB for Timing master algorithm */ @@ -569,10 +569,10 @@ u32 vdec_input_buf_strm_config; /* inputBufStrmConfig: rsConfig for the input buffer to the decimator (buffer size = 64 dwords) */ - long vdec_coef_increment; + u32 vdec_coef_increment; /* coefIncrement = - 128.0 / decimationFactor (as a 32Q15 number) */ - long vdec_accumphi; + u32 vdec_accumphi; /* accumPhi: accumulated fractional phase increment (6.26) */ u16 vdec_exp_vol_change_rate; diff -Nru a/include/sound/cs46xx_dsp_spos.h b/include/sound/cs46xx_dsp_spos.h --- a/include/sound/cs46xx_dsp_spos.h Sun Feb 9 21:13:33 2003 +++ b/include/sound/cs46xx_dsp_spos.h Sun Feb 9 21:13:33 2003 @@ -196,8 +196,8 @@ u16 spdif_input_volume_left; /* spdif channel status, left right and user validity bits */ - int spdif_csuv_default; - int spdif_csuv_stream; + unsigned int spdif_csuv_default; + unsigned int spdif_csuv_stream; /* SPDIF input sample rate converter */ dsp_scb_descriptor_t * spdif_in_src; diff -Nru a/include/sound/emu10k1.h b/include/sound/emu10k1.h --- a/include/sound/emu10k1.h Sun Feb 9 21:13:30 2003 +++ b/include/sound/emu10k1.h Sun Feb 9 21:13:30 2003 @@ -25,12 +25,11 @@ #ifdef __KERNEL__ -#include "pcm.h" -#include "pcm_sgbuf.h" -#include "rawmidi.h" -#include "hwdep.h" -#include "ac97_codec.h" -#include "util_mem.h" +#include +#include +#include +#include +#include #include #ifndef PCI_VENDOR_ID_CREATIVE @@ -232,7 +231,7 @@ #define A_IOCFG 0x18 /* GPIO on Audigy card (16bits) */ #define A_GPINPUT_MASK 0xff00 #define A_GPOUTPUT_MASK 0x00ff -#define A_IOCFG_GPOUT0 0x0040 /* analog/digital? */ +#define A_IOCFG_GPOUT0 0x0044 /* analog/digital? */ #define TIMER 0x1a /* Timer terminal count register */ /* NOTE: After the rate is changed, a maximum */ @@ -993,13 +992,6 @@ emu10k1_midi_t midi2; /* for audigy */ unsigned int efx_voices_mask[2]; - - snd_info_entry_t *proc_entry; - snd_info_entry_t *proc_entry_fx8010_gpr; - snd_info_entry_t *proc_entry_fx8010_tram_data; - snd_info_entry_t *proc_entry_fx8010_tram_addr; - snd_info_entry_t *proc_entry_fx8010_code; - snd_info_entry_t *proc_entry_fx8010_iblocks; }; int snd_emu10k1_create(snd_card_t * card, @@ -1045,7 +1037,7 @@ unsigned char snd_emu10k1_sum_vol_attn(unsigned int value); /* memory allocation */ -snd_util_memblk_t *snd_emu10k1_alloc_pages(emu10k1_t *emu, struct snd_sg_buf *sgbuf); +snd_util_memblk_t *snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream); int snd_emu10k1_free_pages(emu10k1_t *emu, snd_util_memblk_t *blk); snd_util_memblk_t *snd_emu10k1_synth_alloc(emu10k1_t *emu, unsigned int size); int snd_emu10k1_synth_free(emu10k1_t *emu, snd_util_memblk_t *blk); @@ -1063,7 +1055,6 @@ /* proc interface */ int snd_emu10k1_proc_init(emu10k1_t * emu); -int snd_emu10k1_proc_done(emu10k1_t * emu); #endif /* __KERNEL__ */ diff -Nru a/include/sound/gus.h b/include/sound/gus.h --- a/include/sound/gus.h Sun Feb 9 21:13:28 2003 +++ b/include/sound/gus.h Sun Feb 9 21:13:28 2003 @@ -210,7 +210,6 @@ snd_gf1_bank_info_t banks_16[4]; snd_gf1_mem_block_t *first; snd_gf1_mem_block_t *last; - snd_info_entry_t *info_entry; struct semaphore memory_mutex; } snd_gf1_mem_t; @@ -332,8 +331,6 @@ unsigned int rom_banks; /* GUS's ROM banks */ snd_gf1_mem_t mem_alloc; - snd_info_entry_t *ram_entries[4]; - snd_info_entry_t *rom_entries[4]; /* registers */ unsigned short reg_page; @@ -452,9 +449,6 @@ int timer_dev; /* timer device */ struct _snd_gf1 gf1; /* gf1 specific variables */ -#ifdef CONFIG_SND_DEBUG - snd_info_entry_t *irq_entry; -#endif snd_pcm_t *pcm; snd_pcm_substream_t *pcm_cap_substream; unsigned int c_dma_size; @@ -601,7 +595,6 @@ /* gus_mem_proc.c */ int snd_gf1_mem_proc_init(snd_gus_card_t * gus); -int snd_gf1_mem_proc_done(snd_gus_card_t * gus); /* gus_dma.c */ @@ -676,7 +669,6 @@ void snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs); #ifdef CONFIG_SND_DEBUG void snd_gus_irq_profile_init(snd_gus_card_t *gus); -void snd_gus_irq_profile_done(snd_gus_card_t *gus); #endif /* gus_uart.c */ diff -Nru a/include/sound/info.h b/include/sound/info.h --- a/include/sound/info.h Sun Feb 9 21:13:34 2003 +++ b/include/sound/info.h Sun Feb 9 21:13:34 2003 @@ -141,6 +141,19 @@ void snd_remove_proc_entry(struct proc_dir_entry *parent, struct proc_dir_entry *de); +/* for card drivers */ +int snd_card_proc_new(snd_card_t *card, const char *name, snd_info_entry_t **entryp); + +inline static void snd_info_set_text_ops(snd_info_entry_t *entry, + void *private_data, + void (*read)(snd_info_entry_t *, snd_info_buffer_t *)) +{ + entry->private_data = private_data; + entry->c.text.read_size = 1024; + entry->c.text.read = read; +} + + #else #define snd_seq_root NULL @@ -160,14 +173,18 @@ unsigned int mode) { return NULL; } static inline void snd_info_free_device(snd_info_entry_t * entry) { ; } +static inline int snd_info_card_create(snd_card_t * card) { return 0; } static inline int snd_info_card_register(snd_card_t * card) { return 0; } -static inline int snd_info_card_unregister(snd_card_t * card) { return 0; } +static inline int snd_info_card_free(snd_card_t * card) { return 0; } static inline int snd_info_register(snd_info_entry_t * entry) { return 0; } static inline int snd_info_unregister(snd_info_entry_t * entry) { return 0; } static inline struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent) { return NULL; } static inline void snd_remove_proc_entry(struct proc_dir_entry *parent, struct proc_dir_entry *de) { ; } + +#define snd_card_proc_new(card,name,entryp) 0 /* always success */ +#define snd_info_set_text_ops(entry,private_data,read) /*NOP*/ #endif diff -Nru a/include/sound/mixer_oss.h b/include/sound/mixer_oss.h --- a/include/sound/mixer_oss.h Sun Feb 9 21:13:32 2003 +++ b/include/sound/mixer_oss.h Sun Feb 9 21:13:32 2003 @@ -31,8 +31,8 @@ typedef int (*snd_mixer_oss_put_volume_t)(snd_mixer_oss_file_t *fmixer, snd_mixer_oss_slot_t *chn, int left, int right); typedef int (*snd_mixer_oss_get_recsrc_t)(snd_mixer_oss_file_t *fmixer, snd_mixer_oss_slot_t *chn, int *active); typedef int (*snd_mixer_oss_put_recsrc_t)(snd_mixer_oss_file_t *fmixer, snd_mixer_oss_slot_t *chn, int active); -typedef int (*snd_mixer_oss_get_recsrce_t)(snd_mixer_oss_file_t *fmixer, int *active_index); -typedef int (*snd_mixer_oss_put_recsrce_t)(snd_mixer_oss_file_t *fmixer, int active_index); +typedef int (*snd_mixer_oss_get_recsrce_t)(snd_mixer_oss_file_t *fmixer, unsigned int *active_index); +typedef int (*snd_mixer_oss_put_recsrce_t)(snd_mixer_oss_file_t *fmixer, unsigned int active_index); #define SNDRV_OSS_MAX_MIXERS 32 diff -Nru a/include/sound/pcm.h b/include/sound/pcm.h --- a/include/sound/pcm.h Sun Feb 9 21:13:32 2003 +++ b/include/sound/pcm.h Sun Feb 9 21:13:32 2003 @@ -50,7 +50,7 @@ typedef struct sndrv_pcm_mmap_control snd_pcm_mmap_control_t; typedef struct sndrv_mask snd_mask_t; -#define _snd_pcm_substream_chip(substream) ((substream)->pcm->private_data) +#define _snd_pcm_substream_chip(substream) ((substream)->private_data) #define snd_pcm_substream_chip(substream) snd_magic_cast1(chip_t, _snd_pcm_substream_chip(substream), return -ENXIO) #define _snd_pcm_chip(pcm) ((pcm)->private_data) #define snd_pcm_chip(pcm) snd_magic_cast1(chip_t, _snd_pcm_chip(pcm), return -ENXIO) @@ -120,10 +120,12 @@ #define SNDRV_PCM_TRIGGER_SUSPEND 5 #define SNDRV_PCM_TRIGGER_RESUME 6 -#define SNDRV_PCM_DMA_TYPE_CONTINUOUS 0 /* continuous no-DMA memory */ -#define SNDRV_PCM_DMA_TYPE_ISA 1 /* ISA continuous */ -#define SNDRV_PCM_DMA_TYPE_PCI 2 /* PCI continuous */ -#define SNDRV_PCM_DMA_TYPE_SBUS 3 /* SBUS continuous */ +#define SNDRV_PCM_DMA_TYPE_UNKNOWN 0 /* not defined */ +#define SNDRV_PCM_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */ +#define SNDRV_PCM_DMA_TYPE_ISA 2 /* ISA continuous */ +#define SNDRV_PCM_DMA_TYPE_PCI 3 /* PCI continuous */ +#define SNDRV_PCM_DMA_TYPE_SBUS 4 /* SBUS continuous */ +#define SNDRV_PCM_DMA_TYPE_PCI_SG 5 /* PCI SG-buffer */ /* If you change this don't forget to change rates[] table in pcm_native.c */ #define SNDRV_PCM_RATE_5512 (1<<0) /* 5512Hz */ @@ -363,6 +365,7 @@ struct _snd_pcm_substream { snd_pcm_t *pcm; snd_pcm_str_t *pstr; + void *private_data; /* copied from pcm->private_data */ int number; char name[32]; /* substream name */ int stream; /* stream (direction) */ @@ -741,6 +744,10 @@ snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, unsigned int val, int *dir); +int snd_pcm_hw_param_set(snd_pcm_substream_t *pcm, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, + unsigned int val, int dir); int snd_pcm_hw_params_choose(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params); int snd_pcm_hw_refine(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params); diff -Nru a/include/sound/pcm_params.h b/include/sound/pcm_params.h --- a/include/sound/pcm_params.h Sun Feb 9 21:13:29 2003 +++ b/include/sound/pcm_params.h Sun Feb 9 21:13:29 2003 @@ -129,7 +129,7 @@ INLINE void snd_mask_set_range(snd_mask_t *mask, unsigned int from, unsigned int to) { - int i; + unsigned int i; assert(to <= SNDRV_MASK_BITS && from <= to); for (i = from; i <= to; i++) mask->bits[MASK_OFS(i)] |= MASK_BIT(i); @@ -137,7 +137,7 @@ INLINE void snd_mask_reset_range(snd_mask_t *mask, unsigned int from, unsigned int to) { - int i; + unsigned int i; assert(to <= SNDRV_MASK_BITS && from <= to); for (i = from; i <= to; i++) mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i); diff -Nru a/include/sound/pcm_sgbuf.h b/include/sound/pcm_sgbuf.h --- a/include/sound/pcm_sgbuf.h Sun Feb 9 21:13:35 2003 +++ b/include/sound/pcm_sgbuf.h Sun Feb 9 21:13:35 2003 @@ -32,6 +32,7 @@ int pages; /* allocated pages */ int tblsize; /* allocated table size */ struct snd_sg_page *table; + struct page **page_table; struct pci_dev *pci; }; @@ -53,15 +54,17 @@ return sgbuf->table[offset >> PAGE_SHIFT].addr + offset % PAGE_SIZE; } -int snd_pcm_sgbuf_init(snd_pcm_substream_t *substream, struct pci_dev *pci, int tblsize); -int snd_pcm_sgbuf_delete(snd_pcm_substream_t *substream); -int snd_pcm_sgbuf_alloc(snd_pcm_substream_t *substream, size_t size); -int snd_pcm_sgbuf_free(snd_pcm_substream_t *substream); - -int snd_pcm_sgbuf_ops_copy_playback(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t hwoff, void *buf, snd_pcm_uframes_t count); -int snd_pcm_sgbuf_ops_copy_capture(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t hwoff, void *buf, snd_pcm_uframes_t count); -int snd_pcm_sgbuf_ops_silence(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t hwoff, snd_pcm_uframes_t count); -struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset); +struct snd_sg_buf *snd_pcm_sgbuf_init(struct pci_dev *pci); +void snd_pcm_sgbuf_delete(struct snd_sg_buf *sgbuf); +void *snd_pcm_sgbuf_alloc_pages(struct snd_sg_buf *sgbuf, size_t size); +int snd_pcm_sgbuf_free_pages(struct snd_sg_buf *sgbuf, void *vmaddr); + +int snd_pcm_lib_preallocate_sg_pages(struct pci_dev *pci, snd_pcm_substream_t *substream); +int snd_pcm_lib_preallocate_sg_pages_for_all(struct pci_dev *pci, snd_pcm_t *pcm); +#define _snd_pcm_substream_sgbuf(substream) ((substream)->dma_private) +#define snd_pcm_substream_sgbuf(substream) snd_magic_cast(snd_pcm_sgbuf_t, _snd_pcm_substream_sgbuf(substream), return -ENXIO) + +struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset); #endif /* __SOUND_PCM_SGBUF_H */ diff -Nru a/include/sound/sb.h b/include/sound/sb.h --- a/include/sound/sb.h Sun Feb 9 21:13:31 2003 +++ b/include/sound/sb.h Sun Feb 9 21:13:31 2003 @@ -305,6 +305,7 @@ /* sb16_init.c */ int snd_sb16dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm); +const snd_pcm_ops_t *snd_sb16dsp_get_pcm_ops(int direction); int snd_sb16dsp_configure(sb_t *chip); /* sb16.c */ void snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -312,5 +313,50 @@ int snd_sb16_capture_open(snd_pcm_substream_t *substream); int snd_sb16_playback_close(snd_pcm_substream_t *substream); int snd_sb16_capture_close(snd_pcm_substream_t *substream); + +/* exported mixer stuffs */ +enum { + SB_MIX_SINGLE, + SB_MIX_DOUBLE, + SB_MIX_INPUT_SW, + SB_MIX_CAPTURE_PRO, + SB_MIX_CAPTURE_DT019X +}; + +#define SB_MIXVAL_DOUBLE(left_reg, right_reg, left_shift, right_shift, mask) \ + ((left_reg) | ((right_reg) << 8) | ((left_shift) << 16) | ((right_shift) << 19) | ((mask) << 24)) +#define SB_MIXVAL_SINGLE(reg, shift, mask) \ + ((reg) | ((shift) << 16) | ((mask) << 24)) +#define SB_MIXVAL_INPUT_SW(reg1, reg2, left_shift, right_shift) \ + ((reg1) | ((reg2) << 8) | ((left_shift) << 16) | ((right_shift) << 24)) + +int snd_sbmixer_add_ctl(sb_t *chip, const char *name, int index, int type, unsigned long value); + +/* for ease of use */ +struct sbmix_elem { + const char *name; + int type; + unsigned long private_value; +}; + +#define SB_SINGLE(xname, reg, shift, mask) \ +{ .name = xname, \ + .type = SB_MIX_SINGLE, \ + .private_value = SB_MIXVAL_SINGLE(reg, shift, mask) } + +#define SB_DOUBLE(xname, left_reg, right_reg, left_shift, right_shift, mask) \ +{ .name = xname, \ + .type = SB_MIX_DOUBLE, \ + .private_value = SB_MIXVAL_DOUBLE(left_reg, right_reg, left_shift, right_shift, mask) } + +#define SB16_INPUT_SW(xname, reg1, reg2, left_shift, right_shift) \ +{ .name = xname, \ + .type = SB_MIX_INPUT_SW, \ + .private_value = SB_MIXVAL_INPUT_SW(reg1, reg2, left_shift, right_shift) } + +static inline int snd_sbmixer_add_ctl_elem(sb_t *chip, const struct sbmix_elem *c) +{ + return snd_sbmixer_add_ctl(chip, c->name, 0, c->type, c->private_value); +} #endif /* __SOUND_SB_H */ diff -Nru a/include/sound/sb16_csp.h b/include/sound/sb16_csp.h --- a/include/sound/sb16_csp.h Sun Feb 9 21:13:36 2003 +++ b/include/sound/sb16_csp.h Sun Feb 9 21:13:36 2003 @@ -159,7 +159,6 @@ snd_kcontrol_t *qsound_space; struct semaphore access_mutex; /* locking */ - snd_info_entry_t *proc; /* proc interface */ }; int snd_sb_csp_new(sb_t *chip, int device, snd_hwdep_t ** rhwdep); diff -Nru a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h --- a/include/sound/seq_kernel.h Sun Feb 9 21:13:36 2003 +++ b/include/sound/seq_kernel.h Sun Feb 9 21:13:36 2003 @@ -174,7 +174,7 @@ /* port attach/detach */ int snd_seq_event_port_attach(int client, snd_seq_port_callback_t *pcbp, - int cap, int type, char *portname); + int cap, int type, int midi_channels, char *portname); int snd_seq_event_port_detach(int client, int port); #endif /* __SOUND_SEQ_KERNEL_H */ diff -Nru a/include/sound/sndmagic.h b/include/sound/sndmagic.h --- a/include/sound/sndmagic.h Sun Feb 9 21:13:30 2003 +++ b/include/sound/sndmagic.h Sun Feb 9 21:13:30 2003 @@ -27,14 +27,49 @@ void *_snd_magic_kcalloc(unsigned long magic, size_t size, int flags); void *_snd_magic_kmalloc(unsigned long magic, size_t size, int flags); -void snd_magic_kfree(void *ptr); -#define snd_magic_kcalloc(type, extra, flags) (type *) _snd_magic_kcalloc(type##_magic, sizeof(type) + extra, flags) -#define snd_magic_kmalloc(type, extra, flags) (type *) _snd_magic_kmalloc(type##_magic, sizeof(type) + extra, flags) +/** + * snd_magic_kmalloc - allocate a record with a magic-prefix + * @type: the type to allocate a record (like xxx_t) + * @extra: the extra size to allocate in bytes + * @flags: the allocation condition (GFP_XXX) + * + * Allocates a record of the given type with the extra space and + * returns its pointer. The allocated record has a secret magic-key + * to be checked via snd_magic_cast() for safe casts. + * + * The allocated pointer must be released via snd_magic_kfree(). + * + * The "struct xxx" style cannot be used as the type argument + * because the magic-key constant is generated from the type-name + * string. + */ +#define snd_magic_kmalloc(type, extra, flags) \ + (type *) _snd_magic_kmalloc(type##_magic, sizeof(type) + extra, flags) +/** + * snd_magic_kcalloc - allocate a record with a magic-prefix and initialize + * @type: the type to allocate a record (like xxx_t) + * @extra: the extra size to allocate in bytes + * @flags: the allocation condition (GFP_XXX) + * + * Works like snd_magic_kmalloc() but this clears the area with zero + * automatically. + */ +#define snd_magic_kcalloc(type, extra, flags) \ + (type *) _snd_magic_kcalloc(type##_magic, sizeof(type) + extra, flags) + +/** + * snd_magic_kfree - release the allocated area + * @ptr: the pointer allocated via snd_magic_kmalloc() or snd_magic_kcalloc() + * + * Releases the memory area allocated via snd_magic_kmalloc() or + * snd_magic_kcalloc() function. + */ +void snd_magic_kfree(void *ptr); static inline unsigned long _snd_magic_value(void *obj) { - return obj == NULL ? -1 : *(((unsigned long *)obj) - 1); + return obj == NULL ? (unsigned long)-1 : *(((unsigned long *)obj) - 1); } static inline int _snd_magic_bad(void *obj, unsigned long magic) @@ -44,7 +79,19 @@ #define snd_magic_cast1(t, expr, cmd) snd_magic_cast(t, expr, cmd) -#define snd_magic_cast(type, ptr, action...) (type *) ({\ +/** + * snd_magic_cast - check and cast the magic-allocated pointer + * @type: the type of record to cast + * @ptr: the magic-allocated pointer + * @action...: the action to do if failed + * + * This macro provides a safe cast for the given type, which was + * allocated via snd_magic_kmalloc() or snd_magic_kcallc(). + * If the pointer is invalid, i.e. the cast-type doesn't match, + * the action arguments are called with a debug message. + */ +#define snd_magic_cast(type, ptr, action...) \ + (type *) ({\ void *__ptr = ptr;\ unsigned long __magic = _snd_magic_value(__ptr);\ if (__magic != type##_magic) {\ @@ -64,6 +111,7 @@ #define snd_pcm_sgbuf_t_magic 0xa15a0107 #define snd_info_private_data_t_magic 0xa15a0201 +#define snd_info_entry_t_magic 0xa15a0202 #define snd_ctl_file_t_magic 0xa15a0301 #define snd_kcontrol_t_magic 0xa15a0302 #define snd_rawmidi_t_magic 0xa15a0401 diff -Nru a/include/sound/timer.h b/include/sound/timer.h --- a/include/sound/timer.h Sun Feb 9 21:13:32 2003 +++ b/include/sound/timer.h Sun Feb 9 21:13:32 2003 @@ -23,6 +23,7 @@ */ #include +#include typedef enum sndrv_timer_class snd_timer_class_t; typedef enum sndrv_timer_slave_class snd_timer_slave_class_t; @@ -45,17 +46,19 @@ #define SNDRV_TIMER_HW_STOP 0x00000002 /* call stop before start */ #define SNDRV_TIMER_HW_SLAVE 0x00000004 /* only slave timer (variable resolution) */ #define SNDRV_TIMER_HW_FIRST 0x00000008 /* first tick can be incomplete */ +#define SNDRV_TIMER_HW_TASKLET 0x00000010 /* timer is called from tasklet */ -#define SNDRV_TIMER_IFLG_SLAVE 0x00000001 -#define SNDRV_TIMER_IFLG_RUNNING 0x00000002 -#define SNDRV_TIMER_IFLG_START 0x00000004 -#define SNDRV_TIMER_IFLG_AUTO 0x00000008 /* auto restart */ - -#define SNDRV_TIMER_FLG_SYSTEM 0x00000001 /* system timer */ -#define SNDRV_TIMER_FLG_CHANGE 0x00000002 -#define SNDRV_TIMER_FLG_RESCHED 0x00000004 /* need reschedule */ +#define SNDRV_TIMER_IFLG_SLAVE 0x00000001 +#define SNDRV_TIMER_IFLG_RUNNING 0x00000002 +#define SNDRV_TIMER_IFLG_START 0x00000004 +#define SNDRV_TIMER_IFLG_AUTO 0x00000008 /* auto restart */ +#define SNDRV_TIMER_IFLG_FAST 0x00000010 /* fast callback (do not use tasklet) */ +#define SNDRV_TIMER_IFLG_CALLBACK 0x00000020 /* timer callback is active */ -typedef void (*snd_timer_callback_t) (snd_timer_instance_t * timeri, unsigned long ticks, unsigned long resolution, void *data); +#define SNDRV_TIMER_FLG_CHANGE 0x00000001 +#define SNDRV_TIMER_FLG_RESCHED 0x00000002 /* need reschedule */ + +typedef void (*snd_timer_callback_t) (snd_timer_instance_t * timeri, unsigned long ticks, unsigned long resolution); struct _snd_timer_hardware { /* -- must be filled with low-level driver */ @@ -87,6 +90,9 @@ struct list_head device_list; struct list_head open_list_head; struct list_head active_list_head; + struct list_head ack_list_head; + struct list_head sack_list_head; /* slow ack list head */ + struct tasklet_struct task_queue; }; struct _snd_timer_instance { @@ -97,17 +103,19 @@ void (*private_free) (snd_timer_instance_t *ti); snd_timer_callback_t callback; void *callback_data; - unsigned long ticks; - unsigned long cticks; + unsigned long ticks; /* auto-load ticks when expired */ + unsigned long cticks; /* current ticks */ + unsigned long pticks; /* accumulated ticks for callback */ + unsigned long resolution; /* current resolution for tasklet */ unsigned long lost; /* lost ticks */ snd_timer_slave_class_t slave_class; unsigned int slave_id; struct list_head open_list; struct list_head active_list; + struct list_head ack_list; struct list_head slave_list_head; struct list_head slave_active_head; snd_timer_instance_t *master; - atomic_t in_use; /* don't free */ }; /* @@ -128,7 +136,6 @@ extern unsigned long snd_timer_resolution(snd_timer_instance_t * timeri); extern int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks); extern int snd_timer_stop(snd_timer_instance_t * timeri); -extern int snd_timer_del(snd_timer_instance_t * timeri); extern int snd_timer_continue(snd_timer_instance_t * timeri); extern void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left); diff -Nru a/include/sound/trident.h b/include/sound/trident.h --- a/include/sound/trident.h Sun Feb 9 21:13:33 2003 +++ b/include/sound/trident.h Sun Feb 9 21:13:33 2003 @@ -431,7 +431,8 @@ int ChanPCM; /* max number of PCM channels */ int ChanPCMcnt; /* actual number of PCM channels */ - int ac97_detect; /* 1 = AC97 in detection phase */ + unsigned int ac97_detect: 1; /* 1 = AC97 in detection phase */ + unsigned int in_suspend: 1; /* 1 during suspend/resume */ struct _snd_4dwave synth; /* synth specific variables */ @@ -452,7 +453,6 @@ snd_trident_pcm_mixer_t pcm_mixer[32]; spinlock_t reg_lock; - snd_info_entry_t *proc_entry; struct snd_trident_gameport *gameport; }; @@ -479,7 +479,7 @@ void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max); /* TLB memory allocation */ -snd_util_memblk_t *snd_trident_alloc_pages(trident_t *trident, void *pages, dma_addr_t addr, unsigned long size); +snd_util_memblk_t *snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream); int snd_trident_free_pages(trident_t *trident, snd_util_memblk_t *blk); snd_util_memblk_t *snd_trident_synth_alloc(trident_t *trident, unsigned int size); int snd_trident_synth_free(trident_t *trident, snd_util_memblk_t *blk); diff -Nru a/include/sound/version.h b/include/sound/version.h --- a/include/sound/version.h Sun Feb 9 21:13:31 2003 +++ b/include/sound/version.h Sun Feb 9 21:13:31 2003 @@ -1,3 +1,3 @@ -/* include/version.h. Generated automatically by configure. */ -#define CONFIG_SND_VERSION "0.9.0rc6" -#define CONFIG_SND_DATE " (Tue Dec 17 19:01:13 2002 UTC)" +/* include/version.h. Generated by configure. */ +#define CONFIG_SND_VERSION "0.9.0rc7" +#define CONFIG_SND_DATE " (Sun Feb 09 18:00:12 2003 UTC)" diff -Nru a/init/Kconfig b/init/Kconfig --- a/init/Kconfig Sun Feb 9 21:13:35 2003 +++ b/init/Kconfig Sun Feb 9 21:13:35 2003 @@ -144,6 +144,18 @@ have not been converted to the new module parameter system yet. If unsure, say Y. +config MODVERSIONS + bool "Module versioning support (EXPERIMENTAL)" + depends on MODULES && EXPERIMENTAL + help + Usually, you have to use modules compiled with your kernel. + Saying Y here makes it sometimes possible to use modules + compiled for different kernels, by adding enough information + to the modules to (hopefully) spot any changes which would + make them incompatible with the kernel you are running. If + you say Y here, you will need a copy of genksyms. If + unsure, say N. + config KMOD bool "Kernel module loader" depends on MODULES diff -Nru a/init/do_mounts.c b/init/do_mounts.c --- a/init/do_mounts.c Sun Feb 9 21:13:31 2003 +++ b/init/do_mounts.c Sun Feb 9 21:13:31 2003 @@ -653,12 +653,6 @@ /* * OK, time to copy in the data */ - buf = kmalloc(BLOCK_SIZE, GFP_KERNEL); - if (buf == 0) { - printk(KERN_ERR "RAMDISK: could not allocate buffer\n"); - goto done; - } - if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0) devblocks = 0; else @@ -669,6 +663,12 @@ if (devblocks == 0) { printk(KERN_ERR "RAMDISK: could not determine device size\n"); + goto done; + } + + buf = kmalloc(BLOCK_SIZE, GFP_KERNEL); + if (buf == 0) { + printk(KERN_ERR "RAMDISK: could not allocate buffer\n"); goto done; } diff -Nru a/kernel/Makefile b/kernel/Makefile --- a/kernel/Makefile Sun Feb 9 21:13:29 2003 +++ b/kernel/Makefile Sun Feb 9 21:13:29 2003 @@ -2,10 +2,6 @@ # Makefile for the linux kernel. # -export-objs = signal.o sys.o kmod.o workqueue.o ksyms.o pm.o exec_domain.o \ - printk.o suspend.o dma.o module.o cpufreq.o \ - profile.o rcupdate.o intermodule.o params.o - obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ exit.o itimer.o time.o softirq.o resource.o \ sysctl.o capability.o ptrace.o timer.o user.o \ diff -Nru a/kernel/acct.c b/kernel/acct.c --- a/kernel/acct.c Sun Feb 9 21:13:32 2003 +++ b/kernel/acct.c Sun Feb 9 21:13:32 2003 @@ -51,7 +51,9 @@ #include #include #include +#include #include +#include /* * These constants control the amount of freespace that suspend and @@ -306,6 +308,7 @@ mm_segment_t fs; unsigned long vsize; unsigned long flim; + u64 elapsed; /* * First check to see if there is enough free_space to continue @@ -323,9 +326,11 @@ strncpy(ac.ac_comm, current->comm, ACCT_COMM); ac.ac_comm[ACCT_COMM - 1] = '\0'; - ac.ac_btime = CT_TO_SECS(current->start_time) + - (xtime.tv_sec - (jiffies / HZ)); - ac.ac_etime = encode_comp_t(jiffies - current->start_time); + elapsed = get_jiffies_64() - current->start_time; + ac.ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ? + (unsigned long) elapsed : (unsigned long) -1l); + do_div(elapsed, HZ); + ac.ac_btime = xtime.tv_sec - elapsed; ac.ac_utime = encode_comp_t(current->utime); ac.ac_stime = encode_comp_t(current->stime); ac.ac_uid = current->uid; diff -Nru a/kernel/exit.c b/kernel/exit.c --- a/kernel/exit.c Sun Feb 9 21:13:35 2003 +++ b/kernel/exit.c Sun Feb 9 21:13:35 2003 @@ -76,6 +76,7 @@ if (unlikely(p->ptrace)) __ptrace_unlink(p); BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children)); + __exit_signal(p); __exit_sighand(p); proc_dentry = __unhash_process(p); @@ -156,7 +157,7 @@ * * "I ask you, have you ever known what it is to be an orphan?" */ -static int __will_become_orphaned_pgrp(int pgrp, task_t *ignored_task) +static int will_become_orphaned_pgrp(int pgrp, task_t *ignored_task) { struct task_struct *p; struct list_head *l; @@ -177,22 +178,17 @@ return ret; /* (sighing) "Often!" */ } -static int will_become_orphaned_pgrp(int pgrp, struct task_struct * ignored_task) +int is_orphaned_pgrp(int pgrp) { int retval; read_lock(&tasklist_lock); - retval = __will_become_orphaned_pgrp(pgrp, ignored_task); + retval = will_become_orphaned_pgrp(pgrp, NULL); read_unlock(&tasklist_lock); return retval; } -int is_orphaned_pgrp(int pgrp) -{ - return will_become_orphaned_pgrp(pgrp, 0); -} - static inline int has_stopped_jobs(int pgrp) { int retval = 0; @@ -203,6 +199,17 @@ for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) { if (p->state != TASK_STOPPED) continue; + + /* If p is stopped by a debugger on a signal that won't + stop it, then don't count p as stopped. This isn't + perfect but it's a good approximation. */ + if (unlikely (p->ptrace) + && p->exit_code != SIGSTOP + && p->exit_code != SIGTSTP + && p->exit_code != SIGTTOU + && p->exit_code != SIGTTIN) + continue; + retval = 1; break; } @@ -247,6 +254,29 @@ write_unlock_irq(&tasklist_lock); } +void __set_special_pids(pid_t session, pid_t pgrp) +{ + struct task_struct *curr = current; + + if (curr->session != session) { + detach_pid(curr, PIDTYPE_SID); + curr->session = session; + attach_pid(curr, PIDTYPE_SID, session); + } + if (curr->pgrp != pgrp) { + detach_pid(curr, PIDTYPE_PGID); + curr->pgrp = pgrp; + attach_pid(curr, PIDTYPE_PGID, pgrp); + } +} + +void set_special_pids(pid_t session, pid_t pgrp) +{ + write_lock_irq(&tasklist_lock); + __set_special_pids(session, pgrp); + write_unlock_irq(&tasklist_lock); +} + /* * Put all the gunge required to become a kernel thread without * attached user resources in one place where it belongs. @@ -264,8 +294,7 @@ */ exit_mm(current); - current->session = 1; - current->pgrp = 1; + set_special_pids(1, 1); current->tty = NULL; /* Become as one with the init task */ @@ -495,7 +524,7 @@ (p->session == father->session)) { int pgrp = p->pgrp; - if (__will_become_orphaned_pgrp(pgrp, 0) && has_stopped_jobs(pgrp)) { + if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) { __kill_pg_info(SIGHUP, (void *)1, pgrp); __kill_pg_info(SIGCONT, (void *)1, pgrp); } @@ -547,10 +576,33 @@ * Send signals to all our closest relatives so that they know * to properly mourn us.. */ -static void exit_notify(void) +static void exit_notify(struct task_struct *tsk) { struct task_struct *t; + if (signal_pending(tsk) && !tsk->signal->group_exit + && !thread_group_empty(tsk)) { + /* + * This occurs when there was a race between our exit + * syscall and a group signal choosing us as the one to + * wake up. It could be that we are the only thread + * alerted to check for pending signals, but another thread + * should be woken now to take the signal since we will not. + * Now we'll wake all the threads in the group just to make + * sure someone gets all the pending signals. + */ + read_lock(&tasklist_lock); + spin_lock_irq(&tsk->sighand->siglock); + for (t = next_thread(tsk); t != tsk; t = next_thread(t)) + if (!signal_pending(t) && !(t->flags & PF_EXITING)) { + recalc_sigpending_tsk(t); + if (signal_pending(t)) + signal_wake_up(t, 0); + } + spin_unlock_irq(&tsk->sighand->siglock); + read_unlock(&tasklist_lock); + } + write_lock_irq(&tasklist_lock); /* @@ -562,8 +614,8 @@ * jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2) */ - forget_original_parent(current); - BUG_ON(!list_empty(¤t->children)); + forget_original_parent(tsk); + BUG_ON(!list_empty(&tsk->children)); /* * Check to see if any process groups have become orphaned @@ -575,14 +627,14 @@ * is about to become orphaned. */ - t = current->parent; + t = tsk->real_parent; - if ((t->pgrp != current->pgrp) && - (t->session == current->session) && - __will_become_orphaned_pgrp(current->pgrp, current) && - has_stopped_jobs(current->pgrp)) { - __kill_pg_info(SIGHUP, (void *)1, current->pgrp); - __kill_pg_info(SIGCONT, (void *)1, current->pgrp); + if ((t->pgrp != tsk->pgrp) && + (t->session == tsk->session) && + will_become_orphaned_pgrp(tsk->pgrp, tsk) && + has_stopped_jobs(tsk->pgrp)) { + __kill_pg_info(SIGHUP, (void *)1, tsk->pgrp); + __kill_pg_info(SIGCONT, (void *)1, tsk->pgrp); } /* Let father know we died @@ -601,17 +653,25 @@ * */ - if (current->exit_signal != SIGCHLD && current->exit_signal != -1 && - ( current->parent_exec_id != t->self_exec_id || - current->self_exec_id != current->parent_exec_id) + if (tsk->exit_signal != SIGCHLD && tsk->exit_signal != -1 && + ( tsk->parent_exec_id != t->self_exec_id || + tsk->self_exec_id != tsk->parent_exec_id) && !capable(CAP_KILL)) - current->exit_signal = SIGCHLD; + tsk->exit_signal = SIGCHLD; - if (current->exit_signal != -1) - do_notify_parent(current, current->exit_signal); + /* If something other than our normal parent is ptracing us, then + * send it a SIGCHLD instead of honoring exit_signal. exit_signal + * only has special meaning to our real parent. + */ + if (tsk->exit_signal != -1) { + if (tsk->parent == tsk->real_parent) + do_notify_parent(tsk, tsk->exit_signal); + else + do_notify_parent(tsk, SIGCHLD); + } - current->state = TASK_ZOMBIE; + tsk->state = TASK_ZOMBIE; /* * No need to unlock IRQs, we'll schedule() immediately * anyway. In the preemption case this also makes it @@ -642,7 +702,9 @@ profile_exit_task(tsk); -fake_volatile: + if (unlikely(current->ptrace & PT_TRACE_EXIT)) + ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP); + acct_process(code); __exit_mm(tsk); @@ -652,7 +714,7 @@ exit_namespace(tsk); exit_thread(); - if (current->leader) + if (tsk->leader) disassociate_ctty(1); module_put(tsk->thread_info->exec_domain->module); @@ -660,26 +722,16 @@ module_put(tsk->binfmt->module); tsk->exit_code = code; - exit_notify(); + exit_notify(tsk); preempt_disable(); - if (current->exit_signal == -1) - release_task(current); + + if (tsk->exit_signal == -1) + release_task(tsk); + schedule(); BUG(); -/* - * In order to get rid of the "volatile function does return" message - * I did this little loop that confuses gcc to think do_exit really - * is volatile. In fact it's schedule() that is volatile in some - * circumstances: when current->state = ZOMBIE, schedule() never - * returns. - * - * In fact the natural way to do all this is to have the label and the - * goto right after each other, but I put the fake_volatile label at - * the start of the function just in case something /really/ bad - * happens, and the schedule returns. This way we can try again. I'm - * not paranoid: it's just that everybody is out to get me. - */ - goto fake_volatile; + /* Avoid "noreturn function does return". */ + for (;;) ; } NORET_TYPE void complete_and_exit(struct completion *comp, long code) @@ -701,9 +753,9 @@ struct list_head *tmp, *head = &link->pidptr->task_list; #if CONFIG_SMP - if (!p->sig) + if (!p->sighand) BUG(); - if (!spin_is_locked(&p->sig->siglock) && + if (!spin_is_locked(&p->sighand->siglock) && !rwlock_is_locked(&tasklist_lock)) BUG(); #endif @@ -715,31 +767,45 @@ } /* - * this kills every thread in the thread group. Note that any externally - * wait4()-ing process will get the correct exit code - even if this - * thread is not the thread group leader. + * Take down every thread in the group. This is called by fatal signals + * as well as by sys_exit_group (below). */ -asmlinkage long sys_exit_group(int error_code) +NORET_TYPE void +do_group_exit(int exit_code) { - unsigned int exit_code = (error_code & 0xff) << 8; - - if (!thread_group_empty(current)) { - struct signal_struct *sig = current->sig; + BUG_ON(exit_code & 0x80); /* core dumps don't get here */ - spin_lock_irq(&sig->siglock); - if (sig->group_exit) { - spin_unlock_irq(&sig->siglock); - - /* another thread was faster: */ - do_exit(sig->group_exit_code); + if (current->signal->group_exit) + exit_code = current->signal->group_exit_code; + else if (!thread_group_empty(current)) { + struct signal_struct *const sig = current->signal; + struct sighand_struct *const sighand = current->sighand; + read_lock(&tasklist_lock); + spin_lock_irq(&sighand->siglock); + if (sig->group_exit) + /* Another thread got here before we took the lock. */ + exit_code = sig->group_exit_code; + else { + sig->group_exit = 1; + sig->group_exit_code = exit_code; + zap_other_threads(current); } - sig->group_exit = 1; - sig->group_exit_code = exit_code; - __broadcast_thread_group(current, SIGKILL); - spin_unlock_irq(&sig->siglock); + spin_unlock_irq(&sighand->siglock); + read_unlock(&tasklist_lock); } do_exit(exit_code); + /* NOTREACHED */ +} + +/* + * this kills every thread in the thread group. Note that any externally + * wait4()-ing process will get the correct exit code - even if this + * thread is not the thread group leader. + */ +asmlinkage void sys_exit_group(int error_code) +{ + do_group_exit((error_code & 0xff) << 8); } static int eligible_child(pid_t pid, int options, task_t *p) @@ -783,11 +849,149 @@ return 1; } +/* + * Handle sys_wait4 work for one task in state TASK_ZOMBIE. We hold + * read_lock(&tasklist_lock) on entry. If we return zero, we still hold + * the lock and this task is uninteresting. If we return nonzero, we have + * released the lock and the system call should return. + */ +static int wait_task_zombie(task_t *p, unsigned int *stat_addr, struct rusage *ru) +{ + unsigned long state; + int retval; + + /* + * Try to move the task's state to DEAD + * only one thread is allowed to do this: + */ + state = xchg(&p->state, TASK_DEAD); + if (state != TASK_ZOMBIE) { + BUG_ON(state != TASK_DEAD); + return 0; + } + if (unlikely(p->exit_signal == -1)) + /* + * This can only happen in a race with a ptraced thread + * dying on another processor. + */ + return 0; + + /* + * Now we are sure this task is interesting, and no other + * thread can reap it because we set its state to TASK_DEAD. + */ + read_unlock(&tasklist_lock); + + retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; + if (!retval && stat_addr) { + if (p->signal->group_exit) + retval = put_user(p->signal->group_exit_code, stat_addr); + else + retval = put_user(p->exit_code, stat_addr); + } + if (retval) { + p->state = TASK_ZOMBIE; + return retval; + } + retval = p->pid; + if (p->real_parent != p->parent) { + write_lock_irq(&tasklist_lock); + /* Double-check with lock held. */ + if (p->real_parent != p->parent) { + __ptrace_unlink(p); + do_notify_parent(p, p->exit_signal); + p->state = TASK_ZOMBIE; + p = NULL; + } + write_unlock_irq(&tasklist_lock); + } + if (p != NULL) + release_task(p); + BUG_ON(!retval); + return retval; +} + +/* + * Handle sys_wait4 work for one task in state TASK_STOPPED. We hold + * read_lock(&tasklist_lock) on entry. If we return zero, we still hold + * the lock and this task is uninteresting. If we return nonzero, we have + * released the lock and the system call should return. + */ +static int wait_task_stopped(task_t *p, int delayed_group_leader, + unsigned int *stat_addr, struct rusage *ru) +{ + int retval, exit_code; + + if (!p->exit_code) + return 0; + if (delayed_group_leader && !(p->ptrace & PT_PTRACED) && + p->signal && p->signal->group_stop_count > 0) + /* + * A group stop is in progress and this is the group leader. + * We won't report until all threads have stopped. + */ + return 0; + + /* + * Now we are pretty sure this task is interesting. + * Make sure it doesn't get reaped out from under us while we + * give up the lock and then examine it below. We don't want to + * keep holding onto the tasklist_lock while we call getrusage and + * possibly take page faults for user memory. + */ + get_task_struct(p); + read_unlock(&tasklist_lock); + write_lock_irq(&tasklist_lock); + + /* + * This uses xchg to be atomic with the thread resuming and setting + * it. It must also be done with the write lock held to prevent a + * race with the TASK_ZOMBIE case. + */ + exit_code = xchg(&p->exit_code, 0); + if (unlikely(p->state > TASK_STOPPED)) { + /* + * The task resumed and then died. Let the next iteration + * catch it in TASK_ZOMBIE. Note that exit_code might + * already be zero here if it resumed and did _exit(0). + * The task itself is dead and won't touch exit_code again; + * other processors in this function are locked out. + */ + p->exit_code = exit_code; + exit_code = 0; + } + if (unlikely(exit_code == 0)) { + /* + * Another thread in this function got to it first, or it + * resumed, or it resumed and then died. + */ + write_unlock_irq(&tasklist_lock); + put_task_struct(p); + read_lock(&tasklist_lock); + return 0; + } + + /* move to end of parent's list to avoid starvation */ + remove_parent(p); + add_parent(p, p->parent); + + write_unlock_irq(&tasklist_lock); + + retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; + if (!retval && stat_addr) + retval = put_user((exit_code << 8) | 0x7f, stat_addr); + if (!retval) + retval = p->pid; + put_task_struct(p); + + BUG_ON(!retval); + return retval; +} + asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru) { DECLARE_WAITQUEUE(wait, current); struct task_struct *tsk; - unsigned long state; int flag, retval; if (options & ~(WNOHANG|WUNTRACED|__WNOTHREAD|__WCLONE|__WALL)) @@ -814,63 +1018,24 @@ switch (p->state) { case TASK_STOPPED: - if (!p->exit_code) - continue; - if (!(options & WUNTRACED) && !(p->ptrace & PT_PTRACED)) + if (!(options & WUNTRACED) && + !(p->ptrace & PT_PTRACED)) continue; - read_unlock(&tasklist_lock); - - /* move to end of parent's list to avoid starvation */ - write_lock_irq(&tasklist_lock); - remove_parent(p); - add_parent(p, p->parent); - write_unlock_irq(&tasklist_lock); - retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; - if (!retval && stat_addr) - retval = put_user((p->exit_code << 8) | 0x7f, stat_addr); - if (!retval) { - p->exit_code = 0; - retval = p->pid; - } - goto end_wait4; + retval = wait_task_stopped(p, ret == 2, + stat_addr, ru); + if (retval != 0) /* He released the lock. */ + goto end_wait4; + break; case TASK_ZOMBIE: /* * Eligible but we cannot release it yet: */ if (ret == 2) continue; - /* - * Try to move the task's state to DEAD - * only one thread is allowed to do this: - */ - state = xchg(&p->state, TASK_DEAD); - if (state != TASK_ZOMBIE) - continue; - read_unlock(&tasklist_lock); - - retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; - if (!retval && stat_addr) { - if (p->sig->group_exit) - retval = put_user(p->sig->group_exit_code, stat_addr); - else - retval = put_user(p->exit_code, stat_addr); - } - if (retval) { - p->state = TASK_ZOMBIE; + retval = wait_task_zombie(p, stat_addr, ru); + if (retval != 0) /* He released the lock. */ goto end_wait4; - } - retval = p->pid; - if (p->real_parent != p->parent) { - write_lock_irq(&tasklist_lock); - __ptrace_unlink(p); - do_notify_parent(p, SIGCHLD); - p->state = TASK_ZOMBIE; - write_unlock_irq(&tasklist_lock); - } else - release_task(p); - goto end_wait4; - default: - continue; + break; } } if (!flag) { @@ -885,7 +1050,7 @@ if (options & __WNOTHREAD) break; tsk = next_thread(tsk); - if (tsk->sig != current->sig) + if (tsk->signal != current->signal) BUG(); } while (tsk != current); read_unlock(&tasklist_lock); diff -Nru a/kernel/fork.c b/kernel/fork.c --- a/kernel/fork.c Sun Feb 9 21:13:29 2003 +++ b/kernel/fork.c Sun Feb 9 21:13:29 2003 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -664,22 +665,39 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk) { - struct signal_struct *sig; + struct sighand_struct *sig; - if (clone_flags & CLONE_SIGHAND) { - atomic_inc(¤t->sig->count); + if (clone_flags & (CLONE_SIGHAND | CLONE_THREAD)) { + atomic_inc(¤t->sighand->count); return 0; } - sig = kmem_cache_alloc(sigact_cachep, GFP_KERNEL); - tsk->sig = sig; + sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL); + tsk->sighand = sig; if (!sig) return -1; spin_lock_init(&sig->siglock); atomic_set(&sig->count, 1); + memcpy(sig->action, current->sighand->action, sizeof(sig->action)); + return 0; +} + +static inline int copy_signal(unsigned long clone_flags, struct task_struct * tsk) +{ + struct signal_struct *sig; + + if (clone_flags & CLONE_THREAD) { + atomic_inc(¤t->signal->count); + return 0; + } + sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); + tsk->signal = sig; + if (!sig) + return -1; + atomic_set(&sig->count, 1); sig->group_exit = 0; sig->group_exit_code = 0; sig->group_exit_task = NULL; - memcpy(sig->action, current->sig->action, sizeof(sig->action)); + sig->group_stop_count = 0; sig->curr_target = NULL; init_sigpending(&sig->shared_pending); @@ -800,7 +818,7 @@ spin_lock_init(&p->alloc_lock); spin_lock_init(&p->switch_lock); - clear_tsk_thread_flag(p,TIF_SIGPENDING); + clear_tsk_thread_flag(p, TIF_SIGPENDING); init_sigpending(&p->pending); p->it_real_value = p->it_virt_value = p->it_prof_value = 0; @@ -814,7 +832,7 @@ p->cutime = p->cstime = 0; p->array = NULL; p->lock_depth = -1; /* -1 = no lock */ - p->start_time = jiffies; + p->start_time = get_jiffies_64(); p->security = NULL; retval = -ENOMEM; @@ -829,8 +847,10 @@ goto bad_fork_cleanup_files; if (copy_sighand(clone_flags, p)) goto bad_fork_cleanup_fs; - if (copy_mm(clone_flags, p)) + if (copy_signal(clone_flags, p)) goto bad_fork_cleanup_sighand; + if (copy_mm(clone_flags, p)) + goto bad_fork_cleanup_signal; if (copy_namespace(clone_flags, p)) goto bad_fork_cleanup_mm; retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); @@ -909,6 +929,7 @@ */ if (sigismember(¤t->pending.signal, SIGKILL)) { write_unlock_irq(&tasklist_lock); + retval = -EINTR; goto bad_fork_cleanup_namespace; } @@ -920,20 +941,31 @@ p->parent = p->real_parent; if (clone_flags & CLONE_THREAD) { - spin_lock(¤t->sig->siglock); + spin_lock(¤t->sighand->siglock); /* * Important: if an exit-all has been started then * do not create this new thread - the whole thread * group is supposed to exit anyway. */ - if (current->sig->group_exit) { - spin_unlock(¤t->sig->siglock); + if (current->signal->group_exit) { + spin_unlock(¤t->sighand->siglock); write_unlock_irq(&tasklist_lock); goto bad_fork_cleanup_namespace; } p->tgid = current->tgid; p->group_leader = current->group_leader; - spin_unlock(¤t->sig->siglock); + + if (current->signal->group_stop_count > 0) { + /* + * There is an all-stop in progress for the group. + * We ourselves will stop as soon as we check signals. + * Make the new thread part of that group stop too. + */ + current->signal->group_stop_count++; + set_tsk_thread_flag(p, TIF_SIGPENDING); + } + + spin_unlock(¤t->sighand->siglock); } SET_LINKS(p); @@ -963,6 +995,8 @@ exit_namespace(p); bad_fork_cleanup_mm: exit_mm(p); +bad_fork_cleanup_signal: + exit_signal(p); bad_fork_cleanup_sighand: exit_sighand(p); bad_fork_cleanup_fs: @@ -1035,8 +1069,13 @@ init_completion(&vfork); } - if (p->ptrace & PT_PTRACED) - send_sig(SIGSTOP, p, 1); + if (p->ptrace & PT_PTRACED) { + /* + * We'll start up with an immediate SIGSTOP. + */ + sigaddset(&p->pending.signal, SIGSTOP); + set_tsk_thread_flag(p, TIF_SIGPENDING); + } wake_up_forked_process(p); /* do this last */ ++total_forks; @@ -1046,9 +1085,11 @@ ptrace_notify ((trace << 8) | SIGTRAP); } - if (clone_flags & CLONE_VFORK) + if (clone_flags & CLONE_VFORK) { wait_for_completion(&vfork); - else + if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) + ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP); + } else /* * Let the child process run first, to avoid most of the * COW overhead when the child exec()s afterwards. @@ -1058,8 +1099,11 @@ return p; } -/* SLAB cache for signal_struct structures (tsk->sig) */ -kmem_cache_t *sigact_cachep; +/* SLAB cache for signal_struct structures (tsk->signal) */ +kmem_cache_t *signal_cachep; + +/* SLAB cache for sighand_struct structures (tsk->sighand) */ +kmem_cache_t *sighand_cachep; /* SLAB cache for files_struct structures (tsk->files) */ kmem_cache_t *files_cachep; @@ -1075,11 +1119,17 @@ void __init proc_caches_init(void) { - sigact_cachep = kmem_cache_create("signal_act", + sighand_cachep = kmem_cache_create("sighand_cache", + sizeof(struct sighand_struct), 0, + SLAB_HWCACHE_ALIGN, NULL, NULL); + if (!sighand_cachep) + panic("Cannot create sighand SLAB cache"); + + signal_cachep = kmem_cache_create("signal_cache", sizeof(struct signal_struct), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - if (!sigact_cachep) - panic("Cannot create signal action SLAB cache"); + if (!signal_cachep) + panic("Cannot create signal SLAB cache"); files_cachep = kmem_cache_create("files_cache", sizeof(struct files_struct), 0, diff -Nru a/kernel/kmod.c b/kernel/kmod.c --- a/kernel/kmod.c Sun Feb 9 21:13:30 2003 +++ b/kernel/kmod.c Sun Feb 9 21:13:30 2003 @@ -100,8 +100,7 @@ int i; struct task_struct *curtask = current; - curtask->session = 1; - curtask->pgrp = 1; + set_special_pids(1, 1); use_init_fs_context(); @@ -111,12 +110,12 @@ as the super user right after the execve fails if you time the signal just right. */ - spin_lock_irq(&curtask->sig->siglock); + spin_lock_irq(&curtask->sighand->siglock); sigemptyset(&curtask->blocked); flush_signals(curtask); flush_signal_handlers(curtask); recalc_sigpending(); - spin_unlock_irq(&curtask->sig->siglock); + spin_unlock_irq(&curtask->sighand->siglock); for (i = 0; i < curtask->files->max_fds; i++ ) { if (curtask->files->fd[i]) close(i); @@ -239,20 +238,20 @@ } /* Block everything but SIGKILL/SIGSTOP */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); tmpsig = current->blocked; siginitsetinv(¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP)); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); waitpid_result = waitpid(pid, NULL, __WCLONE); atomic_dec(&kmod_concurrent); /* Allow signals again.. */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = tmpsig; recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (waitpid_result != pid) { printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n", diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c --- a/kernel/ksyms.c Sun Feb 9 21:13:28 2003 +++ b/kernel/ksyms.c Sun Feb 9 21:13:28 2003 @@ -55,6 +55,7 @@ #include #include #include +#include #include #if defined(CONFIG_PROC_FS) @@ -68,13 +69,6 @@ extern int panic_timeout; -#ifdef CONFIG_MODVERSIONS -const struct module_symbol __export_Using_Versions -__attribute__((section("__ksymtab"))) = { - 1 /* Version version */, "Using_Versions" -}; -#endif - /* process memory management */ EXPORT_SYMBOL(do_mmap_pgoff); EXPORT_SYMBOL(do_munmap); @@ -272,6 +266,10 @@ EXPORT_SYMBOL(vfs_stat); EXPORT_SYMBOL(vfs_lstat); EXPORT_SYMBOL(vfs_getattr); +EXPORT_SYMBOL(inode_add_bytes); +EXPORT_SYMBOL(inode_sub_bytes); +EXPORT_SYMBOL(inode_get_bytes); +EXPORT_SYMBOL(inode_set_bytes); EXPORT_SYMBOL(lock_rename); EXPORT_SYMBOL(unlock_rename); EXPORT_SYMBOL(generic_read_dir); @@ -488,6 +486,7 @@ EXPORT_SYMBOL(jiffies); EXPORT_SYMBOL(jiffies_64); EXPORT_SYMBOL(xtime); +EXPORT_SYMBOL(xtime_lock); EXPORT_SYMBOL(do_gettimeofday); EXPORT_SYMBOL(do_settimeofday); #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP diff -Nru a/kernel/module.c b/kernel/module.c --- a/kernel/module.c Sun Feb 9 21:13:34 2003 +++ b/kernel/module.c Sun Feb 9 21:13:34 2003 @@ -78,6 +78,7 @@ /* Find a symbol, return value and the symbol group */ static unsigned long __find_symbol(const char *name, struct kernel_symbol_group **group, + unsigned int *symidx, int gplok) { struct kernel_symbol_group *ks; @@ -90,6 +91,8 @@ for (i = 0; i < ks->num_syms; i++) { if (strcmp(ks->syms[i].name, name) == 0) { *group = ks; + if (symidx) + *symidx = i; return ks->syms[i].value; } } @@ -520,7 +523,7 @@ unsigned long flags; spin_lock_irqsave(&modlist_lock, flags); - if (!__find_symbol(symbol, &ksg, 1)) + if (!__find_symbol(symbol, &ksg, NULL, 1)) BUG(); module_put(ksg->owner); spin_unlock_irqrestore(&modlist_lock, flags); @@ -722,22 +725,91 @@ } #endif /* CONFIG_OBSOLETE_MODPARM */ +#ifdef CONFIG_MODVERSIONS +static int check_version(Elf_Shdr *sechdrs, + unsigned int versindex, + const char *symname, + struct module *mod, + struct kernel_symbol_group *ksg, + unsigned int symidx) +{ + unsigned long crc; + unsigned int i, num_versions; + struct modversion_info *versions; + + /* Exporting module didn't supply crcs? OK, we're already tainted. */ + if (!ksg->crcs) + return 1; + + crc = ksg->crcs[symidx]; + + versions = (void *) sechdrs[versindex].sh_addr; + num_versions = sechdrs[versindex].sh_size + / sizeof(struct modversion_info); + + for (i = 0; i < num_versions; i++) { + if (strcmp(versions[i].name, symname) != 0) + continue; + + if (versions[i].crc == crc) + return 1; + printk("%s: disagrees about version of symbol %s\n", + mod->name, symname); + DEBUGP("Found checksum %lX vs module %lX\n", + crc, versions[i].crc); + return 0; + } + /* Not in module's version table. OK, but that taints the kernel. */ + if (!(tainted & TAINT_FORCED_MODULE)) { + printk("%s: no version for \"%s\" found: kernel tainted.\n", + mod->name, symname); + tainted |= TAINT_FORCED_MODULE; + } + return 1; +} + +/* First part is kernel version, which we ignore. */ +static inline int same_magic(const char *amagic, const char *bmagic) +{ + amagic += strcspn(amagic, " "); + bmagic += strcspn(bmagic, " "); + return strcmp(amagic, bmagic) == 0; +} +#else +static inline int check_version(Elf_Shdr *sechdrs, + unsigned int versindex, + const char *symname, + struct module *mod, + struct kernel_symbol_group *ksg, + unsigned int symidx) +{ + return 1; +} + +static inline int same_magic(const char *amagic, const char *bmagic) +{ + return strcmp(amagic, bmagic) == 0; +} +#endif /* CONFIG_MODVERSIONS */ + /* Resolve a symbol for this module. I.e. if we find one, record usage. Must be holding module_mutex. */ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, - unsigned int symindex, - const char *strtab, + unsigned int versindex, const char *name, struct module *mod) { struct kernel_symbol_group *ksg; unsigned long ret; + unsigned int symidx; spin_lock_irq(&modlist_lock); - ret = __find_symbol(name, &ksg, mod->license_gplok); + ret = __find_symbol(name, &ksg, &symidx, mod->license_gplok); if (ret) { - /* This can fail due to OOM, or module unloading */ - if (!use_module(mod, ksg->owner)) + /* use_module can fail due to OOM, or module unloading */ + if (!check_version(sechdrs, versindex, name, mod, + ksg, symidx) || + !use_module(mod, ksg->owner)) ret = 0; } spin_unlock_irq(&modlist_lock); @@ -772,7 +844,7 @@ unsigned long value, flags; spin_lock_irqsave(&modlist_lock, flags); - value = __find_symbol(symbol, &ksg, 1); + value = __find_symbol(symbol, &ksg, NULL, 1); if (value && !strong_try_module_get(ksg->owner)) value = 0; spin_unlock_irqrestore(&modlist_lock, flags); @@ -824,6 +896,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs, unsigned int symindex, unsigned int strindex, + unsigned int versindex, struct module *mod) { Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; @@ -848,7 +921,7 @@ case SHN_UNDEF: sym[i].st_value - = resolve_symbol(sechdrs, symindex, strtab, + = resolve_symbol(sechdrs, versindex, strtab + sym[i].st_name, mod); /* Ok if resolved. */ @@ -916,7 +989,7 @@ || strstr(secstrings + s->sh_name, ".init")) continue; s->sh_entsize = get_offset(&mod->core_size, s); - DEBUGP("\t%s\n", name); + DEBUGP("\t%s\n", secstrings + s->sh_name); } } @@ -932,7 +1005,7 @@ continue; s->sh_entsize = (get_offset(&mod->init_size, s) | INIT_OFFSET_MASK); - DEBUGP("\t%s\n", name); + DEBUGP("\t%s\n", secstrings + s->sh_name); } } } @@ -976,7 +1049,8 @@ Elf_Shdr *sechdrs; char *secstrings, *args; unsigned int i, symindex, exportindex, strindex, setupindex, exindex, - modindex, obsparmindex, licenseindex, gplindex, vmagindex; + modindex, obsparmindex, licenseindex, gplindex, vmagindex, + crcindex, gplcrcindex, versindex; long arglen; struct module *mod; long err = 0; @@ -1012,7 +1086,8 @@ /* May not export symbols, or have setup params, so these may not exist */ - exportindex = setupindex = obsparmindex = gplindex = licenseindex = 0; + exportindex = setupindex = obsparmindex = gplindex = licenseindex + = crcindex = gplcrcindex = versindex = 0; /* And these should exist, but gcc whinges if we don't init them */ symindex = strindex = exindex = modindex = vmagindex = 0; @@ -1040,6 +1115,21 @@ /* Exported symbols. */ DEBUGP("EXPORT table in section %u\n", i); exportindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, + "__ksymtab_gpl") == 0) { + /* Exported symbols. (GPL) */ + DEBUGP("GPL symbols found in section %u\n", i); + gplindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, "__kcrctab") + == 0) { + /* Exported symbols CRCs. */ + DEBUGP("CRC table in section %u\n", i); + crcindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, "__kcrctab_gpl") + == 0) { + /* Exported symbols CRCs. (GPL)*/ + DEBUGP("CRC table in section %u\n", i); + gplcrcindex = i; } else if (strcmp(secstrings+sechdrs[i].sh_name, "__param") == 0) { /* Setup parameter info */ @@ -1060,16 +1150,21 @@ /* MODULE_LICENSE() */ DEBUGP("Licence found in section %u\n", i); licenseindex = i; + sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC; } else if (strcmp(secstrings+sechdrs[i].sh_name, - "__gpl_ksymtab") == 0) { - /* EXPORT_SYMBOL_GPL() */ - DEBUGP("GPL symbols found in section %u\n", i); - gplindex = i; - } else if (strcmp(secstrings+sechdrs[i].sh_name, - "__vermagic") == 0) { + "__vermagic") == 0 && + (sechdrs[i].sh_flags & SHF_ALLOC)) { /* Version magic. */ DEBUGP("Version magic found in section %u\n", i); vmagindex = i; + sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC; + } else if (strcmp(secstrings+sechdrs[i].sh_name, + "__versions") == 0 && + (sechdrs[i].sh_flags & SHF_ALLOC)) { + /* Module version info (both exported and needed) */ + DEBUGP("Versions found in section %u\n", i); + versindex = i; + sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC; } #ifdef CONFIG_KALLSYMS /* symbol and string tables for decoding later. */ @@ -1090,12 +1185,12 @@ } mod = (void *)sechdrs[modindex].sh_addr; - /* This is allowed: modprobe --force will strip it. */ + /* This is allowed: modprobe --force will invalidate it. */ if (!vmagindex) { tainted |= TAINT_FORCED_MODULE; printk(KERN_WARNING "%s: no version magic, tainting kernel.\n", mod->name); - } else if (strcmp((char *)sechdrs[vmagindex].sh_addr, vermagic) != 0) { + } else if (!same_magic((char *)sechdrs[vmagindex].sh_addr, vermagic)) { printk(KERN_ERR "%s: version magic '%s' should be '%s'\n", mod->name, (char*)sechdrs[vmagindex].sh_addr, vermagic); err = -ENOEXEC; @@ -1181,7 +1276,7 @@ set_license(mod, sechdrs, licenseindex); /* Fix up syms, so that st_value is a pointer to location. */ - err = simplify_symbols(sechdrs, symindex, strindex, mod); + err = simplify_symbols(sechdrs, symindex, strindex, versindex, mod); if (err < 0) goto cleanup; @@ -1189,9 +1284,23 @@ mod->symbols.num_syms = (sechdrs[exportindex].sh_size / sizeof(*mod->symbols.syms)); mod->symbols.syms = (void *)sechdrs[exportindex].sh_addr; + if (crcindex) + mod->symbols.crcs = (void *)sechdrs[crcindex].sh_addr; + mod->gpl_symbols.num_syms = (sechdrs[gplindex].sh_size / sizeof(*mod->symbols.syms)); mod->gpl_symbols.syms = (void *)sechdrs[gplindex].sh_addr; + if (gplcrcindex) + mod->gpl_symbols.crcs = (void *)sechdrs[gplcrcindex].sh_addr; + +#ifdef CONFIG_MODVERSIONS + if ((mod->symbols.num_syms && !crcindex) + || (mod->gpl_symbols.num_syms && !gplcrcindex)) { + printk(KERN_WARNING "%s: No versions for exported symbols." + " Tainting kernel.\n", mod->name); + tainted |= TAINT_FORCED_MODULE; + } +#endif /* Set up exception table */ if (exindex) { @@ -1442,7 +1551,7 @@ return 0; } -/* Format: modulename size refcount deps +/* Format: modulename size refcount deps address Where refcount is a number or -, and deps is a comma-separated list of depends or -. @@ -1492,8 +1601,12 @@ /* Provided by the linker */ extern const struct kernel_symbol __start___ksymtab[]; extern const struct kernel_symbol __stop___ksymtab[]; -extern const struct kernel_symbol __start___gpl_ksymtab[]; -extern const struct kernel_symbol __stop___gpl_ksymtab[]; +extern const struct kernel_symbol __start___ksymtab_gpl[]; +extern const struct kernel_symbol __stop___ksymtab_gpl[]; +extern const unsigned long __start___kcrctab[]; +extern const unsigned long __stop___kcrctab[]; +extern const unsigned long __start___kcrctab_gpl[]; +extern const unsigned long __stop___kcrctab_gpl[]; static struct kernel_symbol_group kernel_symbols, kernel_gpl_symbols; @@ -1502,11 +1615,14 @@ /* Add kernel symbols to symbol table */ kernel_symbols.num_syms = (__stop___ksymtab - __start___ksymtab); kernel_symbols.syms = __start___ksymtab; + kernel_symbols.crcs = __start___kcrctab; kernel_symbols.gplonly = 0; list_add(&kernel_symbols.list, &symbols); - kernel_gpl_symbols.num_syms = (__stop___gpl_ksymtab - - __start___gpl_ksymtab); - kernel_gpl_symbols.syms = __start___gpl_ksymtab; + + kernel_gpl_symbols.num_syms = (__stop___ksymtab_gpl + - __start___ksymtab_gpl); + kernel_gpl_symbols.syms = __start___ksymtab_gpl; + kernel_gpl_symbols.crcs = __start___kcrctab_gpl; kernel_gpl_symbols.gplonly = 1; list_add(&kernel_gpl_symbols.list, &symbols); diff -Nru a/kernel/params.c b/kernel/params.c --- a/kernel/params.c Sun Feb 9 21:13:35 2003 +++ b/kernel/params.c Sun Feb 9 21:13:35 2003 @@ -27,6 +27,22 @@ #define DEBUGP(fmt, a...) #endif +static inline int dash2underscore(char c) +{ + if (c == '-') + return '_'; + return c; +} + +static inline int parameq(const char *input, const char *paramname) +{ + unsigned int i; + for (i = 0; dash2underscore(input[i]) == paramname[i]; i++) + if (input[i] == '\0') + return 1; + return 0; +} + static int parse_one(char *param, char *val, struct kernel_param *params, @@ -37,7 +53,7 @@ /* Find parameter */ for (i = 0; i < num_params; i++) { - if (strcmp(param, params[i].name) == 0) { + if (parameq(param, params[i].name)) { DEBUGP("They are equal! Calling %p\n", params[i].set); return params[i].set(val, ¶ms[i]); @@ -69,8 +85,6 @@ if (equals == 0) { if (args[i] == '=') equals = i; - else if (args[i] == '-') - args[i] = '_'; } if (args[i] == '"') in_quote = !in_quote; diff -Nru a/kernel/printk.c b/kernel/printk.c --- a/kernel/printk.c Sun Feb 9 21:13:37 2003 +++ b/kernel/printk.c Sun Feb 9 21:13:37 2003 @@ -243,19 +243,13 @@ break; case 5: /* Clear ring buffer */ - spin_lock_irq(&logbuf_lock); logged_chars = 0; - spin_unlock_irq(&logbuf_lock); break; case 6: /* Disable logging to console */ - spin_lock_irq(&logbuf_lock); console_loglevel = minimum_console_loglevel; - spin_unlock_irq(&logbuf_lock); break; case 7: /* Enable logging to console */ - spin_lock_irq(&logbuf_lock); console_loglevel = default_console_loglevel; - spin_unlock_irq(&logbuf_lock); break; case 8: /* Set level of messages printed to console */ error = -EINVAL; @@ -263,15 +257,11 @@ goto out; if (len < minimum_console_loglevel) len = minimum_console_loglevel; - spin_lock_irq(&logbuf_lock); console_loglevel = len; - spin_unlock_irq(&logbuf_lock); error = 0; break; case 9: /* Number of chars in the log buffer */ - spin_lock_irq(&logbuf_lock); error = log_end - log_start; - spin_unlock_irq(&logbuf_lock); break; default: error = -EINVAL; diff -Nru a/kernel/ptrace.c b/kernel/ptrace.c --- a/kernel/ptrace.c Sun Feb 9 21:13:37 2003 +++ b/kernel/ptrace.c Sun Feb 9 21:13:37 2003 @@ -277,15 +277,43 @@ else child->ptrace &= ~PT_TRACE_EXEC; + if (data & PTRACE_O_TRACEVFORKDONE) + child->ptrace |= PT_TRACE_VFORK_DONE; + else + child->ptrace &= ~PT_TRACE_VFORK_DONE; + + if (data & PTRACE_O_TRACEEXIT) + child->ptrace |= PT_TRACE_EXIT; + else + child->ptrace &= ~PT_TRACE_EXIT; + if ((data & (PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE - | PTRACE_O_TRACEEXEC)) + | PTRACE_O_TRACEEXEC | PTRACE_O_TRACEEXIT + | PTRACE_O_TRACEVFORKDONE)) != data) return -EINVAL; return 0; } +static int ptrace_getsiginfo(struct task_struct *child, long data) +{ + if (child->last_siginfo == NULL) + return -EINVAL; + return copy_siginfo_to_user ((siginfo_t *) data, child->last_siginfo); +} + +static int ptrace_setsiginfo(struct task_struct *child, long data) +{ + if (child->last_siginfo == NULL) + return -EINVAL; + if (copy_from_user (child->last_siginfo, (siginfo_t *) data, + sizeof (siginfo_t)) != 0) + return -EFAULT; + return 0; +} + int ptrace_request(struct task_struct *child, long request, long addr, long data) { @@ -300,6 +328,12 @@ break; case PTRACE_GETEVENTMSG: ret = put_user(child->ptrace_message, (unsigned long *) data); + break; + case PTRACE_GETSIGINFO: + ret = ptrace_getsiginfo(child, data); + break; + case PTRACE_SETSIGINFO: + ret = ptrace_setsiginfo(child, data); break; default: break; diff -Nru a/kernel/sched.c b/kernel/sched.c --- a/kernel/sched.c Sun Feb 9 21:13:35 2003 +++ b/kernel/sched.c Sun Feb 9 21:13:35 2003 @@ -213,7 +213,7 @@ int i; for (i = 0; i < NR_CPUS; i++) - cpu_rq(i)->node_nr_running = &node_nr_running[__cpu_to_node(i)]; + cpu_rq(i)->node_nr_running = &node_nr_running[cpu_to_node(i)]; } #else /* !CONFIG_NUMA */ @@ -715,7 +715,7 @@ } minload = 10000000; - cpumask = __node_to_cpu_mask(node); + cpumask = node_to_cpumask(node); for (i = 0; i < NR_CPUS; ++i) { if (!(cpumask & (1UL << i))) continue; @@ -767,7 +767,7 @@ static inline unsigned long cpus_to_balance(int this_cpu, runqueue_t *this_rq) { - int this_node = __cpu_to_node(this_cpu); + int this_node = cpu_to_node(this_cpu); /* * Avoid rebalancing between nodes too often. * We rebalance globally once every NODE_BALANCE_RATE load balances. @@ -776,9 +776,9 @@ int node = find_busiest_node(this_node); this_rq->nr_balanced = 0; if (node >= 0) - return (__node_to_cpu_mask(node) | (1UL << this_cpu)); + return (node_to_cpumask(node) | (1UL << this_cpu)); } - return __node_to_cpu_mask(this_node); + return node_to_cpumask(this_node); } #else /* !CONFIG_NUMA */ @@ -2037,7 +2037,7 @@ unsigned long free = 0; task_t *relative; int state; - static const char * stat_nam[] = { "R", "S", "D", "Z", "T", "W" }; + static const char * stat_nam[] = { "R", "S", "D", "T", "Z", "W" }; printk("%-13.13s ", p->comm); state = p->state ? __ffs(p->state) + 1 : 0; @@ -2057,7 +2057,7 @@ printk(" %016lx ", thread_saved_pc(p)); #endif { - unsigned long * n = (unsigned long *) (p+1); + unsigned long * n = (unsigned long *) (p->thread_info+1); while (!*n) n++; free = (unsigned long) n - (unsigned long)(p+1); @@ -2465,15 +2465,12 @@ _raw_spin_lock(lock); return; } - - while (!_raw_spin_trylock(lock)) { - if (need_resched()) { - preempt_enable_no_resched(); - __cond_resched(); - preempt_disable(); - } - cpu_relax(); - } + do { + preempt_enable(); + while (spin_is_locked(lock)) + cpu_relax(); + preempt_disable(); + } while (!_raw_spin_trylock(lock)); } void __preempt_write_lock(rwlock_t *lock) @@ -2483,13 +2480,11 @@ return; } - while (!_raw_write_trylock(lock)) { - if (need_resched()) { - preempt_enable_no_resched(); - __cond_resched(); - preempt_disable(); - } - cpu_relax(); - } + do { + preempt_enable(); + while (rwlock_is_locked(lock)) + cpu_relax(); + preempt_disable(); + } while (!_raw_write_trylock(lock)); } #endif diff -Nru a/kernel/signal.c b/kernel/signal.c --- a/kernel/signal.c Sun Feb 9 21:13:31 2003 +++ b/kernel/signal.c Sun Feb 9 21:13:31 2003 @@ -55,7 +55,7 @@ | SIGALRM | load-balance | kill-all | | SIGTERM | load-balance | kill-all | | SIGCHLD | load-balance | ignore | -| SIGCONT | specific | continue-all | +| SIGCONT | load-balance | ignore | | SIGSTOP | n/a | stop-all | | SIGTSTP | load-balance | stop-all | | SIGTTIN | load-balance | stop-all | @@ -98,26 +98,11 @@ #endif #if SIGRTMIN > BITS_PER_LONG -#define M(sig) (1ULL << (sig)) +#define M(sig) (1ULL << ((sig)-1)) #else -#define M(sig) (1UL << (sig)) +#define M(sig) (1UL << ((sig)-1)) #endif -#define T(sig, mask) (M(sig) & mask) - -#define SIG_USER_SPECIFIC_MASK (\ - M(SIGILL) | M(SIGTRAP) | M(SIGABRT) | M(SIGBUS) | \ - M(SIGFPE) | M(SIGSEGV) | M(SIGPIPE) | M(SIGXFSZ) | \ - M(SIGPROF) | M(SIGSYS) | M_SIGSTKFLT | M(SIGCONT) | \ - M_SIGEMT ) - -#define SIG_USER_LOAD_BALANCE_MASK (\ - M(SIGHUP) | M(SIGINT) | M(SIGQUIT) | M(SIGUSR1) | \ - M(SIGUSR2) | M(SIGALRM) | M(SIGTERM) | M(SIGCHLD) | \ - M(SIGURG) | M(SIGVTALRM) | M(SIGPOLL) | M(SIGWINCH) | \ - M(SIGPWR) | M(SIGTSTP) | M(SIGTTIN) | M(SIGTTOU) ) - -#define SIG_KERNEL_SPECIFIC_MASK (\ - M(SIGCHLD) | M(SIGURG) | M(SIGWINCH) ) +#define T(sig, mask) (M(sig) & (mask)) #define SIG_KERNEL_BROADCAST_MASK (\ M(SIGHUP) | M(SIGINT) | M(SIGQUIT) | M(SIGILL) | \ @@ -132,34 +117,37 @@ #define SIG_KERNEL_ONLY_MASK (\ M(SIGKILL) | M(SIGSTOP) ) +#define SIG_KERNEL_STOP_MASK (\ + M(SIGSTOP) | M(SIGTSTP) | M(SIGTTIN) | M(SIGTTOU) ) + #define SIG_KERNEL_COREDUMP_MASK (\ M(SIGQUIT) | M(SIGILL) | M(SIGTRAP) | M(SIGABRT) | \ M(SIGFPE) | M(SIGSEGV) | M(SIGBUS) | M(SIGSYS) | \ M(SIGXCPU) | M(SIGXFSZ) | M_SIGEMT ) -#define sig_user_specific(sig) \ - (((sig) < SIGRTMIN) && T(sig, SIG_USER_SPECIFIC_MASK)) -#define sig_user_load_balance(sig) \ - (((sig) >= SIGRTMIN) || T(sig, SIG_USER_LOAD_BALANCE_MASK)) -#define sig_kernel_specific(sig) \ - (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_SPECIFIC_MASK)) -#define sig_kernel_broadcast(sig) \ - (((sig) >= SIGRTMIN) || T(sig, SIG_KERNEL_BROADCAST_MASK)) +#define SIG_KERNEL_IGNORE_MASK (\ + M(SIGCONT) | M(SIGCHLD) | M(SIGWINCH) | M(SIGURG) ) + #define sig_kernel_only(sig) \ (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_ONLY_MASK)) #define sig_kernel_coredump(sig) \ (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_COREDUMP_MASK)) - -#define sig_user_defined(t, sig) \ - (((t)->sig->action[(sig)-1].sa.sa_handler != SIG_DFL) && \ - ((t)->sig->action[(sig)-1].sa.sa_handler != SIG_IGN)) - -#define sig_ignored(t, sig) \ - (((sig) != SIGCHLD) && \ - ((t)->sig->action[(sig)-1].sa.sa_handler == SIG_IGN)) - -static int -__send_sig_info(int sig, struct siginfo *info, struct task_struct *p); +#define sig_kernel_ignore(sig) \ + (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_IGNORE_MASK)) +#define sig_kernel_stop(sig) \ + (((sig) < SIGRTMIN) && T(sig, SIG_KERNEL_STOP_MASK)) + +#define sig_user_defined(t, signr) \ + (((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) /* * Re-calculate pending state from the set of locally pending @@ -193,10 +181,11 @@ #define PENDING(p,b) has_pending_signals(&(p)->signal, (b)) -void recalc_sigpending_tsk(struct task_struct *t) +inline void recalc_sigpending_tsk(struct task_struct *t) { - if (PENDING(&t->pending, &t->blocked) || - PENDING(&t->sig->shared_pending, &t->blocked)) + if (t->signal->group_stop_count > 0 || + PENDING(&t->pending, &t->blocked) || + PENDING(&t->signal->shared_pending, &t->blocked)) set_tsk_thread_flag(t, TIF_SIGPENDING); else clear_tsk_thread_flag(t, TIF_SIGPENDING); @@ -204,11 +193,7 @@ void recalc_sigpending(void) { - if (PENDING(¤t->pending, ¤t->blocked) || - PENDING(¤t->sig->shared_pending, ¤t->blocked)) - set_thread_flag(TIF_SIGPENDING); - else - clear_thread_flag(TIF_SIGPENDING); + recalc_sigpending_tsk(current); } /* Given the mask, find the first available signal that should be serviced. */ @@ -280,20 +265,41 @@ */ void __exit_sighand(struct task_struct *tsk) { - struct signal_struct * sig = tsk->sig; + struct sighand_struct * sighand = tsk->sighand; + + /* Ok, we're done with the signal handlers */ + tsk->sighand = NULL; + if (atomic_dec_and_test(&sighand->count)) + kmem_cache_free(sighand_cachep, sighand); +} + +void exit_sighand(struct task_struct *tsk) +{ + write_lock_irq(&tasklist_lock); + __exit_sighand(tsk); + write_unlock_irq(&tasklist_lock); +} + +/* + * This function expects the tasklist_lock write-locked. + */ +void __exit_signal(struct task_struct *tsk) +{ + struct signal_struct * sig = tsk->signal; + struct sighand_struct * sighand = tsk->sighand; if (!sig) BUG(); if (!atomic_read(&sig->count)) BUG(); - spin_lock(&sig->siglock); + spin_lock(&sighand->siglock); if (atomic_dec_and_test(&sig->count)) { if (tsk == sig->curr_target) sig->curr_target = next_thread(tsk); - tsk->sig = NULL; - spin_unlock(&sig->siglock); + tsk->signal = NULL; + spin_unlock(&sighand->siglock); flush_sigqueue(&sig->shared_pending); - kmem_cache_free(sigact_cachep, sig); + kmem_cache_free(signal_cachep, sig); } else { /* * If there is any task waiting for the group exit @@ -305,17 +311,17 @@ } if (tsk == sig->curr_target) sig->curr_target = next_thread(tsk); - tsk->sig = NULL; - spin_unlock(&sig->siglock); + tsk->signal = NULL; + spin_unlock(&sighand->siglock); } clear_tsk_thread_flag(tsk,TIF_SIGPENDING); flush_sigqueue(&tsk->pending); } -void exit_sighand(struct task_struct *tsk) +void exit_signal(struct task_struct *tsk) { write_lock_irq(&tasklist_lock); - __exit_sighand(tsk); + __exit_signal(tsk); write_unlock_irq(&tasklist_lock); } @@ -327,7 +333,7 @@ flush_signal_handlers(struct task_struct *t) { int i; - struct k_sigaction *ka = &t->sig->action[0]; + struct k_sigaction *ka = &t->sighand->action[0]; for (i = _NSIG ; i != 0 ; i--) { if (ka->sa.sa_handler != SIG_IGN) ka->sa.sa_handler = SIG_DFL; @@ -337,23 +343,6 @@ } } -/* - * sig_exit - cause the current task to exit due to a signal. - */ - -void -sig_exit(int sig, int exit_code, struct siginfo *info) -{ - sigaddset(¤t->pending.signal, sig); - recalc_sigpending(); - current->flags |= PF_SIGNALED; - - if (current->sig->group_exit) - exit_code = current->sig->group_exit_code; - - do_exit(exit_code); - /* NOTREACHED */ -} /* Notify the system that a driver wants to block all signals for this * process, and wants to be notified if any signals at all were to be @@ -368,11 +357,11 @@ { unsigned long flags; - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); current->notifier_mask = mask; current->notifier_data = priv; current->notifier = notifier; - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); } /* Notify the system that blocking has ended. */ @@ -382,11 +371,11 @@ { unsigned long flags; - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); current->notifier = NULL; current->notifier_data = NULL; recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); } static inline int collect_signal(int sig, struct sigpending *list, siginfo_t *info) @@ -473,32 +462,78 @@ */ int dequeue_signal(sigset_t *mask, siginfo_t *info) { + int signr = __dequeue_signal(¤t->pending, mask, info); + if (!signr) + signr = __dequeue_signal(¤t->signal->shared_pending, + mask, info); + return signr; +} + +/* + * Tell a process that it has a new active signal.. + * + * NOTE! we rely on the previous spin_lock to + * lock interrupts for us! We can only be called with + * "siglock" held, and the local interrupt must + * have been disabled when that got acquired! + * + * No need to set need_resched since signal event passing + * goes through ->blocked + */ +inline void signal_wake_up(struct task_struct *t, int resume) +{ + unsigned int mask; + + set_tsk_thread_flag(t,TIF_SIGPENDING); + /* - * Here we handle shared pending signals. To implement the full - * semantics we need to unqueue and resend them. It will likely - * get into our own pending queue. + * If the task is running on a different CPU + * force a reschedule on the other CPU to make + * it notice the new signal quickly. + * + * The code below is a tad loose and might occasionally + * kick the wrong CPU if we catch the process in the + * process of changing - but no harm is done by that + * other than doing an extra (lightweight) IPI interrupt. + */ + if (t->state == TASK_RUNNING) + kick_if_running(t); + /* + * If resume is set, we want to wake it up in the TASK_STOPPED case. + * We don't check for TASK_STOPPED because there is a race with it + * executing another processor and just now entering stopped state. + * By calling wake_up_process any time resume is set, we ensure + * the process will wake up and handle its stop or death signal. */ - if (current->sig->shared_pending.head) { - int signr = __dequeue_signal(¤t->sig->shared_pending, mask, info); - if (signr) - __send_sig_info(signr, info, current); + mask = TASK_INTERRUPTIBLE; + if (resume) + mask |= TASK_STOPPED; + if (t->state & mask) { + wake_up_process(t); + return; } - return __dequeue_signal(¤t->pending, mask, info); } -static int rm_from_queue(int sig, struct sigpending *s) +/* + * Remove signals in mask from the pending set and queue. + * Returns 1 if any signals were found. + * + * All callers must be holding the siglock. + */ +static int rm_from_queue(unsigned long mask, struct sigpending *s) { struct sigqueue *q, **pp; - if (!sigismember(&s->signal, sig)) + if (!sigtestsetmask(&s->signal, mask)) return 0; - sigdelset(&s->signal, sig); + sigdelsetmask(&s->signal, mask); pp = &s->head; while ((q = *pp) != NULL) { - if (q->info.si_signo == sig) { + if (q->info.si_signo < SIGRTMIN && + (mask & sigmask (q->info.si_signo))) { if ((*pp = q->next) == NULL) s->tail = pp; kmem_cache_free(sigqueue_cachep,q); @@ -511,111 +546,104 @@ } /* - * Remove signal sig from t->pending. - * Returns 1 if sig was found. - * - * All callers must be holding the siglock. - */ -static int rm_sig_from_queue(int sig, struct task_struct *t) -{ - return rm_from_queue(sig, &t->pending); -} - -/* * Bad permissions for sending the signal */ -static inline int bad_signal(int sig, struct siginfo *info, struct task_struct *t) +static inline int check_kill_permission(int sig, struct siginfo *info, + struct task_struct *t) { - return (!info || ((unsigned long)info != 1 && + int error = -EINVAL; + if (sig < 0 || sig > _NSIG) + return error; + error = -EPERM; + if ((!info || ((unsigned long)info != 1 && (unsigned long)info != 2 && SI_FROMUSER(info))) && ((sig != SIGCONT) || (current->session != t->session)) && (current->euid ^ t->suid) && (current->euid ^ t->uid) && (current->uid ^ t->suid) && (current->uid ^ t->uid) - && !capable(CAP_KILL); + && !capable(CAP_KILL)) + return error; + return security_task_kill(t, info, sig); } -/* - * Signal type: - * < 0 : global action (kill - spread to all non-blocked threads) - * = 0 : ignored - * > 0 : wake up. - */ -static int signal_type(int sig, struct signal_struct *signals) -{ - unsigned long handler; - - if (!signals) - return 0; - - handler = (unsigned long) signals->action[sig-1].sa.sa_handler; - if (handler > 1) - return 1; - - /* "Ignore" handler.. Illogical, but that has an implicit handler for SIGCHLD */ - if (handler == 1) - return sig == SIGCHLD; - - /* Default handler. Normally lethal, but.. */ - switch (sig) { - - /* Ignored */ - case SIGCONT: case SIGWINCH: - case SIGCHLD: case SIGURG: - return 0; - - /* Implicit behaviour */ - case SIGTSTP: case SIGTTIN: case SIGTTOU: - return 1; - - /* Implicit actions (kill or do special stuff) */ - default: - return -1; - } -} - - -/* - * Determine whether a signal should be posted or not. - * - * Signals with SIG_IGN can be ignored, except for the - * special case of a SIGCHLD. - * - * Some signals with SIG_DFL default to a non-action. - */ -static int ignored_signal(int sig, struct task_struct *t) -{ - /* Don't ignore traced or blocked signals */ - if ((t->ptrace & PT_PTRACED) || sigismember(&t->blocked, sig)) - return 0; - - return signal_type(sig, t->sig) == 0; -} +/* forward decl */ +static void do_notify_parent_cldstop(struct task_struct *tsk, + struct task_struct *parent); /* - * Handle TASK_STOPPED cases etc implicit behaviour - * of certain magical signals. - * - * SIGKILL gets spread out to every thread. + * Handle magic process-wide effects of stop/continue signals, and SIGKILL. + * Unlike the signal actions, these happen immediately at signal-generation + * time regardless of blocking, ignoring, or handling. This does the + * actual continuing for SIGCONT, but not the actual stopping for stop + * signals. The process stop is done as a signal action for SIG_DFL. */ -static void handle_stop_signal(int sig, struct task_struct *t) +static void handle_stop_signal(int sig, struct task_struct *p) { - switch (sig) { - case SIGKILL: case SIGCONT: - /* Wake up the process if stopped. */ - if (t->state == TASK_STOPPED) - wake_up_process(t); - t->exit_code = 0; - rm_sig_from_queue(SIGSTOP, t); - rm_sig_from_queue(SIGTSTP, t); - rm_sig_from_queue(SIGTTOU, t); - rm_sig_from_queue(SIGTTIN, t); - break; + struct task_struct *t; - case SIGSTOP: case SIGTSTP: - case SIGTTIN: case SIGTTOU: - /* If we're stopping again, cancel SIGCONT */ - rm_sig_from_queue(SIGCONT, t); - break; + if (sig_kernel_stop(sig)) { + /* + * This is a stop signal. Remove SIGCONT from all queues. + */ + rm_from_queue(sigmask(SIGCONT), &p->signal->shared_pending); + t = p; + do { + rm_from_queue(sigmask(SIGCONT), &t->pending); + t = next_thread(t); + } while (t != p); + } else if (sig == SIGCONT) { + /* + * Remove all stop signals from all queues, + * and wake all threads. + */ + if (unlikely(p->signal->group_stop_count > 0)) { + /* + * There was a group stop in progress. We'll + * pretend it finished before we got here. We are + * obliged to report it to the parent: if the + * SIGSTOP happened "after" this SIGCONT, then it + * would have cleared this pending SIGCONT. If it + * happened "before" this SIGCONT, then the parent + * got the SIGCHLD about the stop finishing before + * the continue happened. We do the notification + * now, and it's as if the stop had finished and + * the SIGCHLD was pending on entry to this kill. + */ + p->signal->group_stop_count = 0; + if (p->ptrace & PT_PTRACED) + do_notify_parent_cldstop(p, p->parent); + else + do_notify_parent_cldstop( + p->group_leader, + p->group_leader->real_parent); + } + rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending); + t = p; + do { + rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending); + /* + * This wakeup is only need if in TASK_STOPPED, + * but there can be SMP races with testing for that. + * In the normal SIGCONT case, all will be stopped. + * A spuriously sent SIGCONT will interrupt all running + * threads to check signals even if it's ignored. + * + * If there is a handler for SIGCONT, we must make + * sure that no thread returns to user mode before + * we post the signal, in case it was the only + * thread eligible to run the signal handler--then + * it must not do anything between resuming and + * running the handler. With the TIF_SIGPENDING + * flag set, the thread will pause and acquire the + * siglock that we hold now and until we've queued + * the pending signal. + */ + if (!(t->flags & PF_EXITING)) { + if (!sigismember(&t->blocked, SIGCONT)) + set_tsk_thread_flag(t, TIF_SIGPENDING); + wake_up_process(t); + } + t = next_thread(t); + } while (t != p); } } @@ -647,23 +675,23 @@ *signals->tail = q; signals->tail = &q->next; switch ((unsigned long) info) { - case 0: - q->info.si_signo = sig; - q->info.si_errno = 0; - q->info.si_code = SI_USER; - q->info.si_pid = current->pid; - q->info.si_uid = current->uid; - break; - case 1: - q->info.si_signo = sig; - q->info.si_errno = 0; - q->info.si_code = SI_KERNEL; - q->info.si_pid = 0; - q->info.si_uid = 0; - break; - default: - copy_siginfo(&q->info, info); - break; + case 0: + q->info.si_signo = sig; + q->info.si_errno = 0; + q->info.si_code = SI_USER; + q->info.si_pid = current->pid; + q->info.si_uid = current->uid; + break; + case 1: + q->info.si_signo = sig; + q->info.si_errno = 0; + q->info.si_code = SI_KERNEL; + q->info.si_pid = 0; + q->info.si_uid = 0; + break; + default: + copy_siginfo(&q->info, info); + break; } } else if (sig >= SIGRTMIN && info && (unsigned long)info != 1 && info->si_code != SI_USER) @@ -678,103 +706,36 @@ return 0; } -/* - * Tell a process that it has a new active signal.. - * - * NOTE! we rely on the previous spin_lock to - * lock interrupts for us! We can only be called with - * "siglock" held, and the local interrupt must - * have been disabled when that got acquired! - * - * No need to set need_resched since signal event passing - * goes through ->blocked - */ -inline void signal_wake_up(struct task_struct *t) -{ - set_tsk_thread_flag(t,TIF_SIGPENDING); - - /* - * If the task is running on a different CPU - * force a reschedule on the other CPU to make - * it notice the new signal quickly. - * - * The code below is a tad loose and might occasionally - * kick the wrong CPU if we catch the process in the - * process of changing - but no harm is done by that - * other than doing an extra (lightweight) IPI interrupt. - */ - if (t->state == TASK_RUNNING) - kick_if_running(t); - if (t->state & TASK_INTERRUPTIBLE) { - wake_up_process(t); - return; - } -} - -static int deliver_signal(int sig, struct siginfo *info, struct task_struct *t) -{ - int retval = send_signal(sig, info, &t->pending); - - if (!retval && !sigismember(&t->blocked, sig)) - signal_wake_up(t); +#define LEGACY_QUEUE(sigptr, sig) \ + (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig))) - return retval; -} static int -specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t, int shared) +specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) { int ret; if (!irqs_disabled()) BUG(); #if CONFIG_SMP - if (!spin_is_locked(&t->sig->siglock)) + if (!spin_is_locked(&t->sighand->siglock)) BUG(); #endif - ret = -EINVAL; - if (sig < 0 || sig > _NSIG) - goto out; - /* The somewhat baroque permissions check... */ - ret = -EPERM; - if (bad_signal(sig, info, t)) - goto out; - ret = security_task_kill(t, info, sig); - if (ret) - goto out; - - /* The null signal is a permissions and process existence probe. - No signal is actually delivered. Same goes for zombies. */ - ret = 0; - if (!sig || !t->sig) - goto out; - handle_stop_signal(sig, t); - - /* Optimize away the signal, if it's a signal that can be - handled immediately (ie non-blocked and untraced) and - that is ignored (either explicitly or by default). */ - - if (ignored_signal(sig, t)) - goto out; + /* Short-circuit ignored signals. */ + if (sig_ignored(t, sig)) + return 0; -#define LEGACY_QUEUE(sigptr, sig) \ - (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig))) + /* Support queueing exactly one non-rt signal, so that we + can get more detailed information about the cause of + the signal. */ + if (LEGACY_QUEUE(&t->pending, sig)) + return 0; - if (!shared) { - /* Support queueing exactly one non-rt signal, so that we - can get more detailed information about the cause of - the signal. */ - if (LEGACY_QUEUE(&t->pending, sig)) - goto out; + ret = send_signal(sig, info, &t->pending); + if (!ret && !sigismember(&t->blocked, sig)) + signal_wake_up(t, sig == SIGKILL); - ret = deliver_signal(sig, info, t); - } else { - if (LEGACY_QUEUE(&t->sig->shared_pending, sig)) - goto out; - ret = send_signal(sig, info, &t->sig->shared_pending); - } -out: return ret; } @@ -789,192 +750,214 @@ unsigned long int flags; int ret; - spin_lock_irqsave(&t->sig->siglock, flags); - if (t->sig->action[sig-1].sa.sa_handler == SIG_IGN) - t->sig->action[sig-1].sa.sa_handler = SIG_DFL; + spin_lock_irqsave(&t->sighand->siglock, flags); + if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) + t->sighand->action[sig-1].sa.sa_handler = SIG_DFL; sigdelset(&t->blocked, sig); recalc_sigpending_tsk(t); - ret = __send_sig_info(sig, info, t); - spin_unlock_irqrestore(&t->sig->siglock, flags); + ret = specific_send_sig_info(sig, info, t); + spin_unlock_irqrestore(&t->sighand->siglock, flags); return ret; } -static int -__specific_force_sig_info(int sig, struct task_struct *t) -{ - if (!t->sig) - return -ESRCH; - - if (t->sig->action[sig-1].sa.sa_handler == SIG_IGN) - t->sig->action[sig-1].sa.sa_handler = SIG_DFL; - sigdelset(&t->blocked, sig); - recalc_sigpending_tsk(t); - - return specific_send_sig_info(sig, (void *)2, t, 0); -} - void force_sig_specific(int sig, struct task_struct *t) { unsigned long int flags; - spin_lock_irqsave(&t->sig->siglock, flags); - if (t->sig->action[sig-1].sa.sa_handler == SIG_IGN) - t->sig->action[sig-1].sa.sa_handler = SIG_DFL; + spin_lock_irqsave(&t->sighand->siglock, flags); + if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) + t->sighand->action[sig-1].sa.sa_handler = SIG_DFL; sigdelset(&t->blocked, sig); recalc_sigpending_tsk(t); - specific_send_sig_info(sig, (void *)2, t, 0); - spin_unlock_irqrestore(&t->sig->siglock, flags); + specific_send_sig_info(sig, (void *)2, t); + spin_unlock_irqrestore(&t->sighand->siglock, flags); } -#define can_take_signal(p, sig) \ - (((unsigned long) p->sig->action[sig-1].sa.sa_handler > 1) && \ - !sigismember(&p->blocked, sig) && (task_curr(p) || !signal_pending(p))) +/* + * Test if P wants to take SIG. After we've checked all threads with this, + * it's equivalent to finding no threads not blocking SIG. Any threads not + * blocking SIG were ruled out because they are not running and already + * have pending signals. Such threads will dequeue from the shared queue + * as soon as they're available, so putting the signal on the shared queue + * will be equivalent to sending it to one such thread. + */ +#define wants_signal(sig, p, mask) \ + (!sigismember(&(p)->blocked, sig) \ + && !((p)->state & mask) \ + && !((p)->flags & PF_EXITING) \ + && (task_curr(p) || !signal_pending(p))) -static inline -int load_balance_thread_group(struct task_struct *p, int sig, - struct siginfo *info) +static inline int +__group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) { - struct task_struct *tmp; + struct task_struct *t; + unsigned int mask; int ret; +#if CONFIG_SMP + if (!spin_is_locked(&p->sighand->siglock)) + BUG(); +#endif + handle_stop_signal(sig, p); + + /* Short-circuit ignored signals. */ + if (sig_ignored(p, sig)) + return 0; + + if (LEGACY_QUEUE(&p->signal->shared_pending, sig)) + /* This is a non-RT signal and we already have one queued. */ + return 0; + /* - * if the specified thread is not blocking this signal - * then deliver it. + * Don't bother zombies and stopped tasks (but + * SIGKILL will punch through stopped state) */ - if (can_take_signal(p, sig)) - return specific_send_sig_info(sig, info, p, 0); + mask = TASK_DEAD | TASK_ZOMBIE; + if (sig != SIGKILL) + mask |= TASK_STOPPED; /* - * Otherwise try to find a suitable thread. - * If no such thread is found then deliver to - * the original thread. + * Put this signal on the shared-pending queue, or fail with EAGAIN. + * We always use the shared queue for process-wide signals, + * to avoid several races. */ + ret = send_signal(sig, info, &p->signal->shared_pending); + if (unlikely(ret)) + return ret; - tmp = p->sig->curr_target; - - if (!tmp || tmp->tgid != p->tgid) - /* restart balancing at this thread */ - p->sig->curr_target = p; - - else for (;;) { - if (thread_group_empty(p)) - BUG(); - if (!tmp || tmp->tgid != p->tgid) - BUG(); - + /* + * Now find a thread we can wake up to take the signal off the queue. + * + * If the main thread wants the signal, it gets first crack. + * Probably the least surprising to the average bear. + */ + if (wants_signal(sig, p, mask)) + t = p; + else if (thread_group_empty(p)) /* - * Do not send signals that are ignored or blocked, - * or to not-running threads that are overworked: + * There is just one thread and it does not need to be woken. + * It will dequeue unblocked signals before it runs again. */ - if (!can_take_signal(tmp, sig)) { - tmp = next_thread(tmp); - p->sig->curr_target = tmp; - if (tmp == p) - break; - continue; + return 0; + else { + /* + * Otherwise try to find a suitable thread. + */ + t = p->signal->curr_target; + if (t == NULL) + /* restart balancing at this thread */ + t = p->signal->curr_target = p; + BUG_ON(t->tgid != p->tgid); + + while (!wants_signal(sig, t, mask)) { + t = next_thread(t); + if (t == p->signal->curr_target) + /* + * No thread needs to be woken. + * Any eligible threads will see + * the signal in the queue soon. + */ + return 0; } - ret = specific_send_sig_info(sig, info, tmp, 0); - return ret; + p->signal->curr_target = t; } + /* - * No suitable thread was found - put the signal - * into the shared-pending queue. + * Found a killable thread. If the signal will be fatal, + * then start taking the whole group down immediately. */ - return specific_send_sig_info(sig, info, p, 1); -} - -int __broadcast_thread_group(struct task_struct *p, int sig) -{ - struct task_struct *tmp; - struct list_head *l; - struct pid *pid; - int err = 0; - - for_each_task_pid(p->tgid, PIDTYPE_TGID, tmp, l, pid) - err = __specific_force_sig_info(sig, tmp); - - return err; -} + if (sig_fatal(p, sig) && !p->signal->group_exit && + !sigismember(&t->real_blocked, sig) && + (sig == SIGKILL || !(t->ptrace & PT_PTRACED))) { + /* + * This signal will be fatal to the whole group. + */ + if (!sig_kernel_coredump(sig)) { + /* + * Start a group exit and wake everybody up. + * This way we don't have other threads + * running and doing things after a slower + * thread has the fatal signal pending. + */ + p->signal->group_exit = 1; + p->signal->group_exit_code = sig; + p->signal->group_stop_count = 0; + t = p; + do { + sigaddset(&t->pending.signal, SIGKILL); + signal_wake_up(t, 1); + t = next_thread(t); + } while (t != p); + return 0; + } -struct task_struct * find_unblocked_thread(struct task_struct *p, int signr) -{ - struct task_struct *tmp; - struct list_head *l; - struct pid *pid; + /* + * There will be a core dump. We make all threads other + * than the chosen one go into a group stop so that nothing + * happens until it gets scheduled, takes the signal off + * the shared queue, and does the core dump. This is a + * little more complicated than strictly necessary, but it + * keeps the signal state that winds up in the core dump + * unchanged from the death state, e.g. which thread had + * the core-dump signal unblocked. + */ + rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending); + rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending); + p->signal->group_stop_count = 0; + p->signal->group_exit_task = t; + t = p; + do { + p->signal->group_stop_count++; + signal_wake_up(t, 0); + t = next_thread(t); + } while (t != p); + wake_up_process(p->signal->group_exit_task); + return 0; + } - for_each_task_pid(p->tgid, PIDTYPE_TGID, tmp, l, pid) - if (!sigismember(&tmp->blocked, signr)) - return tmp; - return NULL; + /* + * The signal is already in the shared-pending queue. + * Tell the chosen thread to wake up and dequeue it. + */ + signal_wake_up(t, sig == SIGKILL); + return 0; } -static int -__send_sig_info(int sig, struct siginfo *info, struct task_struct *p) +/* + * Nuke all other threads in the group. + */ +void zap_other_threads(struct task_struct *p) { struct task_struct *t; - int ret = 0; -#if CONFIG_SMP - if (!spin_is_locked(&p->sig->siglock)) - BUG(); -#endif - /* not a thread group - normal signal behavior */ - if (thread_group_empty(p) || !sig) - goto out_send; - - if (sig_user_defined(p, sig)) { - if (sig_user_specific(sig)) - goto out_send; - if (sig_user_load_balance(sig)) { - ret = load_balance_thread_group(p, sig, info); - goto out_unlock; - } + p->signal->group_stop_count = 0; - /* must not happen */ - BUG(); - } - /* optimize away ignored signals: */ - if (sig_ignored(p, sig)) - goto out_unlock; + if (thread_group_empty(p)) + return; - if (sig_kernel_specific(sig) || - ((p->ptrace & PT_PTRACED) && !sig_kernel_only(sig))) - goto out_send; - - /* Does any of the threads unblock the signal? */ - t = find_unblocked_thread(p, sig); - if (!t) { - ret = specific_send_sig_info(sig, info, p, 1); - goto out_unlock; - } - if (sigismember(&t->real_blocked,sig)) { - ret = specific_send_sig_info(sig, info, t, 0); - goto out_unlock; - } - if (sig_kernel_broadcast(sig) || sig_kernel_coredump(sig)) { - ret = __broadcast_thread_group(p, sig); - goto out_unlock; - } - - /* must not happen */ - BUG(); -out_send: - ret = specific_send_sig_info(sig, info, p, 0); -out_unlock: - return ret; + for (t = next_thread(p); t != p; t = next_thread(t)) { + sigaddset(&t->pending.signal, SIGKILL); + rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending); + signal_wake_up(t, 1); + } } -int -send_sig_info(int sig, struct siginfo *info, struct task_struct *p) +/* + * Must be called with the tasklist_lock held for reading! + */ +int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) { unsigned long flags; int ret; - spin_lock_irqsave(&p->sig->siglock, flags); - ret = __send_sig_info(sig, info, p); - spin_unlock_irqrestore(&p->sig->siglock, flags); + ret = check_kill_permission(sig, info, p); + if (!ret && sig && p->sighand) { + spin_lock_irqsave(&p->sighand->siglock, flags); + ret = __group_send_sig_info(sig, info, p); + spin_unlock_irqrestore(&p->sighand->siglock, flags); + } return ret; } @@ -995,7 +978,7 @@ return -EINVAL; for_each_task_pid(pgrp, PIDTYPE_PGID, p, l, pid) { - err = send_sig_info(sig, info, p); + err = group_send_sig_info(sig, info, p); if (retval) retval = err; } @@ -1037,7 +1020,7 @@ for_each_task_pid(sid, PIDTYPE_SID, p, l, pid) { if (!p->leader) continue; - err = send_sig_info(sig, info, p); + err = group_send_sig_info(sig, info, p); if (retval) retval = err; } @@ -1056,7 +1039,7 @@ p = find_task_by_pid(pid); error = -ESRCH; if (p) - error = send_sig_info(sig, info, p); + error = group_send_sig_info(sig, info, p); read_unlock(&tasklist_lock); return error; } @@ -1079,8 +1062,8 @@ read_lock(&tasklist_lock); for_each_process(p) { - if (p->pid > 1 && p != current) { - int err = send_sig_info(sig, info, p); + if (p->pid > 1 && p->tgid != current->tgid) { + int err = group_send_sig_info(sig, info, p); ++count; if (err != -EPERM) retval = err; @@ -1100,6 +1083,24 @@ */ int +send_sig_info(int sig, struct siginfo *info, struct task_struct *p) +{ + int ret; + + /* XXX should nix these interfaces and update the kernel */ + if (T(sig, SIG_KERNEL_BROADCAST_MASK)) { + read_lock(&tasklist_lock); + ret = group_send_sig_info(sig, info, p); + read_unlock(&tasklist_lock); + } else { + spin_lock_irq(&p->sighand->siglock); + ret = specific_send_sig_info(sig, info, p); + spin_unlock_irq(&p->sighand->siglock); + } + return ret; +} + +int send_sig(int sig, struct task_struct *p, int priv) { return send_sig_info(sig, (void*)(long)(priv != 0), p); @@ -1133,9 +1134,10 @@ * Joy. Or not. Pthread wants us to wake up every thread * in our parent group. */ -static inline void __wake_up_parent(struct task_struct *p) +static inline void __wake_up_parent(struct task_struct *p, + struct task_struct *parent) { - struct task_struct *parent = p->parent, *tsk = parent; + struct task_struct *tsk = parent; /* * Fortunately this is not necessary for thread groups: @@ -1148,7 +1150,7 @@ do { wake_up_interruptible(&tsk->wait_chldexit); tsk = next_thread(tsk); - if (tsk->sig != parent->sig) + if (tsk->signal != parent->signal) BUG(); } while (tsk != parent); } @@ -1162,6 +1164,7 @@ struct siginfo info; unsigned long flags; int why, status; + struct sighand_struct *psig; if (sig == -1) BUG(); @@ -1200,10 +1203,34 @@ info.si_code = why; info.si_status = status; - spin_lock_irqsave(&tsk->parent->sig->siglock, flags); - __send_sig_info(sig, &info, tsk->parent); - __wake_up_parent(tsk); - spin_unlock_irqrestore(&tsk->parent->sig->siglock, flags); + psig = tsk->parent->sighand; + spin_lock_irqsave(&psig->siglock, flags); + if (sig == SIGCHLD && tsk->state != TASK_STOPPED && + (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN || + (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) { + /* + * We are exiting and our parent doesn't care. POSIX.1 + * defines special semantics for setting SIGCHLD to SIG_IGN + * or setting the SA_NOCLDWAIT flag: we should be reaped + * automatically and not left for our parent's wait4 call. + * Rather than having the parent do it as a magic kind of + * signal handler, we just set this to tell do_exit that we + * can be cleaned up without becoming a zombie. Note that + * we still call __wake_up_parent in this case, because a + * blocked sys_wait4 might now return -ECHILD. + * + * Whether we send SIGCHLD or not for SA_NOCLDWAIT + * is implementation-defined: we do (if you don't want + * it, just use SIG_IGN instead). + */ + tsk->exit_signal = -1; + if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) + sig = 0; + } + if (sig > 0 && sig <= _NSIG) + __group_send_sig_info(sig, &info, tsk->parent); + __wake_up_parent(tsk, tsk->parent); + spin_unlock_irqrestore(&psig->siglock, flags); } @@ -1224,6 +1251,152 @@ } } +static void +do_notify_parent_cldstop(struct task_struct *tsk, struct task_struct *parent) +{ + struct siginfo info; + unsigned long flags; + struct sighand_struct *sighand; + + info.si_signo = SIGCHLD; + info.si_errno = 0; + info.si_pid = tsk->pid; + info.si_uid = tsk->uid; + + /* FIXME: find out whether or not this is supposed to be c*time. */ + info.si_utime = tsk->utime; + info.si_stime = tsk->stime; + + info.si_status = tsk->exit_code & 0x7f; + info.si_code = CLD_STOPPED; + + sighand = parent->sighand; + spin_lock_irqsave(&sighand->siglock, flags); + if (sighand->action[SIGCHLD-1].sa.sa_handler != SIG_IGN && + !(sighand->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) + __group_send_sig_info(SIGCHLD, &info, parent); + /* + * Even if SIGCHLD is not generated, we must wake up wait4 calls. + */ + __wake_up_parent(tsk, parent); + spin_unlock_irqrestore(&sighand->siglock, flags); +} + +static void +finish_stop(int stop_count) +{ + /* + * If there are no other threads in the group, or if there is + * a group stop in progress and we are the last to stop, + * report to the parent. When ptraced, every thread reports itself. + */ + if (stop_count < 0 || (current->ptrace & PT_PTRACED)) { + read_lock(&tasklist_lock); + do_notify_parent_cldstop(current, current->parent); + read_unlock(&tasklist_lock); + } + else if (stop_count == 0) { + read_lock(&tasklist_lock); + do_notify_parent_cldstop(current->group_leader, + current->group_leader->real_parent); + read_unlock(&tasklist_lock); + } + + schedule(); + /* + * Now we don't run again until continued. + */ + current->exit_code = 0; +} + +/* + * This performs the stopping for SIGSTOP and other stop signals. + * We have to stop all threads in the thread group. + */ +static void +do_signal_stop(int signr) +{ + struct signal_struct *sig = current->signal; + struct sighand_struct *sighand = current->sighand; + int stop_count = -1; + + if (sig->group_stop_count > 0) { + /* + * There is a group stop in progress. We don't need to + * start another one. + */ + spin_lock_irq(&sighand->siglock); + if (unlikely(sig->group_stop_count == 0)) { + BUG_ON(!sig->group_exit); + spin_unlock_irq(&sighand->siglock); + return; + } + signr = sig->group_exit_code; + stop_count = --sig->group_stop_count; + current->exit_code = signr; + set_current_state(TASK_STOPPED); + spin_unlock_irq(&sighand->siglock); + } + else if (thread_group_empty(current)) { + /* + * No locks needed in this case. + */ + current->exit_code = signr; + set_current_state(TASK_STOPPED); + } + else { + /* + * There is no group stop already in progress. + * We must initiate one now. + */ + struct task_struct *t; + read_lock(&tasklist_lock); + spin_lock_irq(&sighand->siglock); + + if (unlikely(sig->group_exit)) { + /* + * There is a group exit in progress now. + * We'll just ignore the stop and process the + * associated fatal signal. + */ + spin_unlock_irq(&sighand->siglock); + read_unlock(&tasklist_lock); + return; + } + + if (sig->group_stop_count == 0) { + sig->group_exit_code = signr; + stop_count = 0; + for (t = next_thread(current); t != current; + t = next_thread(t)) + /* + * Setting state to TASK_STOPPED for a group + * stop is always done with the siglock held, + * so this check has no races. + */ + if (t->state < TASK_STOPPED) { + stop_count++; + signal_wake_up(t, 0); + } + sig->group_stop_count = stop_count; + } + else { + /* A race with another thread while unlocked. */ + signr = sig->group_exit_code; + stop_count = --sig->group_stop_count; + } + + current->exit_code = signr; + set_current_state(TASK_STOPPED); + + spin_unlock_irq(&sighand->siglock); + read_unlock(&tasklist_lock); + } + + finish_stop(stop_count); +} + + #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs) @@ -1234,31 +1407,65 @@ unsigned long signr = 0; struct k_sigaction *ka; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); + if (unlikely(current->signal->group_stop_count > 0)) { + int stop_count; + if (current->signal->group_exit_task == current) { + /* + * Group stop is so we can do a core dump. + */ + current->signal->group_exit_task = NULL; + goto dequeue; + } + /* + * There is a group stop in progress. We stop + * without any associated signal being in our queue. + */ + stop_count = --current->signal->group_stop_count; + signr = current->signal->group_exit_code; + current->exit_code = signr; + set_current_state(TASK_STOPPED); + spin_unlock_irq(¤t->sighand->siglock); + finish_stop(stop_count); + continue; + } + dequeue: signr = dequeue_signal(mask, info); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (!signr) break; if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { + /* + * If there is a group stop in progress, + * we must participate in the bookkeeping. + */ + if (current->signal->group_stop_count > 0) { + spin_lock_irq(¤t->sighand->siglock); + --current->signal->group_stop_count; + spin_unlock_irq(¤t->sighand->siglock); + } + /* Let the debugger run. */ current->exit_code = signr; + current->last_siginfo = info; set_current_state(TASK_STOPPED); notify_parent(current, SIGCHLD); schedule(); + current->last_siginfo = NULL; + /* We're back. Did the debugger cancel the sig? */ signr = current->exit_code; if (signr == 0) continue; current->exit_code = 0; - /* The debugger continued. Ignore SIGSTOP. */ - if (signr == SIGSTOP) - continue; - - /* Update the siginfo structure. Is this good? */ + /* Update the siginfo structure if the signal has + changed. If the debugger wanted something + specific in the siginfo structure then it should + have updated *info via PTRACE_SETSIGINFO. */ if (signr != info->si_signo) { info->si_signo = signr; info->si_errno = 0; @@ -1269,61 +1476,69 @@ /* If the (new) signal is now blocked, requeue it. */ if (sigismember(¤t->blocked, signr)) { - send_sig_info(signr, info, current); + spin_lock_irq(¤t->sighand->siglock); + specific_send_sig_info(signr, info, current); + spin_unlock_irq(¤t->sighand->siglock); continue; } } - ka = ¤t->sig->action[signr-1]; - if (ka->sa.sa_handler == SIG_IGN) { - if (signr != SIGCHLD) - continue; - /* Check for SIGCHLD: it's special. */ - while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) - /* nothing */; + ka = ¤t->sighand->action[signr-1]; + if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */ continue; - } - - if (ka->sa.sa_handler == SIG_DFL) { - int exit_code = signr; - - /* Init gets no signals it doesn't want. */ - if (current->pid == 1) - continue; + if (ka->sa.sa_handler != SIG_DFL) /* Run the handler. */ + return signr; - switch (signr) { - case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG: - continue; + /* + * Now we are doing the default action for this signal. + */ + if (sig_kernel_ignore(signr)) /* Default is nothing. */ + continue; - case SIGTSTP: case SIGTTIN: case SIGTTOU: - if (is_orphaned_pgrp(current->pgrp)) - continue; - /* FALLTHRU */ - - 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; - } + /* Init gets no signals it doesn't want. */ + if (current->pid == 1) + 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 */ + if (sig_kernel_stop(signr)) { + /* + * The default action is to stop all threads in + * the thread group. The job control signals + * do nothing in an orphaned pgrp, but SIGSTOP + * always works. + */ + if (signr == SIGSTOP || + !is_orphaned_pgrp(current->pgrp)) + do_signal_stop(signr); + continue; + } - default: - sig_exit(signr, exit_code, info); + /* + * Anything else is fatal, maybe with a core dump. + */ + current->flags |= PF_SIGNALED; + if (sig_kernel_coredump(signr) && + do_coredump(signr, signr, regs)) { + /* + * That killed all other threads in the group and + * synchronized with their demise, so there can't + * be any more left to kill now. The group_exit + * flags are set by do_coredump. Note that + * thread_group_empty won't always be true yet, + * because those threads were blocked in __exit_mm + * and we just let them go to finish dying. + */ + const int code = signr | 0x80; + BUG_ON(!current->signal->group_exit); + BUG_ON(current->signal->group_exit_code != code); + do_exit(code); /* NOTREACHED */ } - } - return signr; + + /* + * Death signals, no core dump. + */ + do_group_exit(signr); + /* NOTREACHED */ } return 0; } @@ -1344,6 +1559,7 @@ EXPORT_SYMBOL(notify_parent); EXPORT_SYMBOL(send_sig); EXPORT_SYMBOL(send_sig_info); +EXPORT_SYMBOL(sigprocmask); EXPORT_SYMBOL(block_all_signals); EXPORT_SYMBOL(unblock_all_signals); @@ -1370,6 +1586,42 @@ * used by various programs) */ +/* + * This is also useful for kernel threads that want to temporarily + * (or permanently) block certain signals. + * + * NOTE! Unlike the user-mode sys_sigprocmask(), the kernel + * interface happily blocks "unblockable" signals like SIGKILL + * and friends. + */ +int sigprocmask(int how, sigset_t *set, sigset_t *oldset) +{ + int error; + sigset_t old_block; + + spin_lock_irq(¤t->sighand->siglock); + old_block = current->blocked; + error = 0; + switch (how) { + case SIG_BLOCK: + sigorsets(¤t->blocked, ¤t->blocked, set); + break; + case SIG_UNBLOCK: + signandsets(¤t->blocked, ¤t->blocked, set); + break; + case SIG_SETMASK: + current->blocked = *set; + break; + default: + error = -EINVAL; + } + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + if (oldset) + *oldset = old_block; + return error; +} + asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize) { @@ -1386,35 +1638,15 @@ goto out; sigdelsetmask(&new_set, sigmask(SIGKILL)|sigmask(SIGSTOP)); - spin_lock_irq(¤t->sig->siglock); - old_set = current->blocked; - - error = 0; - switch (how) { - default: - error = -EINVAL; - break; - case SIG_BLOCK: - sigorsets(&new_set, &old_set, &new_set); - break; - case SIG_UNBLOCK: - signandsets(&new_set, &old_set, &new_set); - break; - case SIG_SETMASK: - break; - } - - current->blocked = new_set; - recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + error = sigprocmask(how, &new_set, &old_set); if (error) goto out; if (oset) goto set_old; } else if (oset) { - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); old_set = current->blocked; - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); set_old: error = -EFAULT; @@ -1434,13 +1666,18 @@ if (sigsetsize > sizeof(sigset_t)) goto out; - spin_lock_irq(¤t->sig->siglock); - sigandsets(&pending, ¤t->blocked, ¤t->pending.signal); - spin_unlock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); + sigorsets(&pending, ¤t->pending.signal, + ¤t->signal->shared_pending.signal); + spin_unlock_irq(¤t->sighand->siglock); + + /* Outside the lock because only this thread touches it. */ + sigandsets(&pending, ¤t->blocked, &pending); error = -EFAULT; if (!copy_to_user(set, &pending, sigsetsize)) error = 0; + out: return error; } @@ -1546,7 +1783,7 @@ return -EINVAL; } - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sig = dequeue_signal(&these, &info); if (!sig) { timeout = MAX_SCHEDULE_TIMEOUT; @@ -1561,19 +1798,19 @@ current->real_blocked = current->blocked; sigandsets(¤t->blocked, ¤t->blocked, &these); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; timeout = schedule_timeout(timeout); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); sig = dequeue_signal(&these, &info); current->blocked = current->real_blocked; siginitset(¤t->real_blocked, 0); recalc_sigpending(); } } - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (sig) { ret = sig; @@ -1628,9 +1865,17 @@ p = find_task_by_pid(pid); error = -ESRCH; if (p) { - spin_lock_irq(&p->sig->siglock); - error = specific_send_sig_info(sig, &info, p, 0); - spin_unlock_irq(&p->sig->siglock); + error = check_kill_permission(sig, &info, p); + /* + * The null signal is a permissions and process existence + * probe. No signal is actually delivered. + */ + if (!error && sig && p->sighand) { + spin_lock_irq(&p->sighand->siglock); + handle_stop_signal(sig, p); + error = specific_send_sig_info(sig, &info, p); + spin_unlock_irq(&p->sighand->siglock); + } } read_unlock(&tasklist_lock); return error; @@ -1662,17 +1907,22 @@ if (sig < 1 || sig > _NSIG || (act && sig_kernel_only(sig))) return -EINVAL; - k = ¤t->sig->action[sig-1]; + k = ¤t->sighand->action[sig-1]; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); + if (signal_pending(current)) { + /* + * If there might be a fatal signal pending on multiple + * threads, make sure we take it before changing the action. + */ + spin_unlock_irq(¤t->sighand->siglock); + return -ERESTARTNOINTR; + } if (oact) *oact = *k; if (act) { - *k = *act; - sigdelsetmask(&k->sa.sa_mask, sigmask(SIGKILL) | sigmask(SIGSTOP)); - /* * POSIX 3.3.1.3: * "Setting a signal action to SIG_IGN for a signal that is @@ -1683,25 +1933,40 @@ * pending and whose default action is to ignore the signal * (for example, SIGCHLD), shall cause the pending signal to * be discarded, whether or not it is blocked" - * - * Note the silly behaviour of SIGCHLD: SIG_IGN means that the - * signal isn't actually ignored, but does automatic child - * reaping, while SIG_DFL is explicitly said by POSIX to force - * the signal to be ignored. */ - - if (k->sa.sa_handler == SIG_IGN - || (k->sa.sa_handler == SIG_DFL - && (sig == SIGCONT || - sig == SIGCHLD || - sig == SIGWINCH || - sig == SIGURG))) { - if (rm_sig_from_queue(sig, current)) - recalc_sigpending(); + if (act->sa.sa_handler == SIG_IGN || + (act->sa.sa_handler == SIG_DFL && + sig_kernel_ignore(sig))) { + /* + * This is a fairly rare case, so we only take the + * tasklist_lock once we're sure we'll need it. + * Now we must do this little unlock and relock + * dance to maintain the lock hierarchy. + */ + struct task_struct *t = current; + spin_unlock_irq(&t->sighand->siglock); + read_lock(&tasklist_lock); + spin_lock_irq(&t->sighand->siglock); + *k = *act; + sigdelsetmask(&k->sa.sa_mask, + sigmask(SIGKILL) | sigmask(SIGSTOP)); + rm_from_queue(sigmask(sig), &t->signal->shared_pending); + do { + rm_from_queue(sigmask(sig), &t->pending); + recalc_sigpending_tsk(t); + t = next_thread(t); + } while (t != current); + spin_unlock_irq(¤t->sighand->siglock); + read_unlock(&tasklist_lock); + return 0; } + + *k = *act; + sigdelsetmask(&k->sa.sa_mask, + sigmask(SIGKILL) | sigmask(SIGSTOP)); } - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return 0; } @@ -1730,7 +1995,7 @@ goto out; error = -EPERM; - if (on_sig_stack (sp)) + if (on_sig_stack(sp)) goto out; error = -EINVAL; @@ -1788,9 +2053,9 @@ error = -EFAULT; if (copy_from_user(&new_set, set, sizeof(*set))) goto out; - new_set &= ~(sigmask(SIGKILL)|sigmask(SIGSTOP)); + new_set &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP)); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); old_set = current->blocked.sig[0]; error = 0; @@ -1810,7 +2075,7 @@ } recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); if (error) goto out; if (oset) @@ -1872,13 +2137,13 @@ { int old; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); old = current->blocked.sig[0]; siginitset(¤t->blocked, newmask & ~(sigmask(SIGKILL)| sigmask(SIGSTOP))); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); return old; } diff -Nru a/kernel/suspend.c b/kernel/suspend.c --- a/kernel/suspend.c Sun Feb 9 21:13:30 2003 +++ b/kernel/suspend.c Sun Feb 9 21:13:30 2003 @@ -65,7 +65,6 @@ #include #include -extern void signal_wake_up(struct task_struct *t); extern int sys_sync(void); unsigned char software_suspend_enabled = 0; @@ -219,9 +218,9 @@ /* FIXME: smp problem here: we may not access other process' flags without locking */ p->flags |= PF_FREEZE; - spin_lock_irqsave(&p->sig->siglock, flags); - signal_wake_up(p); - spin_unlock_irqrestore(&p->sig->siglock, flags); + spin_lock_irqsave(&p->sighand->siglock, flags); + signal_wake_up(p, 0); + spin_unlock_irqrestore(&p->sighand->siglock, flags); todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); @@ -1085,12 +1084,12 @@ else if (!memcmp("S2",cur->swh.magic.magic,2)) memcpy(cur->swh.magic.magic,"SWAPSPACE2",10); else { + if (noresume) + return -EINVAL; panic("%sUnable to find suspended-data signature (%.10s - misspelled?\n", name_resume, cur->swh.magic.magic); - /* We want to panic even with noresume -- we certainly don't want to add - out signature into your ext2 filesystem ;-) */ } - if(noresume) { + if (noresume) { /* We don't do a sanity check here: we want to restore the swap whatever version of kernel made the suspend image; We need to write swap, but swap is *not* enabled so @@ -1208,11 +1207,11 @@ /* We enable the possibility of machine suspend */ software_suspend_enabled = 1; #endif - if(!resume_status) + if (!resume_status) return; printk( "%s", name_resume ); - if(resume_status == NORESUME) { + if (resume_status == NORESUME) { if(resume_file[0]) read_suspend_image(resume_file, 1); printk( "disabled\n" ); @@ -1241,7 +1240,7 @@ static int __init resume_setup(char *str) { - if(resume_status) + if (resume_status == NORESUME) return 1; strncpy( resume_file, str, 255 ); @@ -1250,16 +1249,13 @@ return 1; } -static int __init software_noresume(char *str) +static int __init noresume_setup(char *str) { - if(!resume_status) - printk(KERN_WARNING "noresume option lacks a resume= option\n"); resume_status = NORESUME; - return 1; } -__setup("noresume", software_noresume); +__setup("noresume", noresume_setup); __setup("resume=", resume_setup); EXPORT_SYMBOL(software_suspend); diff -Nru a/kernel/sys.c b/kernel/sys.c --- a/kernel/sys.c Sun Feb 9 21:13:29 2003 +++ b/kernel/sys.c Sun Feb 9 21:13:29 2003 @@ -1021,16 +1021,7 @@ goto out; current->leader = 1; - if (current->session != current->pid) { - detach_pid(current, PIDTYPE_SID); - current->session = current->pid; - attach_pid(current, PIDTYPE_SID, current->pid); - } - if (current->pgrp != current->pid) { - detach_pid(current, PIDTYPE_PGID); - current->pgrp = current->pid; - attach_pid(current, PIDTYPE_PGID, current->pid); - } + __set_special_pids(current->pid, current->pid); current->tty = NULL; current->tty_old_pgrp = 0; err = current->pgrp; @@ -1317,7 +1308,7 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { - int error = 0; + int error; int sig; error = security_task_prctl(option, arg2, arg3, arg4, arg5); diff -Nru a/kernel/time.c b/kernel/time.c --- a/kernel/time.c Sun Feb 9 21:13:29 2003 +++ b/kernel/time.c Sun Feb 9 21:13:29 2003 @@ -36,9 +36,6 @@ */ struct timezone sys_tz; -/* The xtime_lock is not only serializing the xtime read/writes but it's also - serializing all accesses to the global NTP variables now. */ -extern rwlock_t xtime_lock; extern unsigned long last_time_offset; #if !defined(__alpha__) && !defined(__ia64__) @@ -80,7 +77,7 @@ return -EPERM; if (get_user(value, tptr)) return -EFAULT; - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); xtime.tv_sec = value; xtime.tv_nsec = 0; last_time_offset = 0; @@ -88,7 +85,7 @@ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); return 0; } @@ -96,13 +93,13 @@ asmlinkage long sys_gettimeofday(struct timeval *tv, struct timezone *tz) { - if (tv) { + if (likely(tv != NULL)) { struct timeval ktv; do_gettimeofday(&ktv); if (copy_to_user(tv, &ktv, sizeof(ktv))) return -EFAULT; } - if (tz) { + if (unlikely(tz != NULL)) { if (copy_to_user(tz, &sys_tz, sizeof(sys_tz))) return -EFAULT; } @@ -127,10 +124,10 @@ */ inline static void warp_clock(void) { - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); xtime.tv_sec += sys_tz.tz_minuteswest * 60; last_time_offset = 0; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); } /* @@ -235,7 +232,7 @@ txc->tick > 1100000/USER_HZ) return -EINVAL; - write_lock_irq(&xtime_lock); + write_seqlock_irq(&xtime_lock); result = time_state; /* mostly `TIME_OK' */ /* Save for later - semantics of adjtime is to return old value */ @@ -386,7 +383,7 @@ txc->errcnt = pps_errcnt; txc->stbcnt = pps_stbcnt; last_time_offset = 0; - write_unlock_irq(&xtime_lock); + write_sequnlock_irq(&xtime_lock); do_gettimeofday(&txc->time); return(result); } @@ -409,9 +406,13 @@ struct timespec current_kernel_time(void) { struct timespec now; - unsigned long flags; - read_lock_irqsave(&xtime_lock,flags); - now = xtime; - read_unlock_irqrestore(&xtime_lock,flags); + unsigned long seq; + + do { + seq = read_seqbegin(&xtime_lock); + + now = xtime; + } while (read_seqretry(&xtime_lock, seq)); + return now; } diff -Nru a/kernel/timer.c b/kernel/timer.c --- a/kernel/timer.c Sun Feb 9 21:13:30 2003 +++ b/kernel/timer.c Sun Feb 9 21:13:30 2003 @@ -26,8 +26,11 @@ #include #include #include +#include +#include #include +#include /* * per-CPU timer vector definitions: @@ -758,7 +761,7 @@ * This read-write spinlock protects us from races in SMP while * playing with xtime and avenrun. */ -rwlock_t xtime_lock __cacheline_aligned_in_smp = RW_LOCK_UNLOCKED; +seqlock_t xtime_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED; unsigned long last_time_offset; /* @@ -799,7 +802,7 @@ /* * The 64-bit jiffies value is not atomic - you MUST NOT read it - * without holding read_lock_irq(&xtime_lock). + * without sampling the sequence number in xtime_lock. * jiffies is defined in the linker script... */ @@ -1085,20 +1088,26 @@ asmlinkage long sys_sysinfo(struct sysinfo *info) { struct sysinfo val; + u64 uptime; unsigned long mem_total, sav_total; unsigned int mem_unit, bitcount; + unsigned long seq; memset((char *)&val, 0, sizeof(struct sysinfo)); - read_lock_irq(&xtime_lock); - val.uptime = jiffies / HZ; + do { + seq = read_seqbegin(&xtime_lock); - val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); - val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); - val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); + uptime = jiffies_64; + do_div(uptime, HZ); + val.uptime = (unsigned long) uptime; + + val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); + val.loads[1] = avenrun[1] << (SI_LOAD_SHIFT - FSHIFT); + val.loads[2] = avenrun[2] << (SI_LOAD_SHIFT - FSHIFT); - val.procs = nr_threads; - read_unlock_irq(&xtime_lock); + val.procs = nr_threads; + } while (read_seqretry(&xtime_lock, seq)); si_meminfo(&val); si_swapinfo(&val); @@ -1143,7 +1152,7 @@ val.totalhigh <<= bitcount; val.freehigh <<= bitcount; -out: + out: if (copy_to_user(info, &val, sizeof(struct sysinfo))) return -EFAULT; diff -Nru a/kernel/workqueue.c b/kernel/workqueue.c --- a/kernel/workqueue.c Sun Feb 9 21:13:37 2003 +++ b/kernel/workqueue.c Sun Feb 9 21:13:37 2003 @@ -177,12 +177,13 @@ current->flags |= PF_IOTHREAD; cwq->thread = current; + set_user_nice(current, -10); set_cpus_allowed(current, 1UL << cpu); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked, sigmask(SIGCHLD)); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); complete(&startup->done); @@ -212,10 +213,10 @@ /* SIGCHLD - auto-reaping */ ; /* zap all other signals */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); flush_signals(current); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } remove_wait_queue(&cwq->more_work, &wait); diff -Nru a/lib/Makefile b/lib/Makefile --- a/lib/Makefile Sun Feb 9 21:13:28 2003 +++ b/lib/Makefile Sun Feb 9 21:13:28 2003 @@ -8,9 +8,6 @@ L_TARGET := lib.a -export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \ - crc32.o rbtree.o radix-tree.o kobject.o - obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o \ bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \ kobject.o diff -Nru a/lib/zlib_deflate/Makefile b/lib/zlib_deflate/Makefile --- a/lib/zlib_deflate/Makefile Sun Feb 9 21:13:34 2003 +++ b/lib/zlib_deflate/Makefile Sun Feb 9 21:13:34 2003 @@ -6,8 +6,6 @@ # decompression code. # -export-objs := deflate_syms.o - obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate.o zlib_deflate-objs := deflate.o deftree.o deflate_syms.o diff -Nru a/lib/zlib_inflate/Makefile b/lib/zlib_inflate/Makefile --- a/lib/zlib_inflate/Makefile Sun Feb 9 21:13:35 2003 +++ b/lib/zlib_inflate/Makefile Sun Feb 9 21:13:35 2003 @@ -13,8 +13,6 @@ # uncompression can be done without blocking on allocation). # -export-objs := inflate_syms.o - obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o zlib_inflate-objs := infblock.o infcodes.o inffast.o inflate.o \ diff -Nru a/mm/Makefile b/mm/Makefile --- a/mm/Makefile Sun Feb 9 21:13:33 2003 +++ b/mm/Makefile Sun Feb 9 21:13:33 2003 @@ -2,14 +2,12 @@ # Makefile for the linux memory manager. # -export-objs := shmem.o filemap.o mempool.o page_alloc.o page-writeback.o - mmu-y := nommu.o mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \ mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \ shmem.o vmalloc.o -obj-y := bootmem.o filemap.o mempool.o oom_kill.o \ +obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \ page_alloc.o page-writeback.o pdflush.o readahead.o \ slab.o swap.o truncate.o vcache.o vmscan.o $(mmu-y) diff -Nru a/mm/fadvise.c b/mm/fadvise.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/mm/fadvise.c Sun Feb 9 21:13:37 2003 @@ -0,0 +1,72 @@ +/* + * mm/fadvise.c + * + * Copyright (C) 2002, Linus Torvalds + * + * 11Jan2003 akpm@digeo.com + * Initial version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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) +{ + struct file *file = fget(fd); + struct inode *inode; + struct address_space *mapping; + struct backing_dev_info *bdi; + int ret = 0; + + if (!file) + return -EBADF; + + inode = file->f_dentry->d_inode; + mapping = inode->i_mapping; + if (!mapping) + return -EINVAL; + + bdi = mapping->backing_dev_info; + + switch (advice) { + case POSIX_FADV_NORMAL: + file->f_ra.ra_pages = bdi->ra_pages; + break; + case POSIX_FADV_RANDOM: + file->f_ra.ra_pages = 0; + break; + case POSIX_FADV_SEQUENTIAL: + file->f_ra.ra_pages = bdi->ra_pages * 2; + break; + case POSIX_FADV_WILLNEED: + case POSIX_FADV_NOREUSE: + if (!mapping->a_ops->readpage) { + ret = -EINVAL; + break; + } + ret = do_page_cache_readahead(mapping, file, + offset >> PAGE_CACHE_SHIFT, + max_sane_readahead(len >> PAGE_CACHE_SHIFT)); + if (ret > 0) + ret = 0; + break; + case POSIX_FADV_DONTNEED: + invalidate_mapping_pages(mapping, offset >> PAGE_CACHE_SHIFT, + (len >> PAGE_CACHE_SHIFT) + 1); + break; + default: + ret = -EINVAL; + } + fput(file); + return ret; +} diff -Nru a/mm/filemap.c b/mm/filemap.c --- a/mm/filemap.c Sun Feb 9 21:13:30 2003 +++ b/mm/filemap.c Sun Feb 9 21:13:30 2003 @@ -259,9 +259,10 @@ do { prepare_to_wait(waitqueue, &wait, TASK_UNINTERRUPTIBLE); - sync_page(page); - if (test_bit(bit_nr, &page->flags)) + if (test_bit(bit_nr, &page->flags)) { + sync_page(page); io_schedule(); + } } while (test_bit(bit_nr, &page->flags)); finish_wait(waitqueue, &wait); } @@ -326,9 +327,10 @@ while (TestSetPageLocked(page)) { prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE); - sync_page(page); - if (PageLocked(page)) + if (PageLocked(page)) { + sync_page(page); io_schedule(); + } } finish_wait(wqh, &wait); } @@ -1306,11 +1308,13 @@ return 0; } +/* + * This is for filesystems which do not implement ->writepage. + */ int generic_file_readonly_mmap(struct file *file, struct vm_area_struct *vma) { - if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_WRITE)) + if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) return -EINVAL; - vma->vm_flags &= ~VM_MAYWRITE; return generic_file_mmap(file, vma); } #else @@ -1553,7 +1557,7 @@ struct page *page; struct page *cached_page = NULL; ssize_t written; - int err; + ssize_t err; size_t bytes; struct pagevec lru_pvec; const struct iovec *cur_iov = iov; /* current iovec */ @@ -1813,7 +1817,7 @@ { struct file *file = iocb->ki_filp; struct inode *inode = file->f_dentry->d_inode->i_mapping->host; - int err; + ssize_t err; struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count }; BUG_ON(iocb->ki_pos != pos); @@ -1832,7 +1836,7 @@ size_t count, loff_t *ppos) { struct inode *inode = file->f_dentry->d_inode->i_mapping->host; - int err; + ssize_t err; struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count }; down(&inode->i_sem); diff -Nru a/mm/fremap.c b/mm/fremap.c --- a/mm/fremap.c Sun Feb 9 21:13:28 2003 +++ b/mm/fremap.c Sun Feb 9 21:13:28 2003 @@ -53,8 +53,11 @@ pte_t *pte, entry; pgd_t *pgd; pmd_t *pmd; - struct pte_chain *pte_chain = NULL; + struct pte_chain *pte_chain; + pte_chain = pte_chain_alloc(GFP_KERNEL); + if (!pte_chain) + goto err; pgd = pgd_offset(mm, addr); spin_lock(&mm->page_table_lock); @@ -62,7 +65,6 @@ if (!pmd) goto err_unlock; - pte_chain = pte_chain_alloc(GFP_KERNEL); pte = pte_alloc_map(mm, pmd, addr); if (!pte) goto err_unlock; @@ -87,6 +89,7 @@ err_unlock: spin_unlock(&mm->page_table_lock); pte_chain_free(pte_chain); +err: return err; } diff -Nru a/mm/highmem.c b/mm/highmem.c --- a/mm/highmem.c Sun Feb 9 21:13:33 2003 +++ b/mm/highmem.c Sun Feb 9 21:13:33 2003 @@ -366,7 +366,7 @@ return 0; } -void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, int bio_gfp, +static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, mempool_t *pool) { struct page *page; @@ -387,7 +387,7 @@ * irk, bounce it */ if (!bio) - bio = bio_alloc(bio_gfp, (*bio_orig)->bi_vcnt); + bio = bio_alloc(GFP_NOIO, (*bio_orig)->bi_vcnt); to = bio->bi_io_vec + i; @@ -447,10 +447,9 @@ *bio_orig = bio; } -inline void blk_queue_bounce(request_queue_t *q, struct bio **bio_orig) +void blk_queue_bounce(request_queue_t *q, struct bio **bio_orig) { mempool_t *pool; - int bio_gfp; /* * for non-isa bounce case, just check if the bounce pfn is equal @@ -460,20 +459,16 @@ if (!(q->bounce_gfp & GFP_DMA)) { if (q->bounce_pfn >= blk_max_pfn) return; - - bio_gfp = GFP_NOHIGHIO; pool = page_pool; } else { BUG_ON(!isa_page_pool); - - bio_gfp = GFP_NOIO; pool = isa_page_pool; } /* * slow path */ - __blk_queue_bounce(q, bio_orig, bio_gfp, pool); + __blk_queue_bounce(q, bio_orig, pool); } #if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_HIGHMEM) diff -Nru a/mm/memory.c b/mm/memory.c --- a/mm/memory.c Sun Feb 9 21:13:31 2003 +++ b/mm/memory.c Sun Feb 9 21:13:31 2003 @@ -607,13 +607,22 @@ pmd_t *pmd; pte_t *ptep, pte; unsigned long pfn; + struct vm_area_struct *vma; + + vma = hugepage_vma(mm, address); + if (vma) + return follow_huge_addr(mm, vma, address, write); pgd = pgd_offset(mm, address); if (pgd_none(*pgd) || pgd_bad(*pgd)) goto out; pmd = pmd_offset(pgd, address); - if (pmd_none(*pmd) || pmd_bad(*pmd)) + if (pmd_none(*pmd)) + goto out; + if (pmd_huge(*pmd)) + return follow_huge_pmd(mm, address, pmd, write); + if (pmd_bad(*pmd)) goto out; ptep = pte_offset_map(pmd, address); @@ -926,9 +935,19 @@ struct page *old_page, *new_page; unsigned long pfn = pte_pfn(pte); struct pte_chain *pte_chain = NULL; + int ret; - if (!pfn_valid(pfn)) - goto bad_wp_page; + if (unlikely(!pfn_valid(pfn))) { + /* + * This should really halt the system so it can be debugged or + * at least the kernel stops what it's doing before it corrupts + * data, but for the moment just pretend this is OOM. + */ + pte_unmap(page_table); + printk(KERN_ERR "do_wp_page: bogus page at address %08lx\n", + address); + goto oom; + } old_page = pfn_to_page(pfn); if (!TestSetPageLocked(old_page)) { @@ -936,10 +955,11 @@ unlock_page(old_page); if (reuse) { flush_cache_page(vma, address); - establish_pte(vma, address, page_table, pte_mkyoung(pte_mkdirty(pte_mkwrite(pte)))); + establish_pte(vma, address, page_table, + pte_mkyoung(pte_mkdirty(pte_mkwrite(pte)))); pte_unmap(page_table); - spin_unlock(&mm->page_table_lock); - return VM_FAULT_MINOR; + ret = VM_FAULT_MINOR; + goto out; } } pte_unmap(page_table); @@ -950,11 +970,13 @@ page_cache_get(old_page); spin_unlock(&mm->page_table_lock); + pte_chain = pte_chain_alloc(GFP_KERNEL); + if (!pte_chain) + goto no_mem; new_page = alloc_page(GFP_HIGHUSER); if (!new_page) goto no_mem; copy_cow_page(old_page,new_page,address); - pte_chain = pte_chain_alloc(GFP_KERNEL); /* * Re-check the pte - we dropped the lock @@ -973,25 +995,19 @@ new_page = old_page; } pte_unmap(page_table); - spin_unlock(&mm->page_table_lock); page_cache_release(new_page); page_cache_release(old_page); - pte_chain_free(pte_chain); - return VM_FAULT_MINOR; + ret = VM_FAULT_MINOR; + goto out; -bad_wp_page: - pte_unmap(page_table); - spin_unlock(&mm->page_table_lock); - printk(KERN_ERR "do_wp_page: bogus page at address %08lx\n", address); - /* - * This should really halt the system so it can be debugged or - * at least the kernel stops what it's doing before it corrupts - * data, but for the moment just pretend this is OOM. - */ - return VM_FAULT_OOM; no_mem: page_cache_release(old_page); - return VM_FAULT_OOM; +oom: + ret = VM_FAULT_OOM; +out: + spin_unlock(&mm->page_table_lock); + pte_chain_free(pte_chain); + return ret; } static void vmtruncate_list(struct list_head *head, unsigned long pgoff) @@ -1286,6 +1302,7 @@ struct page * new_page; pte_t entry; struct pte_chain *pte_chain; + int ret; if (!vma->vm_ops || !vma->vm_ops->nopage) return do_anonymous_page(mm, vma, page_table, @@ -1301,6 +1318,10 @@ if (new_page == NOPAGE_OOM) return VM_FAULT_OOM; + pte_chain = pte_chain_alloc(GFP_KERNEL); + if (!pte_chain) + goto oom; + /* * Should we do an early C-O-W break? */ @@ -1308,7 +1329,7 @@ struct page * page = alloc_page(GFP_HIGHUSER); if (!page) { page_cache_release(new_page); - return VM_FAULT_OOM; + goto oom; } copy_user_highpage(page, new_page, address); page_cache_release(new_page); @@ -1316,7 +1337,6 @@ new_page = page; } - pte_chain = pte_chain_alloc(GFP_KERNEL); spin_lock(&mm->page_table_lock); page_table = pte_offset_map(pmd, address); @@ -1346,15 +1366,20 @@ pte_unmap(page_table); page_cache_release(new_page); spin_unlock(&mm->page_table_lock); - pte_chain_free(pte_chain); - return VM_FAULT_MINOR; + ret = VM_FAULT_MINOR; + goto out; } /* no need to invalidate: a not-present page shouldn't be cached */ update_mmu_cache(vma, address, entry); spin_unlock(&mm->page_table_lock); + ret = VM_FAULT_MAJOR; + goto out; +oom: + ret = VM_FAULT_OOM; +out: pte_chain_free(pte_chain); - return VM_FAULT_MAJOR; + return ret; } /* @@ -1422,6 +1447,10 @@ pgd = pgd_offset(mm, address); inc_page_state(pgfault); + + if (is_vm_hugetlb_page(vma)) + return VM_FAULT_SIGBUS; /* mapping truncation does this. */ + /* * We need the page table lock to synchronize with kswapd * and the SMP-safe atomic PTE updates. diff -Nru a/mm/mmap.c b/mm/mmap.c --- a/mm/mmap.c Sun Feb 9 21:13:33 2003 +++ b/mm/mmap.c Sun Feb 9 21:13:33 2003 @@ -124,6 +124,19 @@ } /* + * Requires inode->i_mapping->i_shared_sem + */ +static inline void +__remove_shared_vm_struct(struct vm_area_struct *vma, struct inode *inode) +{ + if (inode) { + if (vma->vm_flags & VM_DENYWRITE) + atomic_inc(&inode->i_writecount); + list_del_init(&vma->shared); + } +} + +/* * Remove one vm structure from the inode's i_mapping address space. */ static void remove_shared_vm_struct(struct vm_area_struct *vma) @@ -134,9 +147,7 @@ struct inode *inode = file->f_dentry->d_inode; down(&inode->i_mapping->i_shared_sem); - if (vma->vm_flags & VM_DENYWRITE) - atomic_inc(&inode->i_writecount); - list_del_init(&vma->shared); + __remove_shared_vm_struct(vma, inode); up(&inode->i_mapping->i_shared_sem); } } @@ -194,7 +205,8 @@ * internally. Essentially, translate the "PROT_xxx" and "MAP_xxx" bits * into "VM_xxx". */ -static inline unsigned long calc_vm_flags(unsigned long prot, unsigned long flags) +static inline unsigned long +calc_vm_flags(unsigned long prot, unsigned long flags) { #define _trans(x,bit1,bit2) \ ((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0) @@ -243,10 +255,10 @@ #define validate_mm(mm) do { } while (0) #endif -static struct vm_area_struct * find_vma_prepare(struct mm_struct * mm, unsigned long addr, - struct vm_area_struct ** pprev, - struct rb_node *** rb_link, - struct rb_node ** rb_parent) +static struct vm_area_struct * +find_vma_prepare(struct mm_struct *mm, unsigned long addr, + struct vm_area_struct **pprev, struct rb_node ***rb_link, + struct rb_node ** rb_parent) { struct vm_area_struct * vma; struct rb_node ** __rb_link, * __rb_parent, * rb_prev; @@ -280,8 +292,9 @@ return vma; } -static inline void __vma_link_list(struct mm_struct * mm, struct vm_area_struct * vma, - struct vm_area_struct * prev, struct rb_node * rb_parent) +static inline void +__vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, + struct vm_area_struct *prev, struct rb_node *rb_parent) { if (prev) { vma->vm_next = prev->vm_next; @@ -289,20 +302,21 @@ } else { mm->mmap = vma; if (rb_parent) - vma->vm_next = rb_entry(rb_parent, struct vm_area_struct, vm_rb); + vma->vm_next = rb_entry(rb_parent, + struct vm_area_struct, vm_rb); else vma->vm_next = NULL; } } -static void __vma_link_rb(struct mm_struct * mm, struct vm_area_struct * vma, - struct rb_node ** rb_link, struct rb_node * rb_parent) +static void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma, + struct rb_node **rb_link, struct rb_node *rb_parent) { rb_link_node(&vma->vm_rb, rb_parent, rb_link); rb_insert_color(&vma->vm_rb, &mm->mm_rb); } -static inline void __vma_link_file(struct vm_area_struct * vma) +static inline void __vma_link_file(struct vm_area_struct *vma) { struct file * file; @@ -321,8 +335,10 @@ } } -static void __vma_link(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev, - struct rb_node ** rb_link, struct rb_node * rb_parent) +static void +__vma_link(struct mm_struct *mm, struct vm_area_struct *vma, + struct vm_area_struct *prev, struct rb_node **rb_link, + struct rb_node *rb_parent) { __vma_link_list(mm, vma, prev, rb_parent); __vma_link_rb(mm, vma, rb_link, rb_parent); @@ -346,46 +362,124 @@ if (mapping) up(&mapping->i_shared_sem); + mark_mm_hugetlb(mm, vma); mm->map_count++; validate_mm(mm); } -static int vma_merge(struct mm_struct * mm, struct vm_area_struct * prev, - struct rb_node * rb_parent, unsigned long addr, - unsigned long end, unsigned long vm_flags) +/* + * Return true if we can merge this (vm_flags,file,vm_pgoff,size) + * in front of (at a lower virtual address and file offset than) the vma. + * + * We don't check here for the merged mmap wrapping around the end of pagecache + * indices (16TB on ia32) because do_mmap_pgoff() does not permit mmap's which + * wrap, nor mmaps which cover the final page at index -1UL. + */ +static int +can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags, + struct file *file, unsigned long vm_pgoff, unsigned long size) +{ + if (vma->vm_file == file && vma->vm_flags == vm_flags) { + if (!file) + return 1; /* anon mapping */ + if (vma->vm_pgoff == vm_pgoff + size) + return 1; + } + return 0; +} + +/* + * Return true if we can merge this (vm_flags,file,vm_pgoff) + * beyond (at a higher virtual address and file offset than) the vma. + */ +static int +can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, + struct file *file, unsigned long vm_pgoff) +{ + if (vma->vm_file == file && vma->vm_flags == vm_flags) { + unsigned long vma_size; + + if (!file) + return 1; /* anon mapping */ + + vma_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + if (vma->vm_pgoff + vma_size == vm_pgoff) + return 1; + } + return 0; +} + +/* + * Given a new mapping request (addr,end,vm_flags,file,pgoff), figure out + * whether that can be merged with its predecessor or its successor. Or + * both (it neatly fills a hole). + */ +static int vma_merge(struct mm_struct *mm, struct vm_area_struct *prev, + struct rb_node *rb_parent, unsigned long addr, + unsigned long end, unsigned long vm_flags, + struct file *file, unsigned long pgoff) { spinlock_t * lock = &mm->page_table_lock; + if (!prev) { prev = rb_entry(rb_parent, struct vm_area_struct, vm_rb); goto merge_next; } - if (prev->vm_end == addr && can_vma_merge(prev, vm_flags)) { - struct vm_area_struct * next; + /* + * Can it merge with the predecessor? + */ + if (prev->vm_end == addr && + can_vma_merge_after(prev, vm_flags, file, pgoff)) { + struct vm_area_struct *next; + struct inode *inode = file ? file->f_dentry->d_inode : NULL; + int need_up = 0; + + if (unlikely(file && prev->vm_next && + prev->vm_next->vm_file == file)) { + down(&inode->i_mapping->i_shared_sem); + need_up = 1; + } spin_lock(lock); prev->vm_end = end; + + /* + * OK, it did. Can we now merge in the successor as well? + */ next = prev->vm_next; - if (next && prev->vm_end == next->vm_start && can_vma_merge(next, vm_flags)) { + if (next && prev->vm_end == next->vm_start && + can_vma_merge_before(next, vm_flags, file, + pgoff, (end - addr) >> PAGE_SHIFT)) { prev->vm_end = next->vm_end; __vma_unlink(mm, next, prev); + __remove_shared_vm_struct(next, inode); spin_unlock(lock); + if (need_up) + up(&inode->i_mapping->i_shared_sem); mm->map_count--; kmem_cache_free(vm_area_cachep, next); return 1; } spin_unlock(lock); + if (need_up) + up(&inode->i_mapping->i_shared_sem); return 1; } + /* + * Can this new request be merged in front of prev->vm_next? + */ prev = prev->vm_next; if (prev) { merge_next: - if (!can_vma_merge(prev, vm_flags)) + if (!can_vma_merge_before(prev, vm_flags, file, + pgoff, (end - addr) >> PAGE_SHIFT)) return 0; if (end == prev->vm_start) { spin_lock(lock); prev->vm_start = addr; + prev->vm_pgoff -= (end - addr) >> PAGE_SHIFT; spin_unlock(lock); return 1; } @@ -404,7 +498,7 @@ { struct mm_struct * mm = current->mm; struct vm_area_struct * vma, * prev; - struct inode *inode = NULL; + struct inode *inode; unsigned int vm_flags; int correct_wcount = 0; int error; @@ -441,7 +535,8 @@ * to. we assume access permissions have been handled by the open * of the memory object, so we don't do any here. */ - vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; + vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; if (flags & MAP_LOCKED) { if (!capable(CAP_IPC_LOCK)) @@ -456,18 +551,24 @@ return -EAGAIN; } + inode = file ? file->f_dentry->d_inode : NULL; + if (file) { - inode = file->f_dentry->d_inode; switch (flags & MAP_TYPE) { case MAP_SHARED: - if ((prot & PROT_WRITE) && !(file->f_mode & FMODE_WRITE)) + if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE)) return -EACCES; - /* Make sure we don't allow writing to an append-only file.. */ + /* + * Make sure we don't allow writing to an append-only + * file.. + */ if (IS_APPEND(inode) && (file->f_mode & FMODE_WRITE)) return -EACCES; - /* make sure there are no mandatory locks on the file. */ + /* + * Make sure there are no mandatory locks on the file. + */ if (locks_verify_locked(inode)) return -EAGAIN; @@ -521,7 +622,9 @@ /* Check memory availability in shmem_file_setup? */ vm_flags |= VM_ACCOUNT; } else if (vm_flags & VM_WRITE) { - /* Private writable mapping: check memory availability */ + /* + * Private writable mapping: check memory availability + */ charged = len >> PAGE_SHIFT; if (!vm_enough_memory(charged)) return -ENOMEM; @@ -531,10 +634,12 @@ /* Can we just expand an old anonymous mapping? */ if (!file && !(vm_flags & VM_SHARED) && rb_parent) - if (vma_merge(mm, prev, rb_parent, addr, addr + len, vm_flags)) + if (vma_merge(mm, prev, rb_parent, addr, addr + len, + vm_flags, NULL, 0)) goto out; - /* Determine the object being mapped and call the appropriate + /* + * Determine the object being mapped and call the appropriate * specific mapper. the address has already been validated, but * not unmapped, but the maps are removed from the list. */ @@ -590,10 +695,19 @@ */ addr = vma->vm_start; - vma_link(mm, vma, prev, rb_link, rb_parent); - if (correct_wcount) - atomic_inc(&inode->i_writecount); - + if (!file || !rb_parent || !vma_merge(mm, prev, rb_parent, addr, + addr + len, vma->vm_flags, file, pgoff)) { + vma_link(mm, vma, prev, rb_link, rb_parent); + if (correct_wcount) + atomic_inc(&inode->i_writecount); + } else { + if (file) { + if (correct_wcount) + atomic_inc(&inode->i_writecount); + fput(file); + } + kmem_cache_free(vm_area_cachep, vma); + } out: mm->total_vm += len >> PAGE_SHIFT; if (vm_flags & VM_LOCKED) { @@ -636,7 +750,9 @@ * This function "knows" that -ENOMEM has the bits set. */ #ifndef HAVE_ARCH_UNMAPPED_AREA -static inline unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) +static inline unsigned long +arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; @@ -671,10 +787,14 @@ } } #else -extern unsigned long arch_get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); +extern unsigned long +arch_get_unmapped_area(struct file *, unsigned long, unsigned long, + unsigned long, unsigned long); #endif -unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) +unsigned long +get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, + unsigned long pgoff, unsigned long flags) { if (flags & MAP_FIXED) { if (addr > TASK_SIZE - len) @@ -685,7 +805,8 @@ } if (file && file->f_op && file->f_op->get_unmapped_area) - return file->f_op->get_unmapped_area(file, addr, len, pgoff, flags); + return file->f_op->get_unmapped_area(file, addr, len, + pgoff, flags); return arch_get_unmapped_area(file, addr, len, pgoff, flags); } @@ -708,7 +829,8 @@ while (rb_node) { struct vm_area_struct * vma_tmp; - vma_tmp = rb_entry(rb_node, struct vm_area_struct, vm_rb); + vma_tmp = rb_entry(rb_node, + struct vm_area_struct, vm_rb); if (vma_tmp->vm_end > addr) { vma = vma_tmp; @@ -726,8 +848,9 @@ } /* Same as find_vma, but also return a pointer to the previous VMA in *pprev. */ -struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr, - struct vm_area_struct **pprev) +struct vm_area_struct * +find_vma_prev(struct mm_struct *mm, unsigned long addr, + struct vm_area_struct **pprev) { struct vm_area_struct *vma = NULL, *prev = NULL; struct rb_node * rb_node; @@ -754,7 +877,7 @@ } } - out: +out: *pprev = prev; return prev ? prev->vm_next : vma; } @@ -801,7 +924,8 @@ return 0; } -struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long addr) +struct vm_area_struct * +find_extend_vma(struct mm_struct *mm, unsigned long addr) { struct vm_area_struct *vma, *prev; @@ -820,7 +944,7 @@ /* * vma is the first one with address < vma->vm_start. Have to extend vma. */ -int expand_stack(struct vm_area_struct * vma, unsigned long address) +int expand_stack(struct vm_area_struct *vma, unsigned long address) { unsigned long grow; @@ -855,7 +979,8 @@ return 0; } -struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long addr) +struct vm_area_struct * +find_extend_vma(struct mm_struct * mm, unsigned long addr) { struct vm_area_struct * vma; unsigned long start; @@ -925,7 +1050,7 @@ break; } no_mmaps: - if (last < first) /* needed for arches with discontiguous pgd indices */ + if (last < first) /* for arches with discontiguous pgd indices */ return; /* * If the PGD bits are not consecutive in the virtual address, the @@ -1098,6 +1223,11 @@ return 0; /* we have start < mpnt->vm_end */ + if (is_vm_hugetlb_page(mpnt)) { + if ((start & ~HPAGE_MASK) || (len & ~HPAGE_MASK)) + return -EINVAL; + } + /* if it doesn't overlap, we have nothing.. */ end = start + len; if (mpnt->vm_start >= end) @@ -1200,7 +1330,8 @@ flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; /* Can we just expand an old anonymous mapping? */ - if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags)) + if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, + flags, NULL, 0)) goto out; /* @@ -1265,8 +1396,9 @@ tlb = tlb_gather_mmu(mm, 1); flush_cache_mm(mm); + /* Use ~0UL here to ensure all VMAs in the mm are unmapped */ mm->map_count -= unmap_vmas(&tlb, mm, mm->mmap, 0, - TASK_SIZE, &nr_accounted); + ~0UL, &nr_accounted); vm_unacct_memory(nr_accounted); BUG_ON(mm->map_count); /* This is just debugging */ clear_page_tables(tlb, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD); @@ -1297,7 +1429,6 @@ kmem_cache_free(vm_area_cachep, vma); vma = next; } - } /* Insert vm structure into process list sorted by address @@ -1309,7 +1440,7 @@ struct vm_area_struct * __vma, * prev; struct rb_node ** rb_link, * rb_parent; - __vma = find_vma_prepare(mm, vma->vm_start, &prev, &rb_link, &rb_parent); + __vma = find_vma_prepare(mm,vma->vm_start,&prev,&rb_link,&rb_parent); if (__vma && __vma->vm_start < vma->vm_end) BUG(); vma_link(mm, vma, prev, rb_link, rb_parent); diff -Nru a/mm/mremap.c b/mm/mremap.c --- a/mm/mremap.c Sun Feb 9 21:13:32 2003 +++ b/mm/mremap.c Sun Feb 9 21:13:32 2003 @@ -24,9 +24,9 @@ static pte_t *get_one_pte_map_nested(struct mm_struct *mm, unsigned long addr) { - pgd_t * pgd; - pmd_t * pmd; - pte_t * pte = NULL; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte = NULL; pgd = pgd_offset(mm, addr); if (pgd_none(*pgd)) @@ -73,8 +73,8 @@ static inline pte_t *alloc_one_pte_map(struct mm_struct *mm, unsigned long addr) { - pmd_t * pmd; - pte_t * pte = NULL; + pmd_t *pmd; + pte_t *pte = NULL; pmd = pmd_alloc(mm, pgd_offset(mm, addr), addr); if (pmd) @@ -88,7 +88,7 @@ { int error = 0; pte_t pte; - struct page * page = NULL; + struct page *page = NULL; if (pte_present(*src)) page = pte_page(*src); @@ -183,12 +183,12 @@ return -1; } -static unsigned long move_vma(struct vm_area_struct * vma, +static unsigned long move_vma(struct vm_area_struct *vma, unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long new_addr) { - struct mm_struct * mm = vma->vm_mm; - struct vm_area_struct * new_vma, * next, * prev; + struct mm_struct *mm = vma->vm_mm; + struct vm_area_struct *new_vma, *next, *prev; int allocated_vma; int split = 0; @@ -196,14 +196,16 @@ next = find_vma_prev(mm, new_addr, &prev); if (next) { if (prev && prev->vm_end == new_addr && - can_vma_merge(prev, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) { + can_vma_merge(prev, vma->vm_flags) && !vma->vm_file && + !(vma->vm_flags & VM_SHARED)) { spin_lock(&mm->page_table_lock); prev->vm_end = new_addr + new_len; spin_unlock(&mm->page_table_lock); new_vma = prev; if (next != prev->vm_next) BUG(); - if (prev->vm_end == next->vm_start && can_vma_merge(next, prev->vm_flags)) { + if (prev->vm_end == next->vm_start && + can_vma_merge(next, prev->vm_flags)) { spin_lock(&mm->page_table_lock); prev->vm_end = next->vm_end; __vma_unlink(mm, next, prev); @@ -214,7 +216,8 @@ kmem_cache_free(vm_area_cachep, next); } } else if (next->vm_start == new_addr + new_len && - can_vma_merge(next, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) { + can_vma_merge(next, vma->vm_flags) && + !vma->vm_file && !(vma->vm_flags & VM_SHARED)) { spin_lock(&mm->page_table_lock); next->vm_start = new_addr; spin_unlock(&mm->page_table_lock); @@ -223,7 +226,8 @@ } else { prev = find_vma(mm, new_addr-1); if (prev && prev->vm_end == new_addr && - can_vma_merge(prev, vma->vm_flags) && !vma->vm_file && !(vma->vm_flags & VM_SHARED)) { + can_vma_merge(prev, vma->vm_flags) && !vma->vm_file && + !(vma->vm_flags & VM_SHARED)) { spin_lock(&mm->page_table_lock); prev->vm_end = new_addr + new_len; spin_unlock(&mm->page_table_lock); @@ -249,7 +253,7 @@ INIT_LIST_HEAD(&new_vma->shared); new_vma->vm_start = new_addr; new_vma->vm_end = new_addr+new_len; - new_vma->vm_pgoff += (addr - vma->vm_start) >> PAGE_SHIFT; + new_vma->vm_pgoff += (addr-vma->vm_start) >> PAGE_SHIFT; if (new_vma->vm_file) get_file(new_vma->vm_file); if (new_vma->vm_ops && new_vma->vm_ops->open) @@ -428,7 +432,8 @@ if (vma->vm_flags & VM_SHARED) map_flags |= MAP_SHARED; - new_addr = get_unmapped_area(vma->vm_file, 0, new_len, vma->vm_pgoff, map_flags); + new_addr = get_unmapped_area(vma->vm_file, 0, new_len, + vma->vm_pgoff, map_flags); ret = new_addr; if (new_addr & ~PAGE_MASK) goto out; diff -Nru a/mm/oom_kill.c b/mm/oom_kill.c --- a/mm/oom_kill.c Sun Feb 9 21:13:32 2003 +++ b/mm/oom_kill.c Sun Feb 9 21:13:32 2003 @@ -19,6 +19,7 @@ #include #include #include +#include /* #define DEBUG */ @@ -68,11 +69,10 @@ /* * CPU time is in seconds and run time is in minutes. There is no * particular reason for this other than that it turned out to work - * very well in practice. This is not safe against jiffie wraps - * but we don't care _that_ much... + * very well in practice. */ cpu_time = (p->utime + p->stime) >> (SHIFT_HZ + 3); - run_time = (jiffies - p->start_time) >> (SHIFT_HZ + 10); + run_time = (get_jiffies_64() - p->start_time) >> (SHIFT_HZ + 10); points /= int_sqrt(cpu_time); points /= int_sqrt(int_sqrt(run_time)); diff -Nru a/mm/page-writeback.c b/mm/page-writeback.c --- a/mm/page-writeback.c Sun Feb 9 21:13:34 2003 +++ b/mm/page-writeback.c Sun Feb 9 21:13:34 2003 @@ -237,7 +237,6 @@ break; } } - blk_run_queues(); } /* @@ -308,7 +307,6 @@ } nr_to_write -= MAX_WRITEBACK_PAGES - wbc.nr_to_write; } - blk_run_queues(); if (time_before(next_jif, jiffies + HZ)) next_jif = jiffies + HZ; mod_timer(&wb_timer, next_jif); diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c --- a/mm/page_alloc.c Sun Feb 9 21:13:28 2003 +++ b/mm/page_alloc.c Sun Feb 9 21:13:28 2003 @@ -85,6 +85,62 @@ page->mapping = NULL; } +#ifndef CONFIG_HUGETLB_PAGE +#define prep_compound_page(page, order) do { } while (0) +#define destroy_compound_page(page, order) do { } while (0) +#else +/* + * Higher-order pages are called "compound pages". They are structured thusly: + * + * The first PAGE_SIZE page is called the "head page". + * + * The remaining PAGE_SIZE pages are called "tail pages". + * + * All pages have PG_compound set. All pages have their lru.next pointing at + * the head page (even the head page has this). + * + * The head page's lru.prev, if non-zero, holds the address of the compound + * page's put_page() function. + * + * The order of the allocation is stored in the first tail page's lru.prev. + * This is only for debug at present. This usage means that zero-order pages + * may not be compound. + */ +static void prep_compound_page(struct page *page, int order) +{ + int i; + int nr_pages = 1 << order; + + page->lru.prev = NULL; + page[1].lru.prev = (void *)order; + for (i = 0; i < nr_pages; i++) { + struct page *p = page + i; + + SetPageCompound(p); + p->lru.next = (void *)page; + } +} + +static void destroy_compound_page(struct page *page, int order) +{ + int i; + int nr_pages = 1 << order; + + if (page[1].lru.prev != (void *)order) + bad_page(__FUNCTION__, page); + + for (i = 0; i < nr_pages; i++) { + struct page *p = page + i; + + if (!PageCompound(p)) + bad_page(__FUNCTION__, page); + if (p->lru.next != (void *)page) + bad_page(__FUNCTION__, page); + ClearPageCompound(p); + } +} +#endif /* CONFIG_HUGETLB_PAGE */ + /* * Freeing function for a buddy system allocator. * @@ -114,6 +170,8 @@ { unsigned long page_idx, index; + if (order) + destroy_compound_page(page, order); page_idx = page - base; if (page_idx & ~mask) BUG(); @@ -409,6 +467,12 @@ free_hot_cold_page(page, 1); } +/* + * Really, prep_compound_page() should be called from __rmqueue_bulk(). But + * we cheat by calling it from here, in the order > 0 path. Saves a branch + * or two. + */ + static struct page *buffered_rmqueue(struct zone *zone, int order, int cold) { unsigned long flags; @@ -435,6 +499,8 @@ spin_lock_irqsave(&zone->lock, flags); page = __rmqueue(zone, order); spin_unlock_irqrestore(&zone->lock, flags); + if (order && page) + prep_compound_page(page, order); } if (page != NULL) { @@ -1269,7 +1335,7 @@ pgdat->node_mem_map = node_mem_map; free_area_init_core(pgdat, zones_size, zholes_size); - memblk_set_online(__node_to_memblk(nid)); + memblk_set_online(node_to_memblk(nid)); calculate_zone_bitmap(pgdat, zones_size); } @@ -1379,15 +1445,20 @@ "pswpin", "pswpout", "pgalloc", + "pgfree", "pgactivate", "pgdeactivate", "pgfault", "pgmajfault", + "pgscan", "pgrefill", "pgsteal", + "pginodesteal", "kswapd_steal", + + "kswapd_inodesteal", "pageoutrun", "allocstall", "pgrotated", diff -Nru a/mm/pdflush.c b/mm/pdflush.c --- a/mm/pdflush.c Sun Feb 9 21:13:37 2003 +++ b/mm/pdflush.c Sun Feb 9 21:13:37 2003 @@ -90,10 +90,10 @@ strcpy(current->comm, "pdflush"); /* interruptible sleep, so block all signals */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked, 0); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); current->flags |= PF_FLUSHER; my_work->fn = NULL; diff -Nru a/mm/readahead.c b/mm/readahead.c --- a/mm/readahead.c Sun Feb 9 21:13:28 2003 +++ b/mm/readahead.c Sun Feb 9 21:13:28 2003 @@ -42,6 +42,8 @@ return (VM_MIN_READAHEAD * 1024) / PAGE_CACHE_SIZE; } +#define list_to_page(head) (list_entry((head)->prev, struct page, list)) + /** * read_cache_pages - populate an address space with some pages, and * start reads against them. @@ -63,7 +65,7 @@ pagevec_init(&lru_pvec, 0); while (!list_empty(pages)) { - page = list_entry(pages->prev, struct page, list); + page = list_to_page(pages); list_del(&page->list); if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) { page_cache_release(page); @@ -72,8 +74,16 @@ ret = filler(data, page); if (!pagevec_add(&lru_pvec, page)) __pagevec_lru_add(&lru_pvec); - if (ret) + if (ret) { + while (!list_empty(pages)) { + struct page *victim; + + victim = list_to_page(pages); + list_del(&victim->list); + page_cache_release(victim); + } break; + } } pagevec_lru_add(&lru_pvec); return ret; @@ -85,13 +95,12 @@ unsigned page_idx; struct pagevec lru_pvec; - pagevec_init(&lru_pvec, 0); - if (mapping->a_ops->readpages) return mapping->a_ops->readpages(filp, mapping, pages, nr_pages); + pagevec_init(&lru_pvec, 0); for (page_idx = 0; page_idx < nr_pages; page_idx++) { - struct page *page = list_entry(pages->prev, struct page, list); + struct page *page = list_to_page(pages); list_del(&page->list); if (!add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) { @@ -227,10 +236,8 @@ * uptodate then the caller will launch readpage again, and * will then handle the error. */ - if (ret) { + if (ret) read_pages(mapping, filp, &page_pool, ret); - blk_run_queues(); - } BUG_ON(!list_empty(&page_pool)); out: return ret; diff -Nru a/mm/slab.c b/mm/slab.c --- a/mm/slab.c Sun Feb 9 21:13:35 2003 +++ b/mm/slab.c Sun Feb 9 21:13:35 2003 @@ -439,7 +439,6 @@ static kmem_cache_t cache_cache = { .lists = LIST3_INIT(cache_cache.lists), /* Allow for boot cpu != 0 */ - .array = { [0 ... NR_CPUS-1] = &initarray_cache.cache }, .batchcount = 1, .limit = BOOT_CPUCACHE_ENTRIES, .objsize = sizeof(kmem_cache_t), @@ -611,6 +610,7 @@ init_MUTEX(&cache_chain_sem); INIT_LIST_HEAD(&cache_chain); list_add(&cache_cache.next, &cache_chain); + cache_cache.array[smp_processor_id()] = &initarray_cache.cache; cache_estimate(0, cache_cache.objsize, 0, &left_over, &cache_cache.num); @@ -769,7 +769,7 @@ *(unsigned char *)(addr+size-1) = POISON_END; } -static int check_poison_obj (kmem_cache_t *cachep, void *addr) +static void check_poison_obj(kmem_cache_t *cachep, void *addr) { int size = cachep->objsize; void *end; @@ -779,8 +779,7 @@ } end = memchr(addr, POISON_END, size); if (end != (addr+size-1)) - return 1; - return 0; + slab_error(cachep, "object was modified after freeing"); } #endif @@ -1420,6 +1419,8 @@ opps1: kmem_freepages(cachep, objp); failed: + if (local_flags & __GFP_WAIT) + local_irq_disable(); return 0; } @@ -1628,8 +1629,7 @@ if (!objp) return objp; if (cachep->flags & SLAB_POISON) - if (check_poison_obj(cachep, objp)) - BUG(); + check_poison_obj(cachep, objp); if (cachep->flags & SLAB_RED_ZONE) { /* Set alloc red-zone, and check old one. */ if (xchg((unsigned long *)objp, RED_ACTIVE) != RED_INACTIVE) @@ -2048,6 +2048,14 @@ int err; int limit; + /* The head array serves three purposes: + * - create a LIFO ordering, i.e. return objects that are cache-warm + * - reduce the number of spinlock operations. + * - reduce the number of linked list operations on the slab and + * bufctl chains: array operations are cheaper. + * The numbers are guessed, we should auto-tune as described by + * Bonwick. + */ if (cachep->objsize > PAGE_SIZE) limit = 8; else if (cachep->objsize > 1024) @@ -2057,6 +2065,14 @@ else limit = 248; +#ifndef DEBUG + /* With debugging enabled, large batchcount lead to excessively + * long periods with disabled local interrupts. Limit the + * batchcount + */ + if (limit > 32) + limit = 32; +#endif err = do_tune_cpucache(cachep, limit, limit/2); if (err) printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n", diff -Nru a/mm/truncate.c b/mm/truncate.c --- a/mm/truncate.c Sun Feb 9 21:13:36 2003 +++ b/mm/truncate.c Sun Feb 9 21:13:36 2003 @@ -64,24 +64,25 @@ * ->page_lock. That provides exclusion against the __set_page_dirty * functions. */ -static void +static int invalidate_complete_page(struct address_space *mapping, struct page *page) { if (page->mapping != mapping) - return; + return 0; if (PagePrivate(page) && !try_to_release_page(page, 0)) - return; + return 0; write_lock(&mapping->page_lock); if (PageDirty(page)) { write_unlock(&mapping->page_lock); - } else { - __remove_from_page_cache(page); - write_unlock(&mapping->page_lock); - ClearPageUptodate(page); - page_cache_release(page); /* pagecache ref */ + return 0; } + __remove_from_page_cache(page); + write_unlock(&mapping->page_lock); + ClearPageUptodate(page); + page_cache_release(page); /* pagecache ref */ + return 1; } /** @@ -177,24 +178,29 @@ } /** - * invalidate_inode_pages - Invalidate all the unlocked pages of one inode - * @inode: the inode which pages we want to invalidate + * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode + * @inode: the address_space which holds the pages to invalidate + * @end: the index of the last page to invalidate (inclusive) + * @nr_pages: defines the pagecache span. Invalidate up to @start + @nr_pages * * This function only removes the unlocked pages, if you want to * remove all the pages of one inode, you must call truncate_inode_pages. * - * invalidate_inode_pages() will not block on IO activity. It will not + * invalidate_mapping_pages() will not block on IO activity. It will not * invalidate pages which are dirty, locked, under writeback or mapped into * pagetables. */ -void invalidate_inode_pages(struct address_space *mapping) +unsigned long invalidate_mapping_pages(struct address_space *mapping, + pgoff_t start, pgoff_t end) { struct pagevec pvec; - pgoff_t next = 0; + pgoff_t next = start; + unsigned long ret = 0; int i; pagevec_init(&pvec, 0); - while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { + while (next <= end && + pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) { for (i = 0; i < pagevec_count(&pvec); i++) { struct page *page = pvec.pages[i]; @@ -209,13 +215,19 @@ goto unlock; if (page_mapped(page)) goto unlock; - invalidate_complete_page(mapping, page); + ret += invalidate_complete_page(mapping, page); unlock: unlock_page(page); } pagevec_release(&pvec); cond_resched(); } + return ret; +} + +unsigned long invalidate_inode_pages(struct address_space *mapping) +{ + return invalidate_mapping_pages(mapping, 0, ~0UL); } /** diff -Nru a/mm/vmscan.c b/mm/vmscan.c --- a/mm/vmscan.c Sun Feb 9 21:13:29 2003 +++ b/mm/vmscan.c Sun Feb 9 21:13:29 2003 @@ -894,9 +894,9 @@ max_scan = to_reclaim * 2; if (max_scan < SWAP_CLUSTER_MAX) max_scan = SWAP_CLUSTER_MAX; - to_free -= shrink_zone(zone, max_scan, GFP_KSWAPD, + to_free -= shrink_zone(zone, max_scan, GFP_KERNEL, to_reclaim, &nr_mapped, ps, priority); - shrink_slab(max_scan + nr_mapped, GFP_KSWAPD); + shrink_slab(max_scan + nr_mapped, GFP_KERNEL); if (zone->all_unreclaimable) continue; if (zone->pages_scanned > zone->present_pages * 2) @@ -929,7 +929,7 @@ DEFINE_WAIT(wait); daemonize(); - set_cpus_allowed(tsk, __node_to_cpu_mask(pgdat->node_id)); + set_cpus_allowed(tsk, node_to_cpumask(pgdat->node_id)); sprintf(tsk->comm, "kswapd%d", pgdat->node_id); sigfillset(&tsk->blocked); @@ -957,7 +957,6 @@ finish_wait(&pgdat->kswapd_wait, &wait); get_page_state(&ps); balance_pgdat(pgdat, 0, &ps); - blk_run_queues(); } } diff -Nru a/net/802/Makefile b/net/802/Makefile --- a/net/802/Makefile Sun Feb 9 21:13:31 2003 +++ b/net/802/Makefile Sun Feb 9 21:13:31 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux 802.x protocol layers. # -export-objs := p8022.o psnap.o - obj-y := p8023.o # Check the p8022 selections against net/core/Makefile. diff -Nru a/net/8021q/vlan.h b/net/8021q/vlan.h --- a/net/8021q/vlan.h Sun Feb 9 21:13:33 2003 +++ b/net/8021q/vlan.h Sun Feb 9 21:13:33 2003 @@ -41,7 +41,7 @@ /* Find a VLAN device by the MAC address of it's Ethernet device, and * it's VLAN ID. The default configuration is to have VLAN's scope * to be box-wide, so the MAC will be ignored. The mac will only be - * looked at if we are configured to have a seperate set of VLANs per + * looked at if we are configured to have a separate set of VLANs per * each MAC addressable interface. Note that this latter option does * NOT follow the spec for VLANs, but may be useful for doing very * large quantities of VLAN MUX/DEMUX onto FrameRelay or ATM PVCs. diff -Nru a/net/Kconfig b/net/Kconfig --- a/net/Kconfig Sun Feb 9 21:13:28 2003 +++ b/net/Kconfig Sun Feb 9 21:13:28 2003 @@ -31,7 +31,7 @@ protocol implemented in the kernel, e.g. tcpdump. If you want them to work, choose Y. - This driver is also available as a module called af_packet.o ( = + This driver is also available as a module called af_packet ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read ; if you use modprobe @@ -149,7 +149,7 @@ which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . The module will be - called unix.o. If you try building this as a module and you have + called unix. If you try building this as a module and you have said Y to "Kernel module loader support" above, be sure to add 'alias net-pf-1 unix' to your /etc/modules.conf file. Note that several important services won't work correctly if you say M here @@ -217,7 +217,7 @@ This protocol support is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you - want). The module will be called ipv6.o. If you want to compile it + want). The module will be called ipv6. If you want to compile it as a module, say M here and read . It is safe to say N here for now. @@ -329,7 +329,7 @@ The IPX driver would enlarge your kernel by about 16 KB. 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 will - be called ipx.o. If you want to compile it as a module, say M here + be called ipx. If you want to compile it as a module, say M here and read . Unless you want to integrate your Linux box with a local Novell network, say N. @@ -358,7 +358,7 @@ 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 appletalk.o. If you want to compile it as a + The module is called appletalk. If you want to compile it as a module, say M here and read . You almost certainly want to compile it as a module so you can restart your AppleTalk stack without rebooting your machine. I hear that @@ -388,7 +388,7 @@ The DECnet code 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 decnet.o. + The module is called decnet. source "net/decnet/Kconfig" @@ -417,7 +417,7 @@ If you want to compile this code 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 bridge.o. + will be called bridge. If unsure, say N. @@ -455,7 +455,7 @@ If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module - will be called x25.o. If unsure, say N. + will be called x25. If unsure, say N. config LAPB tristate "LAPB Data Link Driver (EXPERIMENTAL)" @@ -476,7 +476,7 @@ If you want to compile this driver as a module though ( = 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 lapb.o. If unsure, say N. + module will be called lapb. If unsure, say N. config NET_DIVERT bool "Frame Diverter (EXPERIMENTAL)" @@ -521,7 +521,7 @@ 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 will be called econet.o. If you want to compile it as a + The module will be called econet. If you want to compile it as a module, say M here and read . config ECONET_AUNUDP @@ -561,7 +561,7 @@ information. The WAN routing support is also available as a module called - wanrouter.o ( = code which can be inserted in and removed from the + wanrouter ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -661,7 +661,7 @@ Documentation on how to use the packet generaor can be found at . - This code is also available as a module called pktgen.o ( = code + This code is also available as a module called pktgen ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . diff -Nru a/net/Makefile b/net/Makefile --- a/net/Makefile Sun Feb 9 21:13:31 2003 +++ b/net/Makefile Sun Feb 9 21:13:31 2003 @@ -5,8 +5,6 @@ # Rewritten to use lists instead of if-statements. # -export-objs := netsyms.o - obj-y := socket.o core/ # LLC has to be linked before the files in net/802/ diff -Nru a/net/appletalk/Makefile b/net/appletalk/Makefile --- a/net/appletalk/Makefile Sun Feb 9 21:13:33 2003 +++ b/net/appletalk/Makefile Sun Feb 9 21:13:33 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux AppleTalk layer. # -export-objs = ddp.o - obj-$(CONFIG_ATALK) += appletalk.o appletalk-y := aarp.o ddp.o atalk_proc.o diff -Nru a/net/atm/Makefile b/net/atm/Makefile --- a/net/atm/Makefile Sun Feb 9 21:13:29 2003 +++ b/net/atm/Makefile Sun Feb 9 21:13:29 2003 @@ -2,8 +2,6 @@ # Makefile for the ATM Protocol Families. # -export-objs := common.o atm_misc.o raw.o resources.o ipcommon.o proc.o - mpoa-objs := mpc.o mpoa_caches.o mpoa_proc.o obj-$(CONFIG_ATM) := addr.o pvc.o signaling.o svc.o common.o atm_misc.o raw.o resources.o diff -Nru a/net/ax25/Kconfig b/net/ax25/Kconfig --- a/net/ax25/Kconfig Sun Feb 9 21:13:35 2003 +++ b/net/ax25/Kconfig Sun Feb 9 21:13:35 2003 @@ -50,7 +50,7 @@ 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 will be called ax25.o. If you want to compile it as a + The module will be called ax25. If you want to compile it as a module, say M here and read . config AX25_DAMA_SLAVE @@ -83,7 +83,7 @@ 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 will be called netrom.o. If you want to compile it as a + The module will be called netrom. If you want to compile it as a module, say M here and read . config ROSE @@ -104,7 +104,7 @@ 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 will be called rose.o. If you want to compile it as a + The module will be called rose. If you want to compile it as a module, say M here and read . diff -Nru a/net/ax25/Makefile b/net/ax25/Makefile --- a/net/ax25/Makefile Sun Feb 9 21:13:28 2003 +++ b/net/ax25/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux AX.25 layer. # -export-objs := af_ax25.o - obj-$(CONFIG_AX25) += ax25.o ax25-y := ax25_addr.o ax25_dev.o ax25_iface.o ax25_in.o ax25_ip.o ax25_out.o \ diff -Nru a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig --- a/net/bluetooth/Kconfig Sun Feb 9 21:13:35 2003 +++ b/net/bluetooth/Kconfig Sun Feb 9 21:13:35 2003 @@ -30,7 +30,7 @@ Bluetooth kernel modules are provided in the BlueZ packages. For more information, see . - If you want to compile Bluetooth Core as module (bluetooth.o) say M here. + If you want to compile Bluetooth Core as module (bluetooth) say M here. config BT_L2CAP tristate "L2CAP protocol support" @@ -41,7 +41,7 @@ support is required for most Bluetooth applications. Say Y here to compile L2CAP support into the kernel or say M to - compile it as module (l2cap.o). + compile it as module (l2cap). config BT_SCO tristate "SCO links support" @@ -51,7 +51,7 @@ required for voice applications like Headset and Audio. Say Y here to compile SCO support into the kernel or say M to - compile it as module (sco.o). + compile it as module (sco). source "net/bluetooth/rfcomm/Kconfig" diff -Nru a/net/bluetooth/Makefile b/net/bluetooth/Makefile --- a/net/bluetooth/Makefile Sun Feb 9 21:13:29 2003 +++ b/net/bluetooth/Makefile Sun Feb 9 21:13:29 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux Bluetooth subsystem. # -export-objs := syms.o - obj-$(CONFIG_BT) += bluetooth.o obj-$(CONFIG_BT_L2CAP) += l2cap.o obj-$(CONFIG_BT_SCO) += sco.o diff -Nru a/net/bluetooth/bnep/Kconfig b/net/bluetooth/bnep/Kconfig --- a/net/bluetooth/bnep/Kconfig Sun Feb 9 21:13:37 2003 +++ b/net/bluetooth/bnep/Kconfig Sun Feb 9 21:13:37 2003 @@ -11,7 +11,7 @@ For more information, see . Say Y here to compile BNEP support into the kernel or say M to - compile it as module (bnep.o). + compile it as module (bnep). config BT_BNEP_MC_FILTER bool "Multicast filter support" diff -Nru a/net/bluetooth/rfcomm/Kconfig b/net/bluetooth/rfcomm/Kconfig --- a/net/bluetooth/rfcomm/Kconfig Sun Feb 9 21:13:32 2003 +++ b/net/bluetooth/rfcomm/Kconfig Sun Feb 9 21:13:32 2003 @@ -7,7 +7,7 @@ applications. Say Y here to compile RFCOMM support into the kernel or say M to - compile it as module (rfcomm.o). + compile it as module (rfcomm). config BT_RFCOMM_TTY bool "RFCOMM TTY support" diff -Nru a/net/bridge/Makefile b/net/bridge/Makefile --- a/net/bridge/Makefile Sun Feb 9 21:13:36 2003 +++ b/net/bridge/Makefile Sun Feb 9 21:13:36 2003 @@ -2,8 +2,6 @@ # Makefile for the IEEE 802.1d ethernet bridging layer. # -export-objs := br.o - obj-$(CONFIG_BRIDGE) += bridge.o bridge-objs := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \ diff -Nru a/net/bridge/br.c b/net/bridge/br.c --- a/net/bridge/br.c Sun Feb 9 21:13:29 2003 +++ b/net/bridge/br.c Sun Feb 9 21:13:29 2003 @@ -33,12 +33,12 @@ void br_dec_use_count() { - MOD_DEC_USE_COUNT; + module_put(THIS_MODULE); } void br_inc_use_count() { - MOD_INC_USE_COUNT; + try_module_get(THIS_MODULE); } static int __init br_init(void) diff -Nru a/net/bridge/br_if.c b/net/bridge/br_if.c --- a/net/bridge/br_if.c Sun Feb 9 21:13:37 2003 +++ b/net/bridge/br_if.c Sun Feb 9 21:13:37 2003 @@ -155,8 +155,6 @@ p->path_cost = br_initial_port_cost(dev); p->priority = 0x80; - dev->br_port = p; - for (i=1;i<255;i++) if (br_get_port(br, i) == NULL) break; @@ -165,6 +163,8 @@ kfree(p); return NULL; } + + dev->br_port = p; p->port_no = i; br_init_port(p); diff -Nru a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile --- a/net/bridge/netfilter/Makefile Sun Feb 9 21:13:33 2003 +++ b/net/bridge/netfilter/Makefile Sun Feb 9 21:13:33 2003 @@ -2,8 +2,6 @@ # Makefile for the netfilter modules for Link Layer filtering on a bridge. # -export-objs := ebtables.o - obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o obj-$(CONFIG_BRIDGE_EBT_T_FILTER) += ebtable_filter.o obj-$(CONFIG_BRIDGE_EBT_T_NAT) += ebtable_nat.o diff -Nru a/net/core/rtnetlink.c b/net/core/rtnetlink.c --- a/net/core/rtnetlink.c Sun Feb 9 21:13:37 2003 +++ b/net/core/rtnetlink.c Sun Feb 9 21:13:37 2003 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -363,7 +364,7 @@ sz_idx = type>>2; kind = type&3; - if (kind != 2 && !cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) { + if (kind != 2 && security_netlink_recv(skb)) { *errp = -EPERM; return -1; } diff -Nru a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c --- a/net/decnet/dn_nsp_in.c Sun Feb 9 21:13:30 2003 +++ b/net/decnet/dn_nsp_in.c Sun Feb 9 21:13:30 2003 @@ -566,26 +566,19 @@ */ static __inline__ int dn_queue_skb(struct sock *sk, struct sk_buff *skb, int sig, struct sk_buff_head *queue) { -#ifdef CONFIG_FILTER - struct sk_filter *filter; -#endif - + int err; + /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces number of warnings when compiling with -W --ANK */ - if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf -) - return -ENOMEM; - -#ifdef CONFIG_FILTER - if (sk->filter) { - int err = 0; - if ((filter = sk->filter) != NULL && sk_filter(skb, sk->filter)) - err = -EPERM; /* Toss packet */ - if (err) - return err; + if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) { + err = -ENOMEM; + goto out; } -#endif /* CONFIG_FILTER */ + + err = sk_filter(sk, skb, 0); + if (err) + goto out; skb_set_owner_r(skb, sk); skb_queue_tail(queue, skb); @@ -603,8 +596,8 @@ (sig == SIGURG) ? POLL_PRI : POLL_IN); } read_unlock(&sk->callback_lock); - - return 0; +out: + return err; } static void dn_nsp_otherdata(struct sock *sk, struct sk_buff *skb) diff -Nru a/net/ipv4/ah.c b/net/ipv4/ah.c --- a/net/ipv4/ah.c Sun Feb 9 21:13:35 2003 +++ b/net/ipv4/ah.c Sun Feb 9 21:13:35 2003 @@ -280,6 +280,8 @@ pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) goto out; + skb->ip_summed = CHECKSUM_NONE; + ah = (struct ip_auth_hdr*)skb->data; iph = skb->nh.iph; @@ -359,7 +361,7 @@ ahp->icv = ah_hmac_digest; /* - * Lookup the algorithm description maintained by pfkey, + * Lookup the algorithm description maintained by xfrm_algo, * verify crypto transform properties, and store information * we need for AH processing. This lookup cannot fail here * after a successful crypto_alloc_tfm(). diff -Nru a/net/ipv4/devinet.c b/net/ipv4/devinet.c --- a/net/ipv4/devinet.c Sun Feb 9 21:13:29 2003 +++ b/net/ipv4/devinet.c Sun Feb 9 21:13:29 2003 @@ -823,6 +823,34 @@ return notifier_chain_unregister(&inetaddr_chain, nb); } +/* Rename ifa_labels for a device name change. Make some effort to preserve existing + * alias numbering and to create unique labels if possible. +*/ +static void inetdev_changename(struct net_device *dev, struct in_device *in_dev) +{ + struct in_ifaddr *ifa; + int named = 0; + + for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { + char old[IFNAMSIZ], *dot; + + memcpy(old, ifa->ifa_label, IFNAMSIZ); + memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); + if (named++ == 0) + continue; + dot = strchr(ifa->ifa_label, ':'); + if (dot == NULL) { + sprintf(old, ":%d", named); + dot = old; + } + if (strlen(dot) + strlen(dev->name) < IFNAMSIZ) { + strcat(ifa->ifa_label, dot); + } else { + strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot); + } + } +} + /* Called only under RTNL semaphore */ static int inetdev_event(struct notifier_block *this, unsigned long event, @@ -873,14 +901,10 @@ inetdev_destroy(in_dev); break; case NETDEV_CHANGENAME: - if (in_dev->ifa_list) { - struct in_ifaddr *ifa; - for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) - memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); - /* Do not notify about label change, this event is - not interesting to applications using netlink. - */ - } + /* Do not notify about label change, this event is + * not interesting to applications using netlink. + */ + inetdev_changename(dev, in_dev); break; } out: diff -Nru a/net/ipv4/esp.c b/net/ipv4/esp.c --- a/net/ipv4/esp.c Sun Feb 9 21:13:33 2003 +++ b/net/ipv4/esp.c Sun Feb 9 21:13:33 2003 @@ -10,6 +10,9 @@ #define MAX_SG_ONSTACK 4 +typedef void (icv_update_fn_t)(struct crypto_tfm *, + struct scatterlist *, unsigned int); + /* BUGS: * - we assume replay seqno is always present. */ @@ -30,37 +33,40 @@ struct crypto_tfm *tfm; /* crypto handle */ } conf; - /* Integrity. It is active when authlen != 0 */ + /* Integrity. It is active when icv_full_len != 0 */ struct { u8 *key; /* Key */ int key_len; /* Length of the key */ - u8 *work_digest; - /* authlen is length of trailer containing auth token. - * If it is not zero it is assumed to be - * >= crypto_tfm_alg_digestsize(atfm) */ - int authlen; - void (*digest)(struct esp_data*, - struct sk_buff *skb, - int offset, - int len, - u8 *digest); + u8 *work_icv; + int icv_full_len; + int icv_trunc_len; + void (*icv)(struct esp_data*, + struct sk_buff *skb, + int offset, int len, u8 *icv); struct crypto_tfm *tfm; } auth; }; /* Move to common area: it is shared with AH. */ -void skb_digest_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, - int offset, int len) +void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm, + int offset, int len, icv_update_fn_t icv_update) { int start = skb->len - skb->data_len; int i, copy = start - offset; + struct scatterlist sg; /* Checksum header. */ if (copy > 0) { if (copy > len) copy = len; - tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx, skb->data+offset, copy); + + sg.page = virt_to_page(skb->data + offset); + sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE; + sg.length = copy; + + icv_update(tfm, &sg, 1); + if ((len -= copy) == 0) return; offset += copy; @@ -73,14 +79,17 @@ end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { - u8 *vaddr; skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; if (copy > len) copy = len; - vaddr = kmap_skb_frag(frag); - tfm->__crt_alg->cra_digest.dia_update(tfm->crt_ctx, vaddr+frag->page_offset+offset-start, copy); - kunmap_skb_frag(vaddr); + + sg.page = frag->page; + sg.offset = frag->page_offset + offset-start; + sg.length = copy; + + icv_update(tfm, &sg, 1); + if (!(len -= copy)) return; offset += copy; @@ -100,7 +109,7 @@ if ((copy = end - offset) > 0) { if (copy > len) copy = len; - skb_digest_walk(list, tfm, offset-start, copy); + skb_icv_walk(list, tfm, offset-start, copy, icv_update); if ((len -= copy) == 0) return; offset += copy; @@ -188,12 +197,13 @@ int len, u8 *auth_data) { struct crypto_tfm *tfm = esp->auth.tfm; - char *digest = esp->auth.work_digest; + char *icv = esp->auth.work_icv; + memset(auth_data, 0, esp->auth.icv_trunc_len); crypto_hmac_init(tfm, esp->auth.key, &esp->auth.key_len); - skb_digest_walk(skb, tfm, offset, len); - crypto_hmac_final(tfm, esp->auth.key, &esp->auth.key_len, digest); - memcpy(auth_data, digest, esp->auth.authlen); + skb_icv_walk(skb, tfm, offset, len, crypto_hmac_update); + crypto_hmac_final(tfm, esp->auth.key, &esp->auth.key_len, icv); + memcpy(auth_data, icv, esp->auth.icv_trunc_len); } /* Check that skb data bits are writable. If they are not, copy data @@ -317,6 +327,7 @@ struct sk_buff *trailer; int blksize; int clen; + int alen; int nfrags; union { struct iphdr iph; @@ -347,13 +358,14 @@ clen = skb->len; esp = x->data; + alen = esp->auth.icv_trunc_len; tfm = esp->conf.tfm; blksize = crypto_tfm_alg_blocksize(tfm); clen = (clen + 2 + blksize-1)&~(blksize-1); if (esp->conf.padlen) clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1); - if ((nfrags = skb_cow_data(skb, clen-skb->len+esp->auth.authlen, &trailer)) < 0) + if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) goto error; /* Fill padding... */ @@ -373,7 +385,7 @@ top_iph->ihl = 5; top_iph->version = 4; top_iph->tos = iph->tos; /* DS disclosed */ - top_iph->tot_len = htons(skb->len + esp->auth.authlen); + top_iph->tot_len = htons(skb->len + alen); top_iph->frag_off = iph->frag_off&htons(IP_DF); if (!(top_iph->frag_off)) ip_select_ident(top_iph, dst, 0); @@ -388,7 +400,7 @@ top_iph = (struct iphdr*)skb_push(skb, iph->ihl*4); memcpy(top_iph, &tmp_iph, iph->ihl*4); iph = &tmp_iph.iph; - top_iph->tot_len = htons(skb->len + esp->auth.authlen); + top_iph->tot_len = htons(skb->len + alen); top_iph->protocol = IPPROTO_ESP; top_iph->check = 0; top_iph->frag_off = iph->frag_off; @@ -411,7 +423,7 @@ goto error; } skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); - crypto_cipher_encrypt(tfm, sg, nfrags); + crypto_cipher_encrypt(tfm, sg, sg, clen); if (unlikely(sg != sgbuf)) kfree(sg); } while (0); @@ -421,10 +433,10 @@ crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); } - if (esp->auth.authlen) { - esp->auth.digest(esp, skb, (u8*)esph-skb->data, - 8+esp->conf.ivlen+clen, trailer->tail); - pskb_put(skb, trailer, esp->auth.authlen); + if (esp->auth.icv_full_len) { + esp->auth.icv(esp, skb, (u8*)esph-skb->data, + 8+esp->conf.ivlen+clen, trailer->tail); + pskb_put(skb, trailer, alen); } ip_send_check(top_iph); @@ -445,6 +457,11 @@ return err; } +/* + * Note: detecting truncated vs. non-truncated authentication data is very + * expensive, so we only support truncated data, which is the recommended + * and common case. + */ int esp_input(struct xfrm_state *x, struct sk_buff *skb) { struct iphdr *iph; @@ -452,7 +469,8 @@ struct esp_data *esp = x->data; struct sk_buff *trailer; int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm); - int elen = skb->len - 8 - esp->conf.ivlen - esp->auth.authlen; + int alen = esp->auth.icv_trunc_len; + int elen = skb->len - 8 - esp->conf.ivlen - alen; int nfrags; if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) @@ -462,17 +480,16 @@ goto out; /* If integrity check is required, do this. */ - if (esp->auth.authlen) { - u8 sum[esp->auth.authlen]; - u8 sum1[esp->auth.authlen]; + if (esp->auth.icv_full_len) { + u8 sum[esp->auth.icv_full_len]; + u8 sum1[alen]; + + esp->auth.icv(esp, skb, 0, skb->len-alen, sum); - esp->auth.digest(esp, skb, 0, skb->len-esp->auth.authlen, sum); - - if (skb_copy_bits(skb, skb->len-esp->auth.authlen, sum1, - esp->auth.authlen)) + if (skb_copy_bits(skb, skb->len-alen, sum1, alen)) BUG(); - if (unlikely(memcmp(sum, sum1, esp->auth.authlen))) { + if (unlikely(memcmp(sum, sum1, alen))) { x->stats.integrity_failed++; goto out; } @@ -481,6 +498,8 @@ if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0) goto out; + skb->ip_summed = CHECKSUM_NONE; + esph = (struct ip_esp_hdr*)skb->data; iph = skb->nh.iph; @@ -501,12 +520,11 @@ goto out; } skb_to_sgvec(skb, sg, 8+esp->conf.ivlen, elen); - crypto_cipher_decrypt(esp->conf.tfm, sg, nfrags); + crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); if (unlikely(sg != sgbuf)) kfree(sg); - if (skb_copy_bits(skb, skb->len-esp->auth.authlen-2, - nexthdr, 2)) + if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) BUG(); padlen = nexthdr[0]; @@ -516,7 +534,7 @@ /* ... check padding bits here. Silly. :-) */ iph->protocol = nexthdr[1]; - pskb_trim(skb, skb->len - esp->auth.authlen - padlen - 2); + pskb_trim(skb, skb->len - alen - padlen - 2); memcpy(workbuf, skb->nh.raw, iph->ihl*4); skb->h.raw = skb_pull(skb, 8 + esp->conf.ivlen); skb->nh.raw += 8 + esp->conf.ivlen; @@ -544,7 +562,7 @@ if (esp->conf.padlen) mtu = (mtu + esp->conf.padlen-1)&~(esp->conf.padlen-1); - return mtu + x->props.header_len + esp->auth.authlen; + return mtu + x->props.header_len + esp->auth.icv_full_len; } void esp4_err(struct sk_buff *skb, u32 info) @@ -581,9 +599,9 @@ crypto_free_tfm(esp->auth.tfm); esp->auth.tfm = NULL; } - if (esp->auth.work_digest) { - kfree(esp->auth.work_digest); - esp->auth.work_digest = NULL; + if (esp->auth.work_icv) { + kfree(esp->auth.work_icv); + esp->auth.work_icv = NULL; } } @@ -591,11 +609,12 @@ { struct esp_data *esp = NULL; + /* null auth and encryption can have zero length keys */ if (x->aalg) { - if (x->aalg->alg_key_len == 0 || x->aalg->alg_key_len > 512) + if (x->aalg->alg_key_len > 512) goto error; } - if (x->ealg == NULL || x->ealg->alg_key_len == 0) + if (x->ealg == NULL) goto error; esp = kmalloc(sizeof(*esp), GFP_KERNEL); @@ -605,21 +624,32 @@ memset(esp, 0, sizeof(*esp)); if (x->aalg) { - int digestsize; + struct xfrm_algo_desc *aalg_desc; esp->auth.key = x->aalg->alg_key; esp->auth.key_len = (x->aalg->alg_key_len+7)/8; esp->auth.tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); if (esp->auth.tfm == NULL) goto error; - esp->auth.digest = esp_hmac_digest; - digestsize = crypto_tfm_alg_digestsize(esp->auth.tfm); - /* XXX RFC2403 and RFC 2404 truncate auth to 96 bit */ - esp->auth.authlen = 12; - if (esp->auth.authlen > digestsize) /* XXX */ - BUG(); - esp->auth.work_digest = kmalloc(digestsize, GFP_KERNEL); - if (!esp->auth.work_digest) + esp->auth.icv = esp_hmac_digest; + + aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name); + BUG_ON(!aalg_desc); + + if (aalg_desc->uinfo.auth.icv_fullbits/8 != + crypto_tfm_alg_digestsize(esp->auth.tfm)) { + printk(KERN_INFO "ESP: %s digestsize %u != %hu\n", + x->aalg->alg_name, + crypto_tfm_alg_digestsize(esp->auth.tfm), + aalg_desc->uinfo.auth.icv_fullbits/8); + goto error; + } + + esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8; + esp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8; + + esp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL); + if (!esp->auth.work_icv) goto error; } esp->conf.key = x->ealg->alg_key; @@ -637,7 +667,6 @@ x->props.header_len = 8 + esp->conf.ivlen; if (x->props.mode) x->props.header_len += 20; - x->props.trailer_len = esp->auth.authlen + crypto_tfm_alg_blocksize(esp->conf.tfm); x->data = esp; return 0; @@ -645,8 +674,8 @@ if (esp) { if (esp->auth.tfm) crypto_free_tfm(esp->auth.tfm); - if (esp->auth.work_digest) - kfree(esp->auth.work_digest); + if (esp->auth.work_icv) + kfree(esp->auth.work_icv); if (esp->conf.tfm) crypto_free_tfm(esp->conf.tfm); kfree(esp); diff -Nru a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c --- a/net/ipv4/fib_hash.c Sun Feb 9 21:13:32 2003 +++ b/net/ipv4/fib_hash.c Sun Feb 9 21:13:32 2003 @@ -941,7 +941,7 @@ if (!iter->zone) goto out; - if (iter->zone->fz_next); + if (iter->zone->fz_next) break; } diff -Nru a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c --- a/net/ipv4/ip_output.c Sun Feb 9 21:13:37 2003 +++ b/net/ipv4/ip_output.c Sun Feb 9 21:13:37 2003 @@ -280,7 +280,7 @@ return ip_finish_output(skb); } -int ip_queue_xmit(struct sk_buff *skb) +int ip_queue_xmit(struct sk_buff *skb, int ipfragok) { struct sock *sk = skb->sk; struct inet_opt *inet = inet_sk(sk); @@ -337,7 +337,7 @@ iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr) + (opt ? opt->optlen : 0)); *((__u16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff)); iph->tot_len = htons(skb->len); - if (ip_dont_fragment(sk, &rt->u.dst)) + if (ip_dont_fragment(sk, &rt->u.dst) && !ipfragok) iph->frag_off = htons(IP_DF); else iph->frag_off = 0; diff -Nru a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig --- a/net/ipv4/netfilter/Kconfig Sun Feb 9 21:13:35 2003 +++ b/net/ipv4/netfilter/Kconfig Sun Feb 9 21:13:35 2003 @@ -148,6 +148,14 @@ config IP_NF_MATCH_DSCP tristate "DSCP match support" depends on IP_NF_IPTABLES + help + This option adds a `DSCP' match, which allows you to match against + the IPv4 header DSCP field (DSCP codepoint). + + The DSCP codepoint can have any value between 0x0 and 0x4f. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. config IP_NF_MATCH_AH_ESP tristate "AH/ESP match support" diff -Nru a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile --- a/net/ipv4/netfilter/Makefile Sun Feb 9 21:13:29 2003 +++ b/net/ipv4/netfilter/Makefile Sun Feb 9 21:13:29 2003 @@ -2,9 +2,6 @@ # Makefile for the netfilter modules on top of IPv4. # -export-objs := ip_conntrack_standalone.o ip_nat_standalone.o \ - ip_tables.o arp_tables.o - # objects for the conntrack and NAT core (used by standalone and backw. compat) ip_nf_conntrack-objs := ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o ip_nf_nat-objs := ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o @@ -25,11 +22,9 @@ # connection tracking helpers obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o ifdef CONFIG_IP_NF_NAT_FTP - export-objs += ip_conntrack_ftp.o endif obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o ifdef CONFIG_IP_NF_NAT_IRC - export-objs += ip_conntrack_irc.o endif # NAT helpers diff -Nru a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c --- a/net/ipv4/netfilter/ip_nat_helper.c Sun Feb 9 21:13:29 2003 +++ b/net/ipv4/netfilter/ip_nat_helper.c Sun Feb 9 21:13:29 2003 @@ -84,7 +84,6 @@ iph = (*skb)->nh.iph; if (iph->protocol == IPPROTO_TCP) { struct tcphdr *tcph = (void *)iph + iph->ihl*4; - void *data = (void *)tcph + tcph->doff*4; DEBUGP("ip_nat_resize_packet: Seq_offset before: "); DUMP_OFFSET(this_way); diff -Nru a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c --- a/net/ipv4/netfilter/ip_queue.c Sun Feb 9 21:13:37 2003 +++ b/net/ipv4/netfilter/ip_queue.c Sun Feb 9 21:13:37 2003 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -496,7 +497,7 @@ if (type <= IPQM_BASE) return; - if(!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) + if (security_netlink_recv(skb)) RCV_SKB_FAIL(-EPERM); write_lock_bh(&queue_lock); diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c --- a/net/ipv4/route.c Sun Feb 9 21:13:37 2003 +++ b/net/ipv4/route.c Sun Feb 9 21:13:37 2003 @@ -2288,7 +2288,7 @@ struct net_device *dev = __dev_get_by_index(iif); err = -ENODEV; if (!dev) - goto out; + goto out_free; skb->protocol = htons(ETH_P_IP); skb->dev = dev; local_bh_disable(); @@ -2307,10 +2307,8 @@ fl.oif = oif; err = ip_route_output_key(&rt, &fl); } - if (err) { - kfree_skb(skb); - goto out; - } + if (err) + goto out_free; skb->dst = &rt->u.dst; if (rtm->rtm_flags & RTM_F_NOTIFY) @@ -2321,16 +2319,20 @@ err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0); if (!err) - goto out; + goto out_free; if (err < 0) { err = -EMSGSIZE; - goto out; + goto out_free; } err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); if (err > 0) err = 0; out: return err; + +out_free: + kfree_skb(skb); + goto out; } int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) diff -Nru a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c --- a/net/ipv4/sysctl_net_ipv4.c Sun Feb 9 21:13:34 2003 +++ b/net/ipv4/sysctl_net_ipv4.c Sun Feb 9 21:13:34 2003 @@ -223,6 +223,8 @@ &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} }; diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c --- a/net/ipv4/tcp_ipv4.c Sun Feb 9 21:13:30 2003 +++ b/net/ipv4/tcp_ipv4.c Sun Feb 9 21:13:30 2003 @@ -75,6 +75,7 @@ extern int sysctl_ip_dynaddr; extern int sysctl_ip_default_ttl; int sysctl_tcp_tw_reuse; +int sysctl_tcp_low_latency; /* Check TCP sequence numbers in ICMP packets. */ #define ICMP_MIN_LENGTH 8 @@ -86,11 +87,11 @@ struct sk_buff *skb); struct tcp_hashinfo __cacheline_aligned tcp_hashinfo = { - .__tcp_lhash_lock = RW_LOCK_UNLOCKED, - .__tcp_lhash_users = ATOMIC_INIT(0), + .__tcp_lhash_lock = RW_LOCK_UNLOCKED, + .__tcp_lhash_users = ATOMIC_INIT(0), .__tcp_lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.__tcp_lhash_wait), - .__tcp_portalloc_lock = SPIN_LOCK_UNLOCKED + .__tcp_portalloc_lock = SPIN_LOCK_UNLOCKED }; /* @@ -1410,11 +1411,11 @@ int sysctl_max_syn_backlog = 256; struct or_calltable or_ipv4 = { - .family = PF_INET, - .rtx_syn_ack = tcp_v4_send_synack, - .send_ack = tcp_v4_or_send_ack, - .destructor = tcp_v4_or_free, - .send_reset = tcp_v4_send_reset, + .family = PF_INET, + .rtx_syn_ack = tcp_v4_send_synack, + .send_ack = tcp_v4_or_send_ack, + .destructor = tcp_v4_or_free, + .send_reset = tcp_v4_send_reset, }; int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) @@ -1696,12 +1697,6 @@ */ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) { -#ifdef CONFIG_FILTER - struct sk_filter *filter = sk->filter; - if (filter && sk_filter(skb, filter)) - goto discard; -#endif /* CONFIG_FILTER */ - if (sk->state == TCP_ESTABLISHED) { /* Fast path */ TCP_CHECK_TIMER(sk); if (tcp_rcv_established(sk, skb, skb->h.th, skb->len)) @@ -1804,6 +1799,9 @@ if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_and_relse; + if (sk_filter(sk, skb, 0)) + goto discard_and_relse; + skb->dev = NULL; bh_lock_sock(sk); @@ -2047,17 +2045,17 @@ } struct tcp_func ipv4_specific = { - .queue_xmit = ip_queue_xmit, - .send_check = tcp_v4_send_check, - .rebuild_header =tcp_v4_rebuild_header, - .conn_request = tcp_v4_conn_request, - .syn_recv_sock =tcp_v4_syn_recv_sock, - .remember_stamp =tcp_v4_remember_stamp, - .net_header_len =sizeof(struct iphdr), - .setsockopt = ip_setsockopt, - .getsockopt = ip_getsockopt, - .addr2sockaddr =v4_addr2sockaddr, - .sockaddr_len = sizeof(struct sockaddr_in), + .queue_xmit = ip_queue_xmit, + .send_check = tcp_v4_send_check, + .rebuild_header = tcp_v4_rebuild_header, + .conn_request = tcp_v4_conn_request, + .syn_recv_sock = tcp_v4_syn_recv_sock, + .remember_stamp = tcp_v4_remember_stamp, + .net_header_len = sizeof(struct iphdr), + .setsockopt = ip_setsockopt, + .getsockopt = ip_getsockopt, + .addr2sockaddr = v4_addr2sockaddr, + .sockaddr_len = sizeof(struct sockaddr_in), }; /* NOTE: A lot of things set to zero explicitly by call to @@ -2543,10 +2541,10 @@ } static struct seq_operations tcp_seq_ops = { - .start = tcp_seq_start, - .next = tcp_seq_next, - .stop = tcp_seq_stop, - .show = tcp_seq_show, + .start = tcp_seq_start, + .next = tcp_seq_next, + .stop = tcp_seq_stop, + .show = tcp_seq_show, }; static int tcp_seq_open(struct inode *inode, struct file *file) @@ -2571,10 +2569,10 @@ } static struct file_operations tcp_seq_fops = { - .open = tcp_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = ip_seq_release, + .open = tcp_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = ip_seq_release, }; int __init tcp_proc_init(void) @@ -2596,23 +2594,23 @@ #endif /* CONFIG_PROC_FS */ struct proto tcp_prot = { - .name = "TCP", - .close = tcp_close, - .connect = tcp_v4_connect, - .disconnect = tcp_disconnect, - .accept = tcp_accept, - .ioctl = tcp_ioctl, - .init = tcp_v4_init_sock, - .destroy = tcp_v4_destroy_sock, - .shutdown = tcp_shutdown, - .setsockopt = tcp_setsockopt, - .getsockopt = tcp_getsockopt, - .sendmsg = tcp_sendmsg, - .recvmsg = tcp_recvmsg, - .backlog_rcv = tcp_v4_do_rcv, - .hash = tcp_v4_hash, - .unhash = tcp_unhash, - .get_port = tcp_v4_get_port, + .name = "TCP", + .close = tcp_close, + .connect = tcp_v4_connect, + .disconnect = tcp_disconnect, + .accept = tcp_accept, + .ioctl = tcp_ioctl, + .init = tcp_v4_init_sock, + .destroy = tcp_v4_destroy_sock, + .shutdown = tcp_shutdown, + .setsockopt = tcp_setsockopt, + .getsockopt = tcp_getsockopt, + .sendmsg = tcp_sendmsg, + .recvmsg = tcp_recvmsg, + .backlog_rcv = tcp_v4_do_rcv, + .hash = tcp_v4_hash, + .unhash = tcp_unhash, + .get_port = tcp_v4_get_port, }; diff -Nru a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c --- a/net/ipv4/tcp_minisocks.c Sun Feb 9 21:13:34 2003 +++ b/net/ipv4/tcp_minisocks.c Sun Feb 9 21:13:34 2003 @@ -952,6 +952,12 @@ if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) goto embryonic_reset; + /* ACK sequence verified above, just make sure ACK is + * set. If ACK not set, just silently drop the packet. + */ + if (!(flg & TCP_FLAG_ACK)) + return NULL; + /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */ if (tp->defer_accept && TCP_SKB_CB(skb)->end_seq == req->rcv_isn+1) { req->acked = 1; diff -Nru a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c --- a/net/ipv4/tcp_output.c Sun Feb 9 21:13:34 2003 +++ b/net/ipv4/tcp_output.c Sun Feb 9 21:13:34 2003 @@ -276,7 +276,7 @@ TCP_INC_STATS(TcpOutSegs); - err = tp->af_specific->queue_xmit(skb); + err = tp->af_specific->queue_xmit(skb, 0); if (err <= 0) return err; @@ -786,13 +786,13 @@ /* Ok. We will be able to collapse the packet. */ __skb_unlink(next_skb, next_skb->list); + memcpy(skb_put(skb, next_skb_size), next_skb->data, next_skb_size); + if (next_skb->ip_summed == CHECKSUM_HW) skb->ip_summed = CHECKSUM_HW; - if (skb->ip_summed != CHECKSUM_HW) { - memcpy(skb_put(skb, next_skb_size), next_skb->data, next_skb_size); + if (skb->ip_summed != CHECKSUM_HW) skb->csum = csum_block_add(skb->csum, next_skb->csum, skb_size); - } /* Update sequence range on original skb. */ TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq; diff -Nru a/net/ipv4/xfrm_user.c b/net/ipv4/xfrm_user.c --- a/net/ipv4/xfrm_user.c Sun Feb 9 21:13:32 2003 +++ b/net/ipv4/xfrm_user.c Sun Feb 9 21:13:32 2003 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -276,9 +277,11 @@ copy_to_user_state(x, p); if (x->aalg) - RTA_PUT(skb, XFRMA_ALG_AUTH, sizeof(*(x->aalg)), x->aalg); + RTA_PUT(skb, XFRMA_ALG_AUTH, + sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg); if (x->ealg) - RTA_PUT(skb, XFRMA_ALG_CRYPT, sizeof(*(x->ealg)), x->ealg); + RTA_PUT(skb, XFRMA_ALG_CRYPT, + sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg); if (x->calg) RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg); @@ -655,6 +658,7 @@ info.in_skb = cb->skb; info.out_skb = skb; info.nlmsg_seq = cb->nlh->nlmsg_seq; + info.this_idx = 0; info.start_idx = cb->args[0]; (void) xfrm_policy_walk(dump_one_policy, &info); cb->args[0] = info.this_idx; @@ -752,7 +756,7 @@ { struct rtattr *xfrma[XFRMA_MAX]; struct xfrm_link *link; - int type, min_len, kind; + int type, min_len; if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) return 0; @@ -768,16 +772,15 @@ goto err_einval; type -= XFRM_MSG_BASE; - kind = (type & 3); link = &xfrm_dispatch[type]; /* All operations require privileges, even GET */ - if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) { + if (security_netlink_recv(skb)) { *errp = -EPERM; return -1; } - if (kind == 2 && (nlh->nlmsg_flags & NLM_F_DUMP)) { + if ((type == 2 || type == 5) && (nlh->nlmsg_flags & NLM_F_DUMP)) { u32 rlen; if (link->dump == NULL) diff -Nru a/net/ipv6/Makefile b/net/ipv6/Makefile --- a/net/ipv6/Makefile Sun Feb 9 21:13:34 2003 +++ b/net/ipv6/Makefile Sun Feb 9 21:13:34 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux TCP/IP (INET6) layer. # -export-objs := ipv6_syms.o - obj-$(CONFIG_IPV6) += ipv6.o ipv6-objs := af_inet6.o ip6_output.o ip6_input.o addrconf.o sit.o \ diff -Nru a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile --- a/net/ipv6/netfilter/Makefile Sun Feb 9 21:13:33 2003 +++ b/net/ipv6/netfilter/Makefile Sun Feb 9 21:13:33 2003 @@ -2,8 +2,6 @@ # Makefile for the netfilter modules on top of IPv6. # -export-objs := ip6_tables.o - # Link order matters here. obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o diff -Nru a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c --- a/net/ipv6/netfilter/ip6_queue.c Sun Feb 9 21:13:30 2003 +++ b/net/ipv6/netfilter/ip6_queue.c Sun Feb 9 21:13:30 2003 @@ -538,10 +538,10 @@ if (type <= IPQM_BASE) return; - - if(!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) - RCV_SKB_FAIL(-EPERM); + if (security_netlink_recv(skb)) + RCV_SKB_FAIL(-EPERM); + write_lock_bh(&queue_lock); if (peer_pid) { diff -Nru a/net/ipv6/route.c b/net/ipv6/route.c --- a/net/ipv6/route.c Sun Feb 9 21:13:34 2003 +++ b/net/ipv6/route.c Sun Feb 9 21:13:34 2003 @@ -1548,14 +1548,14 @@ { struct rtattr **rta = arg; int iif = 0; - int err; + int err = -ENOBUFS; struct sk_buff *skb; struct flowi fl; struct rt6_info *rt; skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); if (skb == NULL) - return -ENOBUFS; + goto out; /* Reserve room for dummy headers, this skb can pass through good chunk of routing engine. @@ -1579,8 +1579,10 @@ if (iif) { struct net_device *dev; dev = __dev_get_by_index(iif); - if (!dev) - return -ENODEV; + if (!dev) { + err = -ENODEV; + goto out_free; + } } fl.oif = 0; @@ -1597,13 +1599,19 @@ fl.nl_u.ip6_u.saddr, iif, RTM_NEWROUTE, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq); - if (err < 0) - return -EMSGSIZE; + if (err < 0) { + err = -EMSGSIZE; + goto out_free; + } err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); - if (err < 0) - return err; - return 0; + if (err > 0) + err = 0; +out: + return err; +out_free: + kfree_skb(skb); + goto out; } void inet6_rt_notify(int event, struct rt6_info *rt) diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c --- a/net/ipv6/tcp_ipv6.c Sun Feb 9 21:13:32 2003 +++ b/net/ipv6/tcp_ipv6.c Sun Feb 9 21:13:32 2003 @@ -60,7 +60,7 @@ struct sk_buff *skb); static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); -static int tcp_v6_xmit(struct sk_buff *skb); +static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok); static struct tcp_func ipv6_mapped; static struct tcp_func ipv6_specific; @@ -934,11 +934,11 @@ } static struct or_calltable or_ipv6 = { - AF_INET6, - tcp_v6_send_synack, - tcp_v6_or_send_ack, - tcp_v6_or_free, - tcp_v6_send_reset + .family = AF_INET6, + .rtx_syn_ack = tcp_v6_send_synack, + .send_ack = tcp_v6_or_send_ack, + .destructor = tcp_v6_or_free, + .send_reset = tcp_v6_send_reset }; static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb) @@ -1470,9 +1470,6 @@ { struct ipv6_pinfo *np = inet6_sk(sk); struct tcp_opt *tp; -#ifdef CONFIG_FILTER - struct sk_filter *filter; -#endif struct sk_buff *opt_skb = NULL; /* Imagine: socket is IPv6. IPv4 packet arrives, @@ -1486,11 +1483,8 @@ if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_do_rcv(sk, skb); -#ifdef CONFIG_FILTER - filter = sk->filter; - if (filter && sk_filter(skb, filter)) + if (sk_filter(sk, skb, 0)) goto discard; -#endif /* CONFIG_FILTER */ /* * socket locking is here for SMP purposes as backlog rcv @@ -1641,6 +1635,9 @@ if(sk->state == TCP_TIME_WAIT) goto do_time_wait; + if (sk_filter(sk, skb, 0)) + goto discard_and_relse; + skb->dev = NULL; bh_lock_sock(sk); @@ -1672,6 +1669,10 @@ kfree_skb(skb); return 0; +discard_and_relse: + sock_put(sk); + goto discard_it; + do_time_wait: if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { TCP_INC_STATS_BH(TcpInErrs); @@ -1746,7 +1747,7 @@ return 0; } -static int tcp_v6_xmit(struct sk_buff *skb) +static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok) { struct sock *sk = skb->sk; struct inet_opt *inet = inet_sk(sk); @@ -1812,18 +1813,18 @@ } static struct tcp_func ipv6_specific = { - tcp_v6_xmit, - tcp_v6_send_check, - tcp_v6_rebuild_header, - tcp_v6_conn_request, - tcp_v6_syn_recv_sock, - tcp_v6_remember_stamp, - sizeof(struct ipv6hdr), - - ipv6_setsockopt, - ipv6_getsockopt, - v6_addr2sockaddr, - sizeof(struct sockaddr_in6) + .queue_xmit = tcp_v6_xmit, + .send_check = tcp_v6_send_check, + .rebuild_header = tcp_v6_rebuild_header, + .conn_request = tcp_v6_conn_request, + .syn_recv_sock = tcp_v6_syn_recv_sock, + .remember_stamp = tcp_v6_remember_stamp, + .net_header_len = sizeof(struct ipv6hdr), + + .setsockopt = ipv6_setsockopt, + .getsockopt = ipv6_getsockopt, + .addr2sockaddr = v6_addr2sockaddr, + .sockaddr_len = sizeof(struct sockaddr_in6) }; /* @@ -1831,18 +1832,18 @@ */ static struct tcp_func ipv6_mapped = { - ip_queue_xmit, - tcp_v4_send_check, - tcp_v4_rebuild_header, - tcp_v6_conn_request, - tcp_v6_syn_recv_sock, - tcp_v4_remember_stamp, - sizeof(struct iphdr), - - ipv6_setsockopt, - ipv6_getsockopt, - v6_addr2sockaddr, - sizeof(struct sockaddr_in6) + .queue_xmit = ip_queue_xmit, + .send_check = tcp_v4_send_check, + .rebuild_header = tcp_v4_rebuild_header, + .conn_request = tcp_v6_conn_request, + .syn_recv_sock = tcp_v6_syn_recv_sock, + .remember_stamp = tcp_v4_remember_stamp, + .net_header_len = sizeof(struct iphdr), + + .setsockopt = ipv6_setsockopt, + .getsockopt = ipv6_getsockopt, + .addr2sockaddr = v6_addr2sockaddr, + .sockaddr_len = sizeof(struct sockaddr_in6) }; @@ -2157,23 +2158,23 @@ } struct proto tcpv6_prot = { - .name = "TCPv6", - .close = tcp_close, - .connect = tcp_v6_connect, - .disconnect = tcp_disconnect, - .accept = tcp_accept, - .ioctl = tcp_ioctl, - .init = tcp_v6_init_sock, - .destroy = tcp_v6_destroy_sock, - .shutdown = tcp_shutdown, - .setsockopt = tcp_setsockopt, - .getsockopt = tcp_getsockopt, - .sendmsg = tcp_sendmsg, - .recvmsg = tcp_recvmsg, - .backlog_rcv = tcp_v6_do_rcv, - .hash = tcp_v6_hash, - .unhash = tcp_unhash, - .get_port = tcp_v6_get_port, + .name = "TCPv6", + .close = tcp_close, + .connect = tcp_v6_connect, + .disconnect = tcp_disconnect, + .accept = tcp_accept, + .ioctl = tcp_ioctl, + .init = tcp_v6_init_sock, + .destroy = tcp_v6_destroy_sock, + .shutdown = tcp_shutdown, + .setsockopt = tcp_setsockopt, + .getsockopt = tcp_getsockopt, + .sendmsg = tcp_sendmsg, + .recvmsg = tcp_recvmsg, + .backlog_rcv = tcp_v6_do_rcv, + .hash = tcp_v6_hash, + .unhash = tcp_unhash, + .get_port = tcp_v6_get_port, }; static struct inet6_protocol tcpv6_protocol = { @@ -2184,13 +2185,13 @@ extern struct proto_ops inet6_stream_ops; static struct inet_protosw tcpv6_protosw = { - .type = SOCK_STREAM, - .protocol = IPPROTO_TCP, - .prot = &tcpv6_prot, - .ops = &inet6_stream_ops, - .capability =-1, - .no_check = 0, - .flags = INET_PROTOSW_PERMANENT, + .type = SOCK_STREAM, + .protocol = IPPROTO_TCP, + .prot = &tcpv6_prot, + .ops = &inet6_stream_ops, + .capability = -1, + .no_check = 0, + .flags = INET_PROTOSW_PERMANENT, }; void __init tcpv6_init(void) diff -Nru a/net/irda/Kconfig b/net/irda/Kconfig --- a/net/irda/Kconfig Sun Feb 9 21:13:32 2003 +++ b/net/irda/Kconfig Sun Feb 9 21:13:32 2003 @@ -22,7 +22,7 @@ will need to install some OBEX application, such as OpenObex : - This support is also available as a module called irda.o. If you + This support is also available as a module called irda. If you want to compile it as a module, say M here and read . diff -Nru a/net/irda/Makefile b/net/irda/Makefile --- a/net/irda/Makefile Sun Feb 9 21:13:35 2003 +++ b/net/irda/Makefile Sun Feb 9 21:13:35 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux IrDA protocol layer. # -export-objs := irsyms.o - obj-$(CONFIG_IRDA) += irda.o obj-$(CONFIG_IRLAN) += irlan/ obj-$(CONFIG_IRNET) += irnet/ diff -Nru a/net/irda/ircomm/Kconfig b/net/irda/ircomm/Kconfig --- a/net/irda/ircomm/Kconfig Sun Feb 9 21:13:28 2003 +++ b/net/irda/ircomm/Kconfig Sun Feb 9 21:13:28 2003 @@ -3,8 +3,8 @@ depends on IRDA help Say Y here if you want to build support for the IrCOMM protocol. If - you want to compile it as a module (you will get ircomm.o and - ircomm-tty.o), say M here and read . + you want to compile it as a module (you will get ircomm and + ircomm-tty), say M here and read . IrCOMM implements serial port emulation, and makes it possible to use all existing applications that understands TTY's with an infrared link. Thus you should be able to use application like PPP, diff -Nru a/net/irda/ircomm/Makefile b/net/irda/ircomm/Makefile --- a/net/irda/ircomm/Makefile Sun Feb 9 21:13:28 2003 +++ b/net/irda/ircomm/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux IrDA IrCOMM protocol layer. # -export-objs := ircomm_core.o - obj-$(CONFIG_IRCOMM) += ircomm.o ircomm-tty.o ircomm-objs := ircomm_core.o ircomm_event.o ircomm_lmp.o ircomm_ttp.o diff -Nru a/net/irda/iriap.c b/net/irda/iriap.c --- a/net/irda/iriap.c Sun Feb 9 21:13:30 2003 +++ b/net/irda/iriap.c Sun Feb 9 21:13:30 2003 @@ -990,7 +990,7 @@ len += sprintf(buf+len, "\n"); /* Careful for priority inversions here ! - * All other uses of attrib spinlock are independant of + * All other uses of attrib spinlock are independent of * the object spinlock, so we are safe. Jean II */ spin_lock(&obj->attribs->hb_spinlock); diff -Nru a/net/irda/irlan/Kconfig b/net/irda/irlan/Kconfig --- a/net/irda/irlan/Kconfig Sun Feb 9 21:13:29 2003 +++ b/net/irda/irlan/Kconfig Sun Feb 9 21:13:29 2003 @@ -3,7 +3,7 @@ depends on IRDA help Say Y here if you want to build support for the IrLAN protocol. If - you want to compile it as a module (irlan.o), say M here and read + you want to compile it as a module (irlan), say M here and read . IrLAN emulates an Ethernet and makes it possible to put up a wireless LAN using infrared beams. diff -Nru a/net/irda/irlmp.c b/net/irda/irlmp.c --- a/net/irda/irlmp.c Sun Feb 9 21:13:36 2003 +++ b/net/irda/irlmp.c Sun Feb 9 21:13:36 2003 @@ -1623,7 +1623,7 @@ ASSERT(lap->magic == LMP_LAP_MAGIC, return TRUE;); /* Careful for priority inversions here ! - * All other uses of attrib spinlock are independant of + * All other uses of attrib spinlock are independent of * the object spinlock, so we are safe. Jean II */ spin_lock(&lap->lsaps->hb_spinlock); @@ -1786,7 +1786,7 @@ len += sprintf(buf+len, "\n"); /* Careful for priority inversions here ! - * All other uses of attrib spinlock are independant of + * All other uses of attrib spinlock are independent of * the object spinlock, so we are safe. Jean II */ spin_lock(&lap->lsaps->hb_spinlock); diff -Nru a/net/irda/irnet/Kconfig b/net/irda/irnet/Kconfig --- a/net/irda/irnet/Kconfig Sun Feb 9 21:13:33 2003 +++ b/net/irda/irnet/Kconfig Sun Feb 9 21:13:33 2003 @@ -3,7 +3,7 @@ depends on IRDA && PPP help Say Y here if you want to build support for the IrNET protocol. If - you want to compile it as a module (irnet.o), say M here and read + you want to compile it as a module (irnet), say M here and read . IrNET is a PPP driver, so you will also need a working PPP subsystem (driver, daemon and config)... diff -Nru a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h --- a/net/irda/irnet/irnet.h Sun Feb 9 21:13:34 2003 +++ b/net/irda/irnet/irnet.h Sun Feb 9 21:13:34 2003 @@ -284,7 +284,7 @@ /* * This set of flags enable and disable all the various warning, * error and debug message of this driver. - * Each section can be enabled and disabled independantly + * Each section can be enabled and disabled independently */ /* In the PPP part */ #define DEBUG_CTRL_TRACE 0 /* Control channel */ diff -Nru a/net/lapb/Makefile b/net/lapb/Makefile --- a/net/lapb/Makefile Sun Feb 9 21:13:28 2003 +++ b/net/lapb/Makefile Sun Feb 9 21:13:28 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux LAPB layer. # -export-objs := lapb_iface.o - obj-$(CONFIG_LAPB) += lapb.o lapb-objs := lapb_in.o lapb_out.o lapb_subr.o lapb_timer.o lapb_iface.o diff -Nru a/net/llc/Makefile b/net/llc/Makefile --- a/net/llc/Makefile Sun Feb 9 21:13:35 2003 +++ b/net/llc/Makefile Sun Feb 9 21:13:35 2003 @@ -18,6 +18,3 @@ llc_main.o llc_s_ac.o llc_conn.o llc_c_st.o llc_stat.o llc_actn.o \ llc_s_ev.o llc_evnt.o llc_pdu.o llc_proc.o llc-$(CONFIG_LLC_UI) += af_llc.o - -# Objects that export symbols. -export-objs := llc_if.o diff -Nru a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c --- a/net/netlink/af_netlink.c Sun Feb 9 21:13:32 2003 +++ b/net/netlink/af_netlink.c Sun Feb 9 21:13:32 2003 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -636,7 +637,12 @@ check them, when this message will be delivered to corresponding kernel module. --ANK (980802) */ - NETLINK_CB(skb).eff_cap = current->cap_effective; + + err = security_netlink_send(skb); + if (err) { + kfree_skb(skb); + goto out; + } err = -EFAULT; if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) { diff -Nru a/net/netsyms.c b/net/netsyms.c --- a/net/netsyms.c Sun Feb 9 21:13:31 2003 +++ b/net/netsyms.c Sun Feb 9 21:13:31 2003 @@ -248,6 +248,8 @@ EXPORT_SYMBOL(ip_route_output_key); EXPORT_SYMBOL(ip_route_input); EXPORT_SYMBOL(icmp_send); +EXPORT_SYMBOL(icmp_statistics); +EXPORT_SYMBOL(icmp_err_convert); EXPORT_SYMBOL(ip_options_compile); EXPORT_SYMBOL(ip_options_undo); EXPORT_SYMBOL(arp_send); @@ -427,6 +429,7 @@ EXPORT_SYMBOL(sysctl_tcp_ecn); EXPORT_SYMBOL(tcp_cwnd_application_limited); EXPORT_SYMBOL(tcp_sendpage); +EXPORT_SYMBOL(sysctl_tcp_low_latency); EXPORT_SYMBOL(tcp_write_xmit); diff -Nru a/net/rxrpc/Makefile b/net/rxrpc/Makefile --- a/net/rxrpc/Makefile Sun Feb 9 21:13:33 2003 +++ b/net/rxrpc/Makefile Sun Feb 9 21:13:33 2003 @@ -2,8 +2,6 @@ # Makefile for Linux kernel Rx RPC # -export-objs := rxrpc_syms.o - rxrpc-objs := \ call.o \ connection.o \ diff -Nru a/net/rxrpc/internal.h b/net/rxrpc/internal.h --- a/net/rxrpc/internal.h Sun Feb 9 21:13:30 2003 +++ b/net/rxrpc/internal.h Sun Feb 9 21:13:30 2003 @@ -54,9 +54,9 @@ while (signal_pending(current)) { siginfo_t sinfo; - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); dequeue_signal(¤t->blocked,&sinfo); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); } } diff -Nru a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c --- a/net/rxrpc/krxiod.c Sun Feb 9 21:13:28 2003 +++ b/net/rxrpc/krxiod.c Sun Feb 9 21:13:28 2003 @@ -47,10 +47,10 @@ daemonize(); /* only certain signals are of interest */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked,0); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); /* 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 Sun Feb 9 21:13:29 2003 +++ b/net/rxrpc/krxsecd.c Sun Feb 9 21:13:29 2003 @@ -59,10 +59,10 @@ daemonize(); /* only certain signals are of interest */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked,0); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); /* 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 Sun Feb 9 21:13:29 2003 +++ b/net/rxrpc/krxtimod.c Sun Feb 9 21:13:29 2003 @@ -77,10 +77,10 @@ complete(&krxtimod_alive); /* only certain signals are of interest */ - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked,0); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); /* loop around looking for things to attend to */ loop: diff -Nru a/net/sched/Kconfig b/net/sched/Kconfig --- a/net/sched/Kconfig Sun Feb 9 21:13:35 2003 +++ b/net/sched/Kconfig Sun Feb 9 21:13:35 2003 @@ -21,7 +21,7 @@ is a routine that allows you to sort your outgoing traffic into classes based on a certain criterion. - This code is also available as a module called sch_cbq.o ( = code + This code is also available as a module called sch_cbq ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -38,7 +38,7 @@ HTB is very similar to the CBQ regarding its goals however is has different properties and different algorithm. - This code is also available as a module called sch_htb.o ( = code + This code is also available as a module called sch_htb ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -55,7 +55,7 @@ Note: this scheduler is currently broken. - This code is also available as a module called sch_csz.o ( = code + This code is also available as a module called sch_csz ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -72,7 +72,7 @@ the flow(s) it is handling to a given virtual circuit (see the top of ). - This code is also available as a module called sch_atm.o ( = code + This code is also available as a module called sch_atm ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -85,7 +85,7 @@ "scheduler" for some of your network devices or as a leaf discipline for the CBQ scheduling algorithm. If unsure, say Y. - This code is also available as a module called sch_prio.o ( = code + This code is also available as a module called sch_prio ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -99,7 +99,7 @@ the top of for details and references about the algorithm). - This code is also available as a module called sch_red.o ( = code + This code is also available as a module called sch_red ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -114,7 +114,7 @@ for details and references about the SFQ algorithm). - This code is also available as a module called sch_sfq.o ( = code + This code is also available as a module called sch_sfq ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -130,7 +130,7 @@ one virtual device. (see the top of for details). - This code is also available as a module called sch_teql.o ( = code + This code is also available as a module called sch_teql ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -144,7 +144,7 @@ leaf discipline for the CBQ scheduling algorithm (see the top of for a description of the TBF algorithm). - This code is also available as a module called sch_tbf.o ( = code + This code is also available as a module called sch_tbf ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -158,7 +158,7 @@ (see the top of for details and references about the algorithm). - This code is also available as a module called sch_gred.o ( = code + This code is also available as a module called sch_gred ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -172,7 +172,7 @@ Technical information on this method, with pointers to associated RFCs, is available at . - This code is also available as a module called sch_dsmark.o ( = code + This code is also available as a module called sch_dsmark ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -185,7 +185,7 @@ and drop packets when this bandwidth exceeds your desired rate. If unsure, say Y. - This code is also available as a module called cls_ingress.o + This code is also available as a module called cls_ingress ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -240,7 +240,7 @@ feature if you want to implement Differentiated Services using sch_dsmark. If unsure, say Y. - This code is also available as a module called cls_tcindex.o + This code is also available as a module called cls_tcindex ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -252,7 +252,7 @@ If you say Y here, you will be able to classify outgoing packets according to the route table entry they matched. If unsure, say Y. - This code is also available as a module called cls_route.o ( = code + This code is also available as a module called cls_route ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -269,7 +269,7 @@ If you say Y here, you will be able to classify outgoing packets according to firewall criteria you specified. - This code is also available as a module called cls_fw.o ( = code + This code is also available as a module called cls_fw ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -281,7 +281,7 @@ If you say Y here, you will be able to classify outgoing packets according to their destination address. If unsure, say Y. - This code is also available as a module called cls_u32.o ( = code + This code is also available as a module called cls_u32 ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -297,7 +297,7 @@ Say Y here if you want to be able to classify outgoing packets based on their RSVP requests. - This code is also available as a module called cls_rsvp.o ( = code + This code is also available as a module called cls_rsvp ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -314,7 +314,7 @@ on their RSVP requests and you are using the new Internet Protocol IPv6 as opposed to the older and more common IPv4. - This code is also available as a module called cls_rsvp6.o ( = code + This code is also available as a module called cls_rsvp6 ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . diff -Nru a/net/sched/sch_htb.c b/net/sched/sch_htb.c --- a/net/sched/sch_htb.c Sun Feb 9 21:13:33 2003 +++ b/net/sched/sch_htb.c Sun Feb 9 21:13:33 2003 @@ -19,7 +19,7 @@ * created test case so that I was able to fix nasty bug * and many others. thanks. * - * $Id: sch_htb.c,v 1.14 2002/09/28 12:55:22 devik Exp devik $ + * $Id: sch_htb.c,v 1.17 2003/01/29 09:22:18 devik Exp devik $ */ #include #include @@ -71,16 +71,12 @@ #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */ #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock) #define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock) -#define HTB_VER 0x30007 /* major must be matched with number suplied by TC as version */ +#define HTB_VER 0x3000a /* major must be matched with number suplied by TC as version */ #if HTB_VER >> 16 != TC_HTB_PROTOVER #error "Mismatched sch_htb.c and pkt_sch.h" #endif -/* temporary debug defines to be removed after beta stage */ -#define DEVIK_MEND(N) -#define DEVIK_MSTART(N) - /* debugging support; S is subsystem, these are defined: 0 - netlink messages 1 - enqueue @@ -421,7 +417,6 @@ if ((delay <= 0 || delay > cl->mbuffer) && net_ratelimit()) printk(KERN_ERR "HTB: suspicious delay in wait_tree d=%ld cl=%X h=%d\n",delay,cl->classid,debug_hint); #endif - DEVIK_MSTART(9); cl->pq_key = jiffies + PSCHED_US2JIFFIE(delay); if (cl->pq_key == jiffies) cl->pq_key++; @@ -440,7 +435,6 @@ } rb_link_node(&cl->pq_node, parent, p); rb_insert_color(&cl->pq_node, &q->wait_pq[cl->level]); - DEVIK_MEND(9); } /** @@ -678,7 +672,6 @@ struct htb_sched *q = (struct htb_sched *)sch->data; struct htb_class *cl = htb_classify(skb,sch); - DEVIK_MSTART(0); if (cl == HTB_DIRECT || !cl) { /* enqueue to helper queue */ if (q->direct_queue.qlen < q->direct_qlen && cl) { @@ -687,25 +680,20 @@ } else { kfree_skb (skb); sch->stats.drops++; - DEVIK_MEND(0); return NET_XMIT_DROP; } } else if (cl->un.leaf.q->enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) { sch->stats.drops++; cl->stats.drops++; - DEVIK_MEND(0); return NET_XMIT_DROP; } else { cl->stats.packets++; cl->stats.bytes += skb->len; - DEVIK_MSTART(1); htb_activate (q,cl); - DEVIK_MEND(1); } sch->q.qlen++; sch->stats.packets++; sch->stats.bytes += skb->len; HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",cl?cl->classid:0,skb); - DEVIK_MEND(0); return NET_XMIT_SUCCESS; } @@ -941,7 +929,6 @@ //struct htb_sched *q = (struct htb_sched *)sch->data; struct htb_class *cl,*start; /* look initial class up in the row */ - DEVIK_MSTART(6); start = cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio); do { @@ -960,8 +947,6 @@ cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio); } while (cl != start); - DEVIK_MEND(6); - DEVIK_MSTART(7); if (likely(skb != NULL)) { if ((cl->un.leaf.deficit[level] -= skb->len) < 0) { HTB_DBG(4,2,"htb_next_cl oldptr=%p quant_add=%d\n", @@ -973,11 +958,8 @@ gives us slightly better performance */ if (!cl->un.leaf.q->q.qlen) htb_deactivate (q,cl); - DEVIK_MSTART(8); htb_charge_class (q,cl,level,skb->len); - DEVIK_MEND(8); } - DEVIK_MEND(7); return skb; } @@ -1005,6 +987,9 @@ struct htb_sched *q = (struct htb_sched *)sch->data; int level; long min_delay; +#ifdef HTB_DEBUG + int evs_used = 0; +#endif HTB_DBG(3,1,"htb_deq dircnt=%d qlen=%d\n",skb_queue_len(&q->direct_queue), sch->q.qlen); @@ -1016,27 +1001,26 @@ return skb; } - DEVIK_MSTART(2); if (!sch->q.qlen) goto fin; PSCHED_GET_TIME(q->now); - min_delay = HZ*5; + min_delay = LONG_MAX; q->nwc_hit = 0; for (level = 0; level < TC_HTB_MAXDEPTH; level++) { /* common case optimization - skip event handler quickly */ int m; long delay; - DEVIK_MSTART(3); if (jiffies - q->near_ev_cache[level] < 0x80000000 || 0) { delay = htb_do_events(q,level); q->near_ev_cache[level] += delay ? delay : HZ; +#ifdef HTB_DEBUG + evs_used++; +#endif } else delay = q->near_ev_cache[level] - jiffies; if (delay && min_delay > delay) min_delay = delay; - DEVIK_MEND(3); - DEVIK_MSTART(5); m = ~q->row_mask[level]; while (m != (int)(-1)) { int prio = ffz (m); @@ -1045,24 +1029,24 @@ if (likely(skb != NULL)) { sch->q.qlen--; sch->flags &= ~TCQ_F_THROTTLED; - DEVIK_MEND(5); goto fin; } } - DEVIK_MEND(5); } - DEVIK_MSTART(4); #ifdef HTB_DEBUG - if (!q->nwc_hit && min_delay >= 5*HZ && net_ratelimit()) { - printk(KERN_ERR "HTB: mindelay=%ld, report it please !\n",min_delay); - htb_debug_dump(q); + if (!q->nwc_hit && min_delay >= 10*HZ && net_ratelimit()) { + if (min_delay == LONG_MAX) { + printk(KERN_ERR "HTB: dequeue bug (%d), report it please !\n", + evs_used); + htb_debug_dump(q); + } else + printk(KERN_WARNING "HTB: mindelay=%ld, some class has " + "too small rate\n",min_delay); } #endif - htb_delay_by (sch,min_delay); - DEVIK_MEND(4); + htb_delay_by (sch,min_delay > 5*HZ ? 5*HZ : min_delay); fin: HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,jiffies,skb); - DEVIK_MEND(2); return skb; } @@ -1433,6 +1417,7 @@ if (!rtab || !ctab) goto failure; if (!cl) { /* new class */ + struct Qdisc *new_q; /* check for valid classid */ if (!classid || TC_H_MAJ(classid^sch->handle) || htb_find(classid,sch)) goto failure; @@ -1456,6 +1441,10 @@ cl->magic = HTB_CMAGIC; #endif + /* create leaf qdisc early because it uses kmalloc(GPF_KERNEL) + so that can't be used inside of sch_tree_lock + -- thanks to Karlis Peisenieks */ + new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); sch_tree_lock(sch); if (parent && !parent->level) { /* turn parent into inner node */ @@ -1474,8 +1463,7 @@ memset (&parent->un.inner,0,sizeof(parent->un.inner)); } /* leaf (we) needs elementary qdisc */ - if (!(cl->un.leaf.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops))) - cl->un.leaf.q = &noop_qdisc; + cl->un.leaf.q = new_q ? new_q : &noop_qdisc; cl->classid = classid; cl->parent = parent; @@ -1503,11 +1491,11 @@ if (!cl->level) { cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum; if (!hopt->quantum && cl->un.leaf.quantum < 1000) { - printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.", cl->classid); + printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.\n", cl->classid); cl->un.leaf.quantum = 1000; } if (!hopt->quantum && cl->un.leaf.quantum > 200000) { - printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.", cl->classid); + printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.\n", cl->classid); cl->un.leaf.quantum = 200000; } if (hopt->quantum) diff -Nru a/net/sctp/Kconfig b/net/sctp/Kconfig --- a/net/sctp/Kconfig Sun Feb 9 21:13:29 2003 +++ b/net/sctp/Kconfig Sun Feb 9 21:13:29 2003 @@ -34,7 +34,7 @@ This protocol support is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you - want). The module will be called sctp.o. If you want to compile it + want). The module will be called sctp. If you want to compile it as a module, say M here and read . If in doubt, say N. diff -Nru a/net/sctp/input.c b/net/sctp/input.c --- a/net/sctp/input.c Sun Feb 9 21:13:28 2003 +++ b/net/sctp/input.c Sun Feb 9 21:13:28 2003 @@ -159,6 +159,10 @@ if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_release; + ret = sk_filter(sk, skb, 1); + if (ret) + goto discard_release; + /* Create an SCTP packet structure. */ chunk = sctp_chunkify(skb, asoc, sk); if (!chunk) { diff -Nru a/net/socket.c b/net/socket.c --- a/net/socket.c Sun Feb 9 21:13:30 2003 +++ b/net/socket.c Sun Feb 9 21:13:30 2003 @@ -77,6 +77,7 @@ #include #include #include +#include #if defined(CONFIG_KMOD) && defined(CONFIG_NET) #include @@ -527,6 +528,10 @@ si->msg = msg; si->size = size; + err = security_socket_sendmsg(sock, msg, size); + if (err) + return err; + err = scm_send(sock, msg, si->scm); if (err >= 0) { err = sock->ops->sendmsg(iocb, sock, msg, size, si->scm); @@ -551,6 +556,7 @@ int __sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int size, int flags) { + int err; struct sock_iocb *si = kiocb_to_siocb(iocb); si->sock = sock; @@ -560,6 +566,10 @@ si->size = size; si->flags = flags; + err = security_socket_recvmsg(sock, msg, size, flags); + if (err) + return err; + memset(si->scm, 0, sizeof(*si->scm)); size = sock->ops->recvmsg(iocb, sock, msg, size, flags, si->scm); @@ -963,6 +973,7 @@ int sock_create(int family, int type, int protocol, struct socket **res) { int i; + int err; struct socket *sock; /* @@ -986,6 +997,10 @@ } family = PF_PACKET; } + + err = security_socket_create(family, type, protocol); + if (err) + return err; #if defined(CONFIG_KMOD) && defined(CONFIG_NET) /* Attempt to load a protocol module if the find failed. @@ -1031,6 +1046,7 @@ } *res = sock; + security_socket_post_create(sock, family, type, protocol); out: net_family_read_unlock(); @@ -1141,8 +1157,14 @@ if((sock = sockfd_lookup(fd,&err))!=NULL) { - if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) + if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) { + err = security_socket_bind(sock, (struct sockaddr *)address, addrlen); + if (err) { + sockfd_put(sock); + return err; + } err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen); + } sockfd_put(sock); } return err; @@ -1163,6 +1185,13 @@ if ((sock = sockfd_lookup(fd, &err)) != NULL) { if ((unsigned) backlog > SOMAXCONN) backlog = SOMAXCONN; + + err = security_socket_listen(sock, backlog); + if (err) { + sockfd_put(sock); + return err; + } + err=sock->ops->listen(sock, backlog); sockfd_put(sock); } @@ -1199,6 +1228,10 @@ newsock->type = sock->type; newsock->ops = sock->ops; + err = security_socket_accept(sock, newsock); + if (err) + goto out_release; + err = sock->ops->accept(sock, newsock, sock->file->f_flags); if (err < 0) goto out_release; @@ -1218,6 +1251,8 @@ if ((err = sock_map_fd(newsock)) < 0) goto out_release; + security_socket_post_accept(sock, newsock); + out_put: sockfd_put(sock); out: @@ -1253,6 +1288,11 @@ err = move_addr_to_kernel(uservaddr, addrlen, address); if (err < 0) goto out_put; + + err = security_socket_connect(sock, (struct sockaddr *)address, addrlen); + if (err) + goto out_put; + err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen, sock->file->f_flags); out_put: @@ -1275,6 +1315,11 @@ sock = sockfd_lookup(fd, &err); if (!sock) goto out; + + err = security_socket_getsockname(sock); + if (err) + goto out_put; + err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 0); if (err) goto out_put; @@ -1299,6 +1344,12 @@ if ((sock = sockfd_lookup(fd, &err))!=NULL) { + err = security_socket_getpeername(sock); + if (err) { + sockfd_put(sock); + return err; + } + err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1); if (!err) err=move_addr_to_user(address,len, usockaddr, usockaddr_len); @@ -1427,6 +1478,12 @@ if ((sock = sockfd_lookup(fd, &err))!=NULL) { + err = security_socket_setsockopt(sock,level,optname); + if (err) { + sockfd_put(sock); + return err; + } + if (level == SOL_SOCKET) err=sock_setsockopt(sock,level,optname,optval,optlen); else @@ -1448,6 +1505,13 @@ if ((sock = sockfd_lookup(fd, &err))!=NULL) { + err = security_socket_getsockopt(sock, level, + optname); + if (err) { + sockfd_put(sock); + return err; + } + if (level == SOL_SOCKET) err=sock_getsockopt(sock,level,optname,optval,optlen); else @@ -1469,6 +1533,12 @@ if ((sock = sockfd_lookup(fd, &err))!=NULL) { + err = security_socket_shutdown(sock, how); + if (err) { + sockfd_put(sock); + return err; + } + err=sock->ops->shutdown(sock, how); sockfd_put(sock); } diff -Nru a/net/sunrpc/Makefile b/net/sunrpc/Makefile --- a/net/sunrpc/Makefile Sun Feb 9 21:13:28 2003 +++ b/net/sunrpc/Makefile Sun Feb 9 21:13:28 2003 @@ -6,8 +6,6 @@ obj-$(CONFIG_SUNRPC) += sunrpc.o -export-objs := sunrpc_syms.o - sunrpc-y := clnt.o xprt.o sched.o \ auth.o auth_null.o auth_unix.o \ svc.o svcsock.o svcauth.o svcauth_unix.o \ diff -Nru a/net/sunrpc/auth_gss/Makefile b/net/sunrpc/auth_gss/Makefile --- a/net/sunrpc/auth_gss/Makefile Sun Feb 9 21:13:31 2003 +++ b/net/sunrpc/auth_gss/Makefile Sun Feb 9 21:13:31 2003 @@ -4,8 +4,6 @@ obj-$(CONFIG_SUNRPC_GSS) += auth_rpcgss.o -export-objs := sunrpcgss_syms.o - auth_rpcgss-objs := auth_gss.o gss_pseudoflavors.o gss_generic_token.o \ sunrpcgss_syms.o gss_mech_switch.o diff -Nru a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c Sun Feb 9 21:13:28 2003 +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c Sun Feb 9 21:13:28 2003 @@ -78,7 +78,7 @@ sg[0].offset = ((long)out & ~PAGE_MASK); sg[0].length = length; - ret = crypto_cipher_encrypt(tfm, sg, 1); + ret = crypto_cipher_encrypt(tfm, sg, sg, length); out: dprintk("gss_k5encrypt returns %d\n",ret); @@ -117,7 +117,7 @@ sg[0].offset = ((long)out & ~PAGE_MASK); sg[0].length = length; - ret = crypto_cipher_decrypt(tfm, sg, 1); + ret = crypto_cipher_decrypt(tfm, sg, sg, length); out: dprintk("gss_k5decrypt returns %d\n",ret); diff -Nru a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c --- a/net/sunrpc/clnt.c Sun Feb 9 21:13:31 2003 +++ b/net/sunrpc/clnt.c Sun Feb 9 21:13:31 2003 @@ -233,27 +233,27 @@ /* Turn off various signals */ if (clnt->cl_intr) { - struct k_sigaction *action = current->sig->action; + struct k_sigaction *action = current->sighand->action; if (action[SIGINT-1].sa.sa_handler == SIG_DFL) sigallow |= sigmask(SIGINT); if (action[SIGQUIT-1].sa.sa_handler == SIG_DFL) sigallow |= sigmask(SIGQUIT); } - spin_lock_irqsave(¤t->sig->siglock, irqflags); + spin_lock_irqsave(¤t->sighand->siglock, irqflags); *oldset = current->blocked; siginitsetinv(¤t->blocked, sigallow & ~oldset->sig[0]); recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, irqflags); + spin_unlock_irqrestore(¤t->sighand->siglock, irqflags); } void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset) { unsigned long irqflags; - spin_lock_irqsave(¤t->sig->siglock, irqflags); + spin_lock_irqsave(¤t->sighand->siglock, irqflags); current->blocked = *oldset; recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, irqflags); + spin_unlock_irqrestore(¤t->sighand->siglock, irqflags); } /* diff -Nru a/net/sunrpc/sched.c b/net/sunrpc/sched.c --- a/net/sunrpc/sched.c Sun Feb 9 21:13:32 2003 +++ b/net/sunrpc/sched.c Sun Feb 9 21:13:32 2003 @@ -964,10 +964,10 @@ daemonize(); - spin_lock_irq(¤t->sig->siglock); + spin_lock_irq(¤t->sighand->siglock); siginitsetinv(¤t->blocked, sigmask(SIGKILL)); recalc_sigpending(); - spin_unlock_irq(¤t->sig->siglock); + spin_unlock_irq(¤t->sighand->siglock); strcpy(current->comm, "rpciod"); @@ -1022,9 +1022,9 @@ } } - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); } /* @@ -1100,9 +1100,9 @@ } interruptible_sleep_on(&rpciod_killer); } - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); out: up(&rpciod_sema); MOD_DEC_USE_COUNT; diff -Nru a/net/sunrpc/svc.c b/net/sunrpc/svc.c --- a/net/sunrpc/svc.c Sun Feb 9 21:13:36 2003 +++ b/net/sunrpc/svc.c Sun Feb 9 21:13:36 2003 @@ -235,9 +235,9 @@ } if (!port) { - spin_lock_irqsave(¤t->sig->siglock, flags); + spin_lock_irqsave(¤t->sighand->siglock, flags); recalc_sigpending(); - spin_unlock_irqrestore(¤t->sig->siglock, flags); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); } return error; diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c --- a/net/unix/af_unix.c Sun Feb 9 21:13:33 2003 +++ b/net/unix/af_unix.c Sun Feb 9 21:13:33 2003 @@ -115,6 +115,7 @@ #include #include #include +#include int sysctl_unix_max_dgram_qlen = 10; @@ -816,6 +817,11 @@ err = -EPERM; if (!unix_may_send(sk, other)) goto out_unlock; + + err = security_unix_may_send(sk->socket, other->socket); + if (err) + goto out_unlock; + } else { /* * 1003.1g breaking connected state with AF_UNSPEC @@ -981,6 +987,12 @@ goto restart; } + err = security_unix_stream_connect(sock, other->socket, newsk); + if (err) { + unix_state_wunlock(sk); + goto out_unlock; + } + /* The way is open! Fastly set all the necessary fields... */ sock_hold(sk); @@ -1278,6 +1290,10 @@ err = -EPIPE; if (other->shutdown&RCV_SHUTDOWN) + goto out_unlock; + + err = security_unix_may_send(sk->socket, other->socket); + if (err) goto out_unlock; if (unix_peer(other) != sk && diff -Nru a/net/wanrouter/Makefile b/net/wanrouter/Makefile --- a/net/wanrouter/Makefile Sun Feb 9 21:13:29 2003 +++ b/net/wanrouter/Makefile Sun Feb 9 21:13:29 2003 @@ -2,8 +2,6 @@ # Makefile for the Linux WAN router layer. # -export-objs := wanmain.o - obj-$(CONFIG_WAN_ROUTER) += wanrouter.o wanrouter-objs := wanproc.o wanmain.o diff -Nru a/scripts/Makefile.build b/scripts/Makefile.build --- a/scripts/Makefile.build Sun Feb 9 21:13:35 2003 +++ b/scripts/Makefile.build Sun Feb 9 21:13:35 2003 @@ -15,8 +15,12 @@ include scripts/Makefile.lib +ifdef export-objs +$(warning kbuild: $(obj)/Makefile - Usage of export-objs is obsolete in 2.5. Please fix!) +endif + ifdef O_TARGET -$(error kbuild: $(obj)/Makefile - Usage of O_TARGET := $(O_TARGET) is obsolete in 2.5. Please fix!) +$(warning kbuild: $(obj)/Makefile - Usage of O_TARGET := $(O_TARGET) is obsolete in 2.5. Please fix!) endif ifdef L_TARGET @@ -45,11 +49,66 @@ endif endif +ifdef CONFIG_MODVERSIONS +modules := $(obj-m) +touch-module = @echo $(@:.o=.ko) > .tmp_versions/$(@F:.o=.mod) +else +modules := $(obj-m:.o=.ko) +endif + __build: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \ - $(if $(KBUILD_MODULES),$(obj-m:.o=.ko)) \ + $(if $(KBUILD_MODULES),$(modules)) \ $(subdir-ym) $(build-targets) @: +# Module versioning +# --------------------------------------------------------------------------- + +ifdef CONFIG_MODVERSIONS + +# $(call if_changed_rule,vcc_o_c) does essentially the same as the +# normal $(call if_changed_dep,cc_o_c), i.e. compile an object file +# from a C file, keeping track of the command line and dependencies. +# +# However, actually it does: +# o compile a .tmp_.o from .c +# o if .tmp_.o doesn't contain a __ksymtab version, i.e. does +# not export symbols, we just rename .tmp_.o to .o and +# are done. +# o otherwise, we calculate symbol versions using the good old +# genksyms on the preprocessed source and postprocess them in a way +# that they are usable as a linker script +# o generate .o from .tmp_.o using the linker to +# replace the unresolved symbols __crc_exported_symbol with +# the actual value of the checksum generated by genksyms + +quiet_cmd_vcc_o_c = CC $(quiet_modtag) $@ +cmd_vcc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< + +define rule_vcc_o_c + $(if $($(quiet)cmd_vcc_o_c),echo ' $($(quiet)cmd_vcc_o_c)';) \ + $(cmd_vcc_o_c); \ + \ + if ! $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ + mv $(@D)/.tmp_$(@F) $@; \ + else \ + $(CPP) -D__GENKSYMS__ $(c_flags) $< \ + | $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) \ + | sed -n 's/\#define __ver_\(\w*\)\W*\(\w*\)/__crc_\1 = 0x\2 ;/gp' \ + > $(@D)/.tmp_$(@F:.o=.ver); \ + \ + $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ + -T $(@D)/.tmp_$(@F:.o=.ver); \ + rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ + fi; + \ + scripts/fixdep $(depfile) $@ '$(cmd_vcc_o_c)' > $(@D)/.$(@F).tmp; \ + rm -f $(depfile); \ + mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd +endef + +endif + # Compile C sources (.c) # --------------------------------------------------------------------------- @@ -69,11 +128,6 @@ $(obj-m) : quiet_modtag := [M] -$(export-objs) : export_flags := $(EXPORT_FLAGS) -$(export-objs:.o=.i) : export_flags := $(EXPORT_FLAGS) -$(export-objs:.o=.s) : export_flags := $(EXPORT_FLAGS) -$(export-objs:.o=.lst): export_flags := $(EXPORT_FLAGS) - # Default for not multi-part modules modname = $(*F) @@ -102,7 +156,20 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< %.o: %.c FORCE +ifdef CONFIG_MODVERSIONS + $(call if_changed_rule,vcc_o_c) +else $(call if_changed_dep,cc_o_c) +endif + +# For modversioning, we need to special case single-part modules +# to mark them in $(MODVERDIR) + +ifdef CONFIG_MODVERSIONS +$(single-used-m): %.o: %.c FORCE + $(touch-module) + $(call if_changed_rule,vcc_o_c) +endif quiet_cmd_cc_lst_c = MKLST $@ cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ @@ -147,7 +214,7 @@ quiet_cmd_link_o_target = LD $@ # If the list of objects to link is empty, just create an empty O_TARGET cmd_link_o_target = $(if $(strip $(obj-y)),\ - $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^),\ + $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\ rm -f $@; $(AR) rcs $@) $(O_TARGET): $(obj-y) FORCE @@ -172,19 +239,20 @@ # # Rule to link composite objects # +# Composite objects are specified in kbuild makefile as follows: +# -objs := +# or +# -y := +link_multi_deps = \ +$(filter $(addprefix $(obj)/, \ +$($(subst $(obj)/,,$(@:.o=-objs))) \ +$($(subst $(obj)/,,$(@:.o=-y)))), $^) + quiet_cmd_link_multi-y = LD $@ -cmd_link_multi-y = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.o=-objs))) $($(subst $(obj)/,,$(@:.o=-y)))),$^) +cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) quiet_cmd_link_multi-m = LD [M] $@ -cmd_link_multi-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.ko=-objs))) $($(subst $(obj)/,,$(@:.ko=-y)))),$^) init/vermagic.o - -quiet_cmd_link_single-m = LD [M] $@ -cmd_link_single-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $< init/vermagic.o - -# Don't rebuilt vermagic.o unless we actually are in the init/ dir -ifneq ($(obj),init) -init/vermagic.o: ; -endif +cmd_link_multi-m = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $(link_multi_deps) # We would rather have a list of rules like # foo.o: $(foo-objs) @@ -193,13 +261,34 @@ $(multi-used-y) : %.o: $(multi-objs-y) FORCE $(call if_changed,link_multi-y) -$(multi-used-m:.o=.ko) : %.ko: $(multi-objs-m) init/vermagic.o FORCE +$(multi-used-m) : %.o: $(multi-objs-m) FORCE + $(touch-module) $(call if_changed,link_multi-m) -$(single-used-m:.o=.ko) : %.ko: %.o init/vermagic.o FORCE - $(call if_changed,link_single-m) +targets += $(multi-used-y) $(multi-used-m) + +# +# Rule to link modules ( .o -> .ko ) +# + +# With CONFIG_MODVERSIONS, generation of the final .ko is handled +# by scripts/Makefile.modver +ifndef CONFIG_MODVERSIONS -targets += $(multi-used-y) $(multi-used-m:.o=.ko) $(single-used-m:.o=.ko) +quiet_cmd_link_module = LD [M] $@ +cmd_link_module = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $< init/vermagic.o + +# Don't rebuilt vermagic.o unless we actually are in the init/ dir +ifneq ($(obj),init) +init/vermagic.o: ; +endif + +$(single-used-m:.o=.ko) $(multi-used-m:.o=.ko): %.ko: %.o init/vermagic.o FORCE + $(call if_changed,link_module) + +targets += $(single-used-m:.o=.ko) $(multi-used-m:.o=.ko) + +endif # Compile programs on the host # =========================================================================== diff -Nru a/scripts/Makefile.lib b/scripts/Makefile.lib --- a/scripts/Makefile.lib Sun Feb 9 21:13:32 2003 +++ b/scripts/Makefile.lib Sun Feb 9 21:13:32 2003 @@ -34,14 +34,9 @@ subdir-ym := $(sort $(subdir-y) $(subdir-m)) -# export.o is never a composite object, since $(export-objs) has a -# fixed meaning (== objects which EXPORT_SYMBOL()) -__obj-y = $(filter-out export.o,$(obj-y)) -__obj-m = $(filter-out export.o,$(obj-m)) - # if $(foo-objs) exists, foo.o is a composite object -multi-used-y := $(sort $(foreach m,$(__obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) -multi-used-m := $(sort $(foreach m,$(__obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) +multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) +multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) multi-used := $(multi-used-y) $(multi-used-m) single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m))) @@ -59,9 +54,6 @@ real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(EXTRA_TARGETS) real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) -# Only build module versions for files which are selected to be built -export-objs := $(filter $(export-objs),$(real-objs-y) $(real-objs-m)) - # C code # Executables compiled from a single .c file host-csingle := $(foreach m,$(host-progs),$(if $($(m)-objs),,$(m))) @@ -96,7 +88,6 @@ build-targets := $(addprefix $(obj)/,$(build-targets)) obj-y := $(addprefix $(obj)/,$(obj-y)) obj-m := $(addprefix $(obj)/,$(obj-m)) -export-objs := $(addprefix $(obj)/,$(export-objs)) subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y)) real-objs-y := $(addprefix $(obj)/,$(real-objs-y)) real-objs-m := $(addprefix $(obj)/,$(real-objs-m)) @@ -130,13 +121,14 @@ modname_flags = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname)))) c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \ $(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \ - $(basename_flags) $(modname_flags) $(export_flags) + $(basename_flags) $(modname_flags) a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS)\ $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o) hostc_flags = -Wp,-MD,$(depfile) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS)\ $(HOSTCFLAGS_$(*F).o) hostcxx_flags = -Wp,-MD,$(depfile) $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS)\ $(HOSTCXXFLAGS_$(*F).o) +ld_flags = $(LDFLAGS) $(EXTRA_LDFLAGS) # Finds the multi-part object the current object will be linked into modname-multi = $(sort $(foreach m,$(multi-used),\ @@ -217,7 +209,6 @@ $(filter-out $(cmd_$(1)),$(cmd_$@))\ $(filter-out $(cmd_$@),$(cmd_$(1)))),\ @set -e; \ - mkdir -p $(dir $@); \ $(rule_$(1))) # If quiet is set, only print short version of command diff -Nru a/scripts/Makefile.modver b/scripts/Makefile.modver --- a/scripts/Makefile.modver Sun Feb 9 21:13:31 2003 +++ b/scripts/Makefile.modver Sun Feb 9 21:13:31 2003 @@ -2,105 +2,87 @@ # Module versions # =========================================================================== -src := $(obj) +.PHONY: __modversions +__modversions: -MODVERDIR := include/linux/modules +include scripts/Makefile.lib -.PHONY: modver -modver: +# -include .config +__modules := $(shell cd $(MODVERDIR); cat *.mod) +modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o))) -include $(obj)/Makefile +ifneq ($(filter-out $(modules),$(__modules)),) + $(warning *** Uh-oh, you have stale module entries. You messed with SUBDIRS, don't complain if something goes wrong.) +endif -include scripts/Makefile.lib +__modversions: $(modules) + @: -# =========================================================================== +# The final module link -ifeq ($(strip $(export-objs)),) +quiet_cmd_ld_ko_o = LD [M] $@ + cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ + $(filter-out FORCE,$^) -# If we don't export any symbols in this dir, just descend -# --------------------------------------------------------------------------- +init/vermagic.o: ; -modver: $(subdir-ym) - @: +$(modules): %.ko :%.o %.ver.o init/vermagic.o FORCE + $(call if_changed,ld_ko_o) -else +targets += $(modules) -# This sets version suffixes on exported symbols -# --------------------------------------------------------------------------- +# Compile version info for unresolved symbols -# -# Added the SMP separator to stop module accidents between uniprocessor -# and SMP Intel boxes - AC - from bits by Michael Chastain -# +quiet_cmd_cc_o_c = CC $@ + cmd_cc_o_c = $(CC) $(CFLAGS) -c -o $@ $< -ifdef CONFIG_SMP - genksyms_smp_prefix := -p smp_ -else - genksyms_smp_prefix := -endif +$(modules:.ko=.ver.o): %.ver.o: %.ver.c FORCE + $(call if_changed,cc_o_c) -# Don't include modversions.h, we're just about to generate it here. +targets += $(modules:.ko=.ver.o) -CFLAGS_MODULE := $(filter-out -include include/linux/modversions.h,$(CFLAGS_MODULE)) +# Generate C source with version info for unresolved symbols -$(addprefix $(MODVERDIR)/,$(real-objs-y:.o=.ver)): modkern_cflags := $(CFLAGS_KERNEL) -$(addprefix $(MODVERDIR)/,$(real-objs-m:.o=.ver)): modkern_cflags := $(CFLAGS_MODULE) -$(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver)): export_flags := -D__GENKSYMS__ -# Default for not multi-part modules -modname = $(*F) - -$(addprefix $(MODVERDIR)/,$(multi-objs:.o=.ver)) : modname = $(modname-multi) - -# Our objects only depend on modversions.h, not on the individual .ver -# files (fix-dep filters them), so touch modversions.h if any of the .ver -# files changes - -quiet_cmd_cc_ver_c = MKVER include/linux/modules/$*.ver -cmd_cc_ver_c = $(CPP) $(c_flags) $< | $(GENKSYMS) $(genksyms_smp_prefix) \ - -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp - -# Okay, let's explain what's happening in rule_make_cc_ver_c: -# o echo the command -# o execute the command -# o If the $(CPP) fails, we won't notice because it's output is piped -# to $(GENKSYMS) which does not fail. We recognize this case by -# looking if the generated $(depfile) exists, though. -# o If the .ver file changed, touch modversions.h, which is our marker -# of any changed .ver files. -# o Move command line and deps into their normal .*.cmd place. - -define rule_cc_ver_c - $(if $($(quiet)cmd_cc_ver_c),echo ' $($(quiet)cmd_cc_ver_c)';) \ - $(cmd_cc_ver_c); \ - if [ ! -r $(depfile) ]; then exit 1; fi; \ - scripts/fixdep $(depfile) $@ '$(cmd_cc_ver_c)' > $(@D)/.$(@F).tmp; \ - rm -f $(depfile); \ - if [ ! -r $@ ] || cmp -s $@ $@.tmp; then \ - touch include/linux/modversions.h; \ - fi; \ - mv -f $@.tmp $@ - mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd +define rule_mkver_o_c + echo ' MKVER $@'; \ + ( echo "#include "; \ + echo ""; \ + echo "static const struct modversion_info ____versions[]"; \ + echo "__attribute__((section(\"__versions\"))) = {"; \ + for sym in `nm -u $<`; do \ + grep "\"$$sym\"" .tmp_all-versions \ + || echo "*** Warning: $(<:.o=.ko): \"$$sym\" unresolved!" >&2;\ + done; \ + echo "};"; \ + ) > $@ endef -targets := $(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver)) +$(modules:.ko=.ver.c): %.ver.c: %.o .tmp_all-versions FORCE + $(call if_changed_rule,mkver_o_c) -$(MODVERDIR)/%.ver: %.c FORCE - @$(call if_changed_rule,cc_ver_c) +targets += $(modules:.ko=.ver.c)) -modver: $(targets) $(subdir-ym) - @mkdir -p $(dir $(addprefix .tmp_export-objs/modules/,$(export-objs:.o=.ver))) - @touch $(addprefix .tmp_export-objs/modules/,$(export-objs:.o=.ver)) +# Extract all checksums for all exported symbols -endif # export-objs +export-objs := $(shell for m in vmlinux $(modules:.ko=.o); do objdump -h $$m | grep -q __ksymtab && echo $$m; done) + +cmd_gen-all-versions = mksyms $(export-objs) +define rule_gen-all-versions + echo ' MKSYMS $@'; \ + for mod in $(export-objs); do \ + modname=`basename $$mod`; \ + nm $$mod \ + | grep ' __crc_' \ + | sed "s/\([^ ]*\) A __crc_\(.*\)/{ 0x\1, \"\2\" }, \/* $$modname *\//g;s/.* w __crc_\(.*\)/{ 0x0 , \"\1\" }, \/* $$modname *\//g"; \ + done > $@; \ + echo 'cmd_$@ := $(cmd_$(1))' > $(@D)/.$(@F).cmd +endef -# Descending -# --------------------------------------------------------------------------- +.tmp_all-versions: $(export-objs) FORCE + $(call if_changed_rule,gen-all-versions) -.PHONY: $(subdir-ym) -$(subdir-ym): - $(Q)$(MAKE) -f scripts/Makefile.modver obj=$@ +targets += .tmp_all-versions # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- diff -Nru a/scripts/per-cpu-check.awk b/scripts/per-cpu-check.awk --- a/scripts/per-cpu-check.awk Sun Feb 9 21:13:35 2003 +++ b/scripts/per-cpu-check.awk Sun Feb 9 21:13:35 2003 @@ -6,7 +6,7 @@ IN_PER_CPU=0 } -/__per_cpu$$/ && ! ( / __ksymtab_/ || / __kstrtab_/ ) { +/__per_cpu$$/ && ! ( / __ksymtab_/ || / __kstrtab_/ || / __kcrctab_/ ) { if (!IN_PER_CPU) { print $$3 " not in per-cpu section" > "/dev/stderr"; FOUND=1; diff -Nru a/scripts/ver_linux b/scripts/ver_linux --- a/scripts/ver_linux Sun Feb 9 21:13:33 2003 +++ b/scripts/ver_linux Sun Feb 9 21:13:33 2003 @@ -28,7 +28,7 @@ mount --version | awk -F\- '{print "mount ", $NF}' -rmmod -V 2>&1 | awk 'NR==1 {print "module-init-tools ",$NF}' +depmod -V 2>&1 | awk 'NR==1 {print "module-init-tools ",$NF}' tune2fs 2>&1 | grep "^tune2fs" | sed 's/,//' | awk \ 'NR==1 {print "e2fsprogs ", $2}' diff -Nru a/security/Kconfig b/security/Kconfig --- a/security/Kconfig Sun Feb 9 21:13:34 2003 +++ b/security/Kconfig Sun Feb 9 21:13:34 2003 @@ -15,6 +15,15 @@ If you are unsure how to answer this question, answer N. +config SECURITY_NETWORK + bool "Socket and Networking Security Hooks" + depends on SECURITY + help + This enables the socket and networking security hooks. + If enabled, a security module can use these hooks to + implement socket and networking access controls. + If you are unsure how to answer this question, answer N. + config SECURITY_CAPABILITIES tristate "Default Linux Capabilities" depends on SECURITY!=n diff -Nru a/security/Makefile b/security/Makefile --- a/security/Makefile Sun Feb 9 21:13:34 2003 +++ b/security/Makefile Sun Feb 9 21:13:34 2003 @@ -2,9 +2,6 @@ # Makefile for the kernel security code # -# Objects that export symbols -export-objs := security.o capability.o - # if we don't select a security model, use the default capabilities ifneq ($(CONFIG_SECURITY),y) obj-y += capability.o diff -Nru a/security/capability.c b/security/capability.c --- a/security/capability.c Sun Feb 9 21:13:31 2003 +++ b/security/capability.c Sun Feb 9 21:13:31 2003 @@ -120,28 +120,26 @@ { /* Derived from fs/exec.c:compute_creds. */ kernel_cap_t new_permitted, working; - int do_unlock = 0; new_permitted = cap_intersect (bprm->cap_permitted, cap_bset); working = cap_intersect (bprm->cap_inheritable, current->cap_inheritable); new_permitted = cap_combine (new_permitted, working); + task_lock(current); if (!cap_issubset (new_permitted, current->cap_permitted)) { current->mm->dumpable = 0; - lock_kernel (); if (must_not_trace_exec (current) || atomic_read (¤t->fs->count) > 1 || atomic_read (¤t->files->count) > 1 - || atomic_read (¤t->sig->count) > 1) { + || atomic_read (¤t->sighand->count) > 1) { if (!capable (CAP_SETPCAP)) { new_permitted = cap_intersect (new_permitted, current-> cap_permitted); } } - do_unlock = 1; } /* For init, we want to retain the capabilities set @@ -154,9 +152,7 @@ } /* AUD: Audit candidate if current->cap_effective is set */ - - if (do_unlock) - unlock_kernel (); + task_unlock(current); current->keep_capabilities = 0; } @@ -286,6 +282,8 @@ .capset_check = cap_capset_check, .capset_set = cap_capset_set, .capable = cap_capable, + .netlink_send = cap_netlink_send, + .netlink_recv = cap_netlink_recv, .bprm_compute_creds = cap_bprm_compute_creds, .bprm_set_security = cap_bprm_set_security, diff -Nru a/security/dummy.c b/security/dummy.c --- a/security/dummy.c Sun Feb 9 21:13:29 2003 +++ b/security/dummy.c Sun Feb 9 21:13:29 2003 @@ -20,7 +20,7 @@ #include #include #include - +#include static int dummy_ptrace (struct task_struct *parent, struct task_struct *child) { @@ -597,6 +597,118 @@ return 0; } +static int dummy_netlink_send (struct sk_buff *skb) +{ + if (current->euid == 0) + cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN); + else + NETLINK_CB (skb).eff_cap = 0; + return 0; +} + +static int dummy_netlink_recv (struct sk_buff *skb) +{ + if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN)) + return -EPERM; + return 0; +} + +#ifdef CONFIG_SECURITY_NETWORK +static int dummy_unix_stream_connect (struct socket *sock, + struct socket *other, + struct sock *newsk) +{ + return 0; +} + +static int dummy_unix_may_send (struct socket *sock, + struct socket *other) +{ + return 0; +} + +static int dummy_socket_create (int family, int type, int protocol) +{ + return 0; +} + +static void dummy_socket_post_create (struct socket *sock, int family, int type, + int protocol) +{ + return; +} + +static int dummy_socket_bind (struct socket *sock, struct sockaddr *address, + int addrlen) +{ + return 0; +} + +static int dummy_socket_connect (struct socket *sock, struct sockaddr *address, + int addrlen) +{ + return 0; +} + +static int dummy_socket_listen (struct socket *sock, int backlog) +{ + return 0; +} + +static int dummy_socket_accept (struct socket *sock, struct socket *newsock) +{ + return 0; +} + +static void dummy_socket_post_accept (struct socket *sock, + struct socket *newsock) +{ + return; +} + +static int dummy_socket_sendmsg (struct socket *sock, struct msghdr *msg, + int size) +{ + return 0; +} + +static int dummy_socket_recvmsg (struct socket *sock, struct msghdr *msg, + int size, int flags) +{ + return 0; +} + +static int dummy_socket_getsockname (struct socket *sock) +{ + return 0; +} + +static int dummy_socket_getpeername (struct socket *sock) +{ + return 0; +} + +static int dummy_socket_setsockopt (struct socket *sock, int level, int optname) +{ + return 0; +} + +static int dummy_socket_getsockopt (struct socket *sock, int level, int optname) +{ + return 0; +} + +static int dummy_socket_shutdown (struct socket *sock, int how) +{ + return 0; +} + +static int dummy_socket_sock_rcv_skb (struct sock *sk, struct sk_buff *skb) +{ + return 0; +} +#endif /* CONFIG_SECURITY_NETWORK */ + static int dummy_register_security (const char *name, struct security_operations *ops) { return -EINVAL; @@ -723,7 +835,28 @@ set_to_dummy_if_null(ops, sem_associate); set_to_dummy_if_null(ops, sem_semctl); set_to_dummy_if_null(ops, sem_semop); + set_to_dummy_if_null(ops, netlink_send); + set_to_dummy_if_null(ops, netlink_recv); set_to_dummy_if_null(ops, register_security); set_to_dummy_if_null(ops, unregister_security); +#ifdef CONFIG_SECURITY_NETWORK + set_to_dummy_if_null(ops, unix_stream_connect); + set_to_dummy_if_null(ops, unix_may_send); + set_to_dummy_if_null(ops, socket_create); + set_to_dummy_if_null(ops, socket_post_create); + set_to_dummy_if_null(ops, socket_bind); + set_to_dummy_if_null(ops, socket_connect); + set_to_dummy_if_null(ops, socket_listen); + set_to_dummy_if_null(ops, socket_accept); + set_to_dummy_if_null(ops, socket_post_accept); + set_to_dummy_if_null(ops, socket_sendmsg); + set_to_dummy_if_null(ops, socket_recvmsg); + set_to_dummy_if_null(ops, socket_getsockname); + set_to_dummy_if_null(ops, socket_getpeername); + set_to_dummy_if_null(ops, socket_setsockopt); + set_to_dummy_if_null(ops, socket_getsockopt); + set_to_dummy_if_null(ops, socket_shutdown); + set_to_dummy_if_null(ops, socket_sock_rcv_skb); +#endif /* CONFIG_SECURITY_NETWORK */ } diff -Nru a/sound/Makefile b/sound/Makefile --- a/sound/Makefile Sun Feb 9 21:13:30 2003 +++ b/sound/Makefile Sun Feb 9 21:13:30 2003 @@ -1,8 +1,6 @@ # Makefile for the Linux sound card driver # -export-objs := sound_core.o - obj-$(CONFIG_SOUND) += soundcore.o obj-$(CONFIG_SOUND_PRIME) += oss/ obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ diff -Nru a/sound/core/Makefile b/sound/core/Makefile --- a/sound/core/Makefile Sun Feb 9 21:13:34 2003 +++ b/sound/core/Makefile Sun Feb 9 21:13:34 2003 @@ -3,8 +3,6 @@ # Copyright (c) 1999,2001 by Jaroslav Kysela # -export-objs := sound.o pcm.o pcm_lib.o rawmidi.o timer.o hwdep.o - snd-objs := sound.o init.o memory.o info.o control.o misc.o \ device.o wrappers.o ifeq ($(CONFIG_ISA),y) @@ -18,7 +16,6 @@ pcm_memory.o ifeq ($(CONFIG_PCI),y) snd-pcm-objs += pcm_sgbuf.o -export-objs += pcm_sgbuf.o endif snd-rawmidi-objs := rawmidi.o diff -Nru a/sound/core/control.c b/sound/core/control.c --- a/sound/core/control.c Sun Feb 9 21:13:29 2003 +++ b/sound/core/control.c Sun Feb 9 21:13:29 2003 @@ -48,9 +48,6 @@ snd_ctl_file_t *ctl; int err; -#ifdef LINUX_2_2 - MOD_INC_USE_COUNT; -#endif card = snd_cards[cardnum]; if (!card) { err = -ENODEV; @@ -82,13 +79,10 @@ return 0; __error: - module_put(card->module); + module_put(card->module); __error2: snd_card_file_remove(card, file); __error1: -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif return err; } @@ -131,9 +125,6 @@ snd_magic_kfree(ctl); module_put(card->module); snd_card_file_remove(card, file); -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif return 0; } @@ -178,6 +169,15 @@ read_unlock(&card->ctl_files_rwlock); } +/** + * snd_ctl_new - create a control instance from the template + * @control: the control template + * + * Allocates a new snd_kcontrol_t instance and copies the given template + * to the new instance. + * + * Returns the pointer of the new instance, or NULL on failure. + */ snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control) { snd_kcontrol_t *kctl; @@ -190,6 +190,17 @@ return kctl; } +/** + * snd_ctl_new1 - create a control instance from the template + * @ncontrol: the initialization record + * @private_data: the private data to set + * + * Allocates a new snd_kcontrol_t instance and initialize from the given + * template. When the access field of ncontrol is 0, it's assumed as + * READWRITE access. + * + * Returns the pointer of the newly generated instance, or NULL on failure. + */ snd_kcontrol_t *snd_ctl_new1(snd_kcontrol_new_t * ncontrol, void *private_data) { snd_kcontrol_t kctl; @@ -200,7 +211,8 @@ kctl.id.iface = ncontrol->iface; kctl.id.device = ncontrol->device; kctl.id.subdevice = ncontrol->subdevice; - strncpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name)-1); + if (ncontrol->name) + strncpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name)-1); kctl.id.index = ncontrol->index; kctl.access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|SNDRV_CTL_ELEM_ACCESS_INACTIVE|SNDRV_CTL_ELEM_ACCESS_INDIRECT)); @@ -212,6 +224,14 @@ return snd_ctl_new(&kctl); } +/** + * snd_ctl_free_one - release the control instance + * @kcontrol: the control instance + * + * Releases the control instance created via snd_ctl_new() + * or snd_ctl_new1(). + * Don't call this after the control was added to the card. + */ void snd_ctl_free_one(snd_kcontrol_t * kcontrol) { if (kcontrol) { @@ -221,6 +241,16 @@ } } +/** + * snd_ctl_add - add the control instance to the card + * @card: the card instance + * @kcontrol: the control instance to add + * + * Adds the control instance created via snd_ctl_new() or + * snd_ctl_new1() to the given card. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol) { snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL); @@ -236,6 +266,16 @@ return 0; } +/** + * snd_ctl_remove - remove the control from the card and release it + * @card: the card instance + * @kcontrol: the control instance to remove + * + * Removes the control from the card and then releases the instance. + * You don't need to call snd_ctl_free_one(). + * + * Returns 0 if successful, or a negative error code on failure. + */ int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol) { snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL); @@ -248,6 +288,16 @@ return 0; } +/** + * snd_ctl_remove_id - remove the control of the given id and release it + * @card: the card instance + * @id: the control id to remove + * + * Finds the control instance with the given id, removes it from the + * card list and releases it. + * + * Returns 0 if successful, or a negative error code on failure. + */ int snd_ctl_remove_id(snd_card_t * card, snd_ctl_elem_id_t *id) { snd_kcontrol_t *kctl; @@ -260,6 +310,17 @@ static snd_kcontrol_t *_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id); /* w/o lock */ +/** + * snd_ctl_rename_id - replace the id of a control on the card + * @card: the card instance + * @src_id: the old id + * @dst_id: the new id + * + * Finds the control with the old id from the card, and replaces the + * id with the new one. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_ctl_rename_id(snd_card_t * card, snd_ctl_elem_id_t *src_id, snd_ctl_elem_id_t *dst_id) { snd_kcontrol_t *kctl; @@ -315,7 +376,15 @@ return NULL; } -/* exported: with read lock */ +/** + * snd_ctl_find_id - find the control instance with the given id + * @card: the card instance + * @id: the id to search + * + * Finds the control instance with the given id from the card. + * + * Returns the pointer of the instance if found, or NULL if not. + */ snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id) { snd_kcontrol_t *kctl; @@ -325,7 +394,15 @@ return kctl; } -/* exported: with read lock */ +/** + * snd_ctl_find_numid - find the control instance with the given number-id + * @card: the card instance + * @numid: the number-id to search + * + * Finds the control instance with the given number-id from the card. + * + * Returns the pointer of the instance if found, or NULL if not. + */ snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid) { snd_kcontrol_t *kctl; @@ -637,13 +714,15 @@ return -EFAULT; if (!capable(CAP_SYS_ADMIN)) return -EPERM; + err = -ENOPROTOOPT; #ifdef CONFIG_PM - if (card->set_power_state == NULL) - return -ENOPROTOOPT; - return card->set_power_state(card, err); -#else - return -ENOPROTOOPT; + if (card->set_power_state) { + snd_power_lock(card); + err = card->set_power_state(card, err); + snd_power_unlock(card); + } #endif + return err; case SNDRV_CTL_IOCTL_POWER_STATE: #ifdef CONFIG_PM return put_user(card->power_state, (int *)arg) ? -EFAULT : 0; @@ -736,6 +815,10 @@ return mask; } +/* + * register the device-specific control-ioctls. + * called from each device manager like pcm.c, hwdep.c, etc. + */ int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn) { snd_kctl_ioctl_t *pn; @@ -751,6 +834,9 @@ return 0; } +/* + * de-register the device-specific control-ioctls. + */ int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn) { struct list_head *list; @@ -806,6 +892,10 @@ .f_ops = &snd_ctl_f_ops, }; +/* + * registration of the control device: + * called from init.c + */ int snd_ctl_register(snd_card_t *card) { int err, cardnum; @@ -821,6 +911,10 @@ return 0; } +/* + * disconnection of the control device: + * called from init.c + */ int snd_ctl_disconnect(snd_card_t *card) { struct list_head *flist; @@ -836,6 +930,10 @@ return 0; } +/* + * de-registration of the control device: + * called from init.c + */ int snd_ctl_unregister(snd_card_t *card) { int err, cardnum; diff -Nru a/sound/core/device.c b/sound/core/device.c --- a/sound/core/device.c Sun Feb 9 21:13:33 2003 +++ b/sound/core/device.c Sun Feb 9 21:13:33 2003 @@ -25,6 +25,22 @@ #include #include +/** + * snd_device_new - create an ALSA device component + * @card: the card instance + * @type: the device type, SNDRV_DEV_TYPE_XXX + * @device_data: the data pointer of this device + * @ops: the operator table + * + * Creates a new device component for the given data pointer. + * The device will be assigned to the card and managed together + * by the card. + * + * The data pointer plays a role as the identifier, too, so the + * pointer address must be unique and unchanged. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_device_new(snd_card_t *card, snd_device_type_t type, void *device_data, snd_device_ops_t *ops) { @@ -43,6 +59,18 @@ return 0; } +/** + * snd_device_free - release the device from the card + * @card: the card instance + * @device_data: the data pointer to release + * + * Removes the device from the list on the card and invokes the + * callback, dev_unregister or dev_free, corresponding to the state. + * Then release the device. + * + * Returns zero if successful, or a negative error code on failure or if the + * device not found. + */ int snd_device_free(snd_card_t *card, void *device_data) { struct list_head *list; @@ -73,6 +101,19 @@ return -ENXIO; } +/** + * snd_device_free - disconnect the device + * @card: the card instance + * @device_data: the data pointer to disconnect + * + * Turns the device into the disconnection state, invoking + * dev_disconnect callback, if the device was already registered. + * + * Usually called from snd_card_disconnect(). + * + * Returns zero if successful, or a negative error code on failure or if the + * device not found. + */ int snd_device_disconnect(snd_card_t *card, void *device_data) { struct list_head *list; @@ -95,6 +136,19 @@ return -ENXIO; } +/** + * snd_device_register - register the device + * @card: the card instance + * @device_data: the data pointer to register + * + * Registers the device which was already created via + * snd_device_new(). Usually this is called from snd_card_register(), + * but it can be called later if any new devices are created after + * invokation of snd_card_register(). + * + * Returns zero if successful, or a negative error code on failure or if the + * device not found. + */ int snd_device_register(snd_card_t *card, void *device_data) { struct list_head *list; @@ -118,6 +172,10 @@ return -ENXIO; } +/* + * register all the devices on the card. + * called from init.c + */ int snd_device_register_all(snd_card_t *card) { struct list_head *list; @@ -136,6 +194,10 @@ return 0; } +/* + * disconnect all the devices on the card. + * called from init.c + */ int snd_device_disconnect_all(snd_card_t *card) { snd_device_t *dev; @@ -151,11 +213,16 @@ return err; } +/* + * release all the devices on the card. + * called from init.c + */ int snd_device_free_all(snd_card_t *card, snd_device_cmd_t cmd) { snd_device_t *dev; struct list_head *list; - int err, range_low, range_high; + int err; + unsigned int range_low, range_high; snd_assert(card != NULL, return -ENXIO); range_low = cmd * SNDRV_DEV_TYPE_RANGE_SIZE; diff -Nru a/sound/core/hwdep.c b/sound/core/hwdep.c --- a/sound/core/hwdep.c Sun Feb 9 21:13:28 2003 +++ b/sound/core/hwdep.c Sun Feb 9 21:13:28 2003 @@ -256,6 +256,19 @@ .f_ops = &snd_hwdep_f_ops, }; +/** + * snd_hwdep_new - create a new hwdep instance + * @card: the card instance + * @id: the id string + * @device: the device index (zero-based) + * @rhwdep: the pointer to store the new hwdep instance + * + * Creates a new hwdep instance with the given index on the card. + * The callbacks (hwdep->ops) must be set on the returned instance + * after this call manually by the caller. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_hwdep_new(snd_card_t * card, char *id, int device, snd_hwdep_t ** rhwdep) { snd_hwdep_t *hwdep; diff -Nru a/sound/core/info.c b/sound/core/info.c --- a/sound/core/info.c Sun Feb 9 21:13:36 2003 +++ b/sound/core/info.c Sun Feb 9 21:13:36 2003 @@ -83,10 +83,16 @@ static int snd_info_version_init(void); static int snd_info_version_done(void); -/* +/** + * snd_iprintf - printf on the procfs buffer + * @buffer: the procfs buffer + * @fmt: the printf format + * + * Outputs the string on the procfs buffer just like printf(). + * + * Returns the size of output string. */ - int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...) { va_list args; @@ -293,9 +299,6 @@ up(&info_mutex); return -ENODEV; } -#ifdef LINUX_2_2 - MOD_INC_USE_COUNT; -#endif if (!try_module_get(entry->module)) { err = -EFAULT; goto __error1; @@ -403,9 +406,6 @@ __error: module_put(entry->module); __error1: -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif up(&info_mutex); return err; } @@ -445,9 +445,6 @@ break; } module_put(entry->module); -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif snd_magic_kfree(data); return 0; } @@ -600,6 +597,17 @@ .follow_link = snd_info_card_followlink, }; +/** + * snd_create_proc_entry - create a procfs entry + * @name: the name of the proc file + * @mode: the file permission bits, S_Ixxx + * @parent: the parent proc-directory entry + * + * Creates a new proc file entry with the given name and permission + * on the given directory. + * + * Returns the pointer of new instance or NULL on failure. + */ struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent) { @@ -691,6 +699,10 @@ */ +/* + * create a card proc file + * called from init.c + */ int snd_info_card_create(snd_card_t * card) { char str[8]; @@ -710,6 +722,10 @@ return 0; } +/* + * register the card proc file + * called from init.c + */ int snd_info_card_register(snd_card_t * card) { char *s; @@ -737,6 +753,10 @@ return 0; } +/* + * de-register the card proc file + * called from init.c + */ int snd_info_card_free(snd_card_t * card) { void *data; @@ -756,10 +776,17 @@ return 0; } -/* +/** + * snd_info_get_line - read one line from the procfs buffer + * @buffer: the procfs buffer + * @line: the buffer to store + * @len: the max. buffer size - 1 + * + * Reads one line from the buffer and stores the string. + * + * Returns zero if successful, or 1 if error or EOF. */ - int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len) { int c = -1; @@ -769,20 +796,20 @@ while (--len > 0) { c = *buffer->curr++; if (c == '\n') { - if ((buffer->curr - buffer->buffer) >= buffer->size) { + if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { buffer->stop = 1; } break; } *line++ = c; - if ((buffer->curr - buffer->buffer) >= buffer->size) { + if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { buffer->stop = 1; break; } } while (c != '\n' && !buffer->stop) { c = *buffer->curr++; - if ((buffer->curr - buffer->buffer) >= buffer->size) { + if ((buffer->curr - buffer->buffer) >= (long)buffer->size) { buffer->stop = 1; } } @@ -790,6 +817,18 @@ return 0; } +/** + * snd_info_get_line - parse a string token + * @dest: the buffer to store the string token + * @src: the original string + * @len: the max. length of token - 1 + * + * Parses the original string and copy a token to the given + * string buffer. + * + * Returns the updated pointer of the original string so that + * it can be used for the next call. + */ char *snd_info_get_str(char *dest, char *src, int len) { int c; @@ -814,15 +853,27 @@ return src; } +/** + * snd_info_create_entry - create an info entry + * @name: the proc file name + * + * Creates an info entry with the given file name and initializes as + * the default state. + * + * Usually called from other functions such as + * snd_info_create_card_entry(). + * + * Returns the pointer of the new instance, or NULL on failure. + */ static snd_info_entry_t *snd_info_create_entry(const char *name) { snd_info_entry_t *entry; - entry = (snd_info_entry_t *) snd_kcalloc(sizeof(snd_info_entry_t), GFP_KERNEL); + entry = snd_magic_kcalloc(snd_info_entry_t, 0, GFP_KERNEL); if (entry == NULL) return NULL; entry->name = snd_kmalloc_strdup(name, GFP_KERNEL); if (entry->name == NULL) { - kfree(entry); + snd_magic_kfree(entry); return NULL; } entry->mode = S_IFREG | S_IRUGO; @@ -831,6 +882,16 @@ return entry; } +/** + * snd_info_create_module_entry - create an info entry for the given module + * @module: the module pointer + * @name: the file name + * @parent: the parent directory + * + * Creates a new info entry and assigns it to the given module. + * + * Returns the pointer of the new instance, or NULL on failure. + */ snd_info_entry_t *snd_info_create_module_entry(struct module * module, const char *name, snd_info_entry_t *parent) @@ -843,6 +904,16 @@ return entry; } +/** + * snd_info_create_card_entry - create an info entry for the given card + * @card: the card instance + * @name: the file name + * @parent: the parent directory + * + * Creates a new info entry and assigns it to the given card. + * + * Returns the pointer of the new instance, or NULL on failure. + */ snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card, const char *name, snd_info_entry_t * parent) @@ -856,6 +927,75 @@ return entry; } +static int snd_info_dev_free_entry(snd_device_t *device) +{ + snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO); + snd_info_free_entry(entry); + return 0; +} + +static int snd_info_dev_register_entry(snd_device_t *device) +{ + snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO); + return snd_info_register(entry); +} + +static int snd_info_dev_unregister_entry(snd_device_t *device) +{ + snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO); + return snd_info_unregister(entry); +} + +/** + * snd_card_proc_new - create an info entry for the given card + * @card: the card instance + * @name: the file name + * @entryp: the pointer to store the new info entry + * + * Creates a new info entry and assigns it to the given card. + * Unlike snd_info_create_card_entry(), this function registers the + * info entry as an ALSA device component, so that it can be + * unregistered/released without explicit call. + * Also, you don't have to register this entry via snd_info_register(), + * since this will be registered by snd_card_register() automatically. + * + * The parent is assumed as card->proc_root. + * + * For releasing this entry, use snd_device_free() instead of + * snd_info_free_entry(). + * + * Returns zero if successful, or a negative error code on failure. + */ +int snd_card_proc_new(snd_card_t *card, const char *name, + snd_info_entry_t **entryp) +{ + static snd_device_ops_t ops = { + .dev_free = snd_info_dev_free_entry, + .dev_register = snd_info_dev_register_entry, + // .dev_disconnect = snd_info_dev_disconnect_entry, + .dev_unregister = snd_info_dev_unregister_entry + }; + snd_info_entry_t *entry; + int err; + + entry = snd_info_create_card_entry(card, name, card->proc_root); + if (! entry) + return -ENOMEM; + if ((err = snd_device_new(card, SNDRV_DEV_INFO, entry, &ops)) < 0) { + snd_info_free_entry(entry); + return err; + } + if (entryp) + *entryp = entry; + return 0; +} + +/** + * snd_info_free_entry - release the info entry + * @entry: the info entry + * + * Releases the info entry. Don't call this after registered. + */ void snd_info_free_entry(snd_info_entry_t * entry) { if (entry == NULL) @@ -864,7 +1004,7 @@ kfree((char *)entry->name); if (entry->private_free) entry->private_free(entry); - kfree(entry); + snd_magic_kfree(entry); } #ifdef LINUX_2_2 @@ -901,11 +1041,11 @@ } #endif /* LINUX_2_2 */ +/* + * create a procfs device file + */ snd_info_entry_t *snd_info_create_device(const char *name, unsigned int number, unsigned int mode) { -#ifdef CONFIG_DEVFS_FS - char dname[32]; -#endif unsigned short _major = number >> 16; unsigned short minor = (unsigned short) number; snd_info_entry_t *entry; @@ -921,7 +1061,7 @@ return NULL; entry->content = SNDRV_INFO_CONTENT_DEVICE; entry->mode = mode; - entry->c.device.major = major; + entry->c.device.major = _major; entry->c.device.minor = minor; down(&info_mutex); p = create_proc_entry(entry->name, entry->mode, snd_proc_dev); @@ -942,15 +1082,19 @@ up(&info_mutex); #ifdef CONFIG_DEVFS_FS if (strncmp(name, "controlC", 8)) { /* created in sound.c */ + char dname[32]; sprintf(dname, "snd/%s", name); devfs_register(NULL, dname, DEVFS_FL_DEFAULT, - major, minor, mode, + _major, minor, mode, &snd_fops, NULL); } #endif return entry; } +/* + * release a procfs device file + */ void snd_info_free_device(snd_info_entry_t * entry) { snd_runtime_check(entry, return); @@ -962,6 +1106,14 @@ snd_info_free_entry(entry); } +/** + * snd_info_register - register the info entry + * @entry: the info entry + * + * Registers the proc info entry. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_info_register(snd_info_entry_t * entry) { struct proc_dir_entry *root, *p = NULL; @@ -991,6 +1143,14 @@ return 0; } +/** + * snd_info_unregister - de-register the info entry + * @entry: the info entry + * + * De-registers the info entry and releases the instance. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_info_unregister(snd_info_entry_t * entry) { struct proc_dir_entry *root; diff -Nru a/sound/core/init.c b/sound/core/init.c --- a/sound/core/init.c Sun Feb 9 21:13:29 2003 +++ b/sound/core/init.c Sun Feb 9 21:13:29 2003 @@ -51,14 +51,16 @@ } /** - * snd_card_new: create and initialize a soundcard structure + * snd_card_new - create and initialize a soundcard structure * @idx: card index (address) [0 ... (SNDRV_CARDS-1)] * @xid: card identification (ASCII string) * @module: top level module for locking * @extra_size: allocate this extra size after the main soundcard structure * + * Creates and initializes a soundcard structure. + * * Returns kmallocated snd_card_t structure. Creates the ALSA control interface - * (which is blocked until #snd_card_register function is called). + * (which is blocked until snd_card_register function is called). */ snd_card_t *snd_card_new(int idx, const char *xid, struct module *module, int extra_size) @@ -84,11 +86,19 @@ idx = idx2; break; } + if (idx < 0 && snd_ecards_limit < SNDRV_CARDS) + /* for dynamically additional devices like hotplug: + * increment the limit if still free slot exists. + */ + idx = snd_ecards_limit++; } else if (idx < snd_ecards_limit) { if (snd_cards_lock & (1 << idx)) idx = -1; /* invalid */ - } - if (idx < 0 || idx >= snd_ecards_limit) { + } else if (idx < SNDRV_CARDS) + snd_ecards_limit = idx + 1; /* increase the limit */ + else + idx = -1; + if (idx < 0) { write_unlock(&snd_card_rwlock); if (idx >= snd_ecards_limit) snd_printk(KERN_ERR "card %i is out of range (0-%i)\n", idx, snd_ecards_limit-1); @@ -136,10 +146,12 @@ } /** - * snd_card_disconnect: disconnect all APIs from the file-operations (user space) + * snd_card_disconnect - disconnect all APIs from the file-operations (user space) * @card: soundcard structure * - * Returns - zero, otherwise a negative error code. + * Disconnects all APIs from the file-operations (user space). + * + * Returns zero, otherwise a negative error code. * * Note: The current implementation replaces all active file->f_op with special * dummy file operations (they do nothing except release). @@ -219,19 +231,18 @@ } /** - * snd_card_free: frees given soundcard structure + * snd_card_free - frees given soundcard structure * @card: soundcard structure * * This function releases the soundcard structure and the all assigned * devices automatically. That is, you don't have to release the devices * by yourself. * - * Returns - zero. Frees all associated devices and frees the control + * Returns zero. Frees all associated devices and frees the control * interface associated to given soundcard. */ int snd_card_free(snd_card_t * card) { - wait_queue_t wait; struct snd_shutdown_f_ops *s_f_ops; if (card == NULL) @@ -242,13 +253,7 @@ write_unlock(&snd_card_rwlock); /* wait, until all devices are ready for the free operation */ - init_waitqueue_entry(&wait, current); - add_wait_queue(&card->shutdown_sleep, &wait); - while (card->files) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(30 * HZ); - } - remove_wait_queue(&card->shutdown_sleep, &wait); + wait_event(card->shutdown_sleep, card->files == NULL); #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) if (snd_mixer_oss_notify_callback) @@ -292,29 +297,29 @@ static void snd_card_free_thread(void * __card) { snd_card_t *card = __card; - struct module * module; + struct module * module = card->module; - if (!try_module_get(module = card->module)) { + if (!try_module_get(module)) { snd_printk(KERN_ERR "unable to lock toplevel module for card %i in free thread\n", card->number); module = NULL; } - wait_event(card->shutdown_sleep, card->files == NULL); snd_card_free(card); + module_put(module); } /** - * snd_card_free_in_thread: call snd_card_free() in thread + * snd_card_free_in_thread - call snd_card_free() in thread * @card: soundcard structure * - * This function schedules the call of #snd_card_free function in a + * This function schedules the call of snd_card_free() function in a * work queue. When all devices are released (non-busy), the work - * is woken up and calls #snd_card_free. + * is woken up and calls snd_card_free(). * * When a card can be disconnected at any time by hotplug service, * this function should be used in disconnect (or detach) callback - * instead of calling #snd_card_free directly. + * instead of calling snd_card_free() directly. * * Returns - zero otherwise a negative error code if the start of thread failed. */ @@ -347,7 +352,7 @@ id++; } id = card->id; - while (*spos != '\0' && id - card->id < sizeof(card->id) - 1) { + while (*spos != '\0' && (size_t)(id - card->id) < sizeof(card->id) - 1) { if (isalnum(*spos)) *id++ = *spos; spos++; @@ -374,12 +379,12 @@ len = strlen(id); if (idx_flag) id[len-1]++; - else if (len <= sizeof(card->id) - 3) { + else if ((size_t)len <= sizeof(card->id) - 3) { strcat(id, "_1"); idx_flag++; } else { spos = id + len - 2; - if (len <= sizeof(card->id) - 2) + if ((size_t)len <= sizeof(card->id) - 2) spos++; *spos++ = '_'; *spos++ = '1'; @@ -390,7 +395,7 @@ } /** - * snd_card_register: register the soundcard + * snd_card_register - register the soundcard * @card: soundcard structure * * This function registers all the devices assigned to the soundcard. @@ -398,7 +403,7 @@ * external accesses. Thus, you should call this function at the end * of the initialization of the card. * - * Returns - zero otherwise a negative error code if the registrain failed. + * Returns zero otherwise a negative error code if the registrain failed. */ int snd_card_register(snd_card_t * card) { @@ -515,14 +520,14 @@ } /** - * snd_component_add: add a component string + * snd_component_add - add a component string * @card: soundcard structure * @component: the component id string * * This function adds the component id string to the supported list. * The component can be referred from the alsa-lib. * - * Returns - zero otherwise a negative error code. + * Returns zero otherwise a negative error code. */ int snd_component_add(snd_card_t *card, const char *component) @@ -546,7 +551,7 @@ } /** - * snd_card_file_add: add the file to the file list of the card + * snd_card_file_add - add the file to the file list of the card * @card: soundcard structure * @file: file pointer * @@ -578,15 +583,15 @@ } /** - * snd_card_file_remove: remove the file from the file list + * snd_card_file_remove - remove the file from the file list * @card: soundcard structure * @file: file pointer * * This function removes the file formerly added to the card via - * #snd_card_file_add function. + * snd_card_file_add() function. * If all files are removed and the release of the card is - * scheduled, it will wake up the the thread to call #snd_card_free - * (see #snd_card_free_in_thread function). + * scheduled, it will wake up the the thread to call snd_card_free() + * (see snd_card_free_in_thread() function). * * Returns zero or a negative error code. */ @@ -621,8 +626,10 @@ #ifdef CONFIG_PM /** - * snd_power_wait: wait until the power-state is changed. + * snd_power_wait - wait until the power-state is changed. * @card: soundcard structure + * + * Waits until the power-state is changed. * * Note: the power lock must be active before call. */ diff -Nru a/sound/core/ioctl32/ioctl32.c b/sound/core/ioctl32/ioctl32.c --- a/sound/core/ioctl32/ioctl32.c Sun Feb 9 21:13:29 2003 +++ b/sound/core/ioctl32/ioctl32.c Sun Feb 9 21:13:29 2003 @@ -71,6 +71,17 @@ /* + * compatible wrapper + */ +int snd_ioctl32_compat(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *filp) +{ + if (! filp->f_op || ! filp->f_op->ioctl) + return -ENOTTY; + return filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg); +} + + +/* * Controls */ @@ -250,9 +261,9 @@ ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO); kctl = snd_ctl_find_id(ctl->card, id); - if (! kctl) + if (! kctl) { return -ENXIO; - + } info.id = *id; err = kctl->info(kctl, &info); if (err >= 0) @@ -381,22 +392,22 @@ static struct ioctl32_mapper control_mappers[] = { /* controls (without rawmidi, hwdep, timer releated ones) */ - { SNDRV_CTL_IOCTL_PVERSION, NULL }, - { SNDRV_CTL_IOCTL_CARD_INFO , NULL }, + MAP_COMPAT(SNDRV_CTL_IOCTL_PVERSION), + MAP_COMPAT(SNDRV_CTL_IOCTL_CARD_INFO), { SNDRV_CTL_IOCTL_ELEM_LIST32, AP(ctl_elem_list) }, { SNDRV_CTL_IOCTL_ELEM_INFO32, AP(ctl_elem_info) }, { SNDRV_CTL_IOCTL_ELEM_READ32, AP(ctl_elem_read) }, { SNDRV_CTL_IOCTL_ELEM_WRITE32, AP(ctl_elem_write) }, - { SNDRV_CTL_IOCTL_ELEM_LOCK, NULL }, - { SNDRV_CTL_IOCTL_ELEM_UNLOCK, NULL }, - { SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, NULL }, - { SNDRV_CTL_IOCTL_HWDEP_INFO, NULL }, - { SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE, NULL }, - { SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE, NULL }, - { SNDRV_CTL_IOCTL_PCM_INFO, NULL }, - { SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE, NULL }, - { SNDRV_CTL_IOCTL_POWER, NULL }, - { SNDRV_CTL_IOCTL_POWER_STATE, NULL }, + MAP_COMPAT(SNDRV_CTL_IOCTL_ELEM_LOCK), + MAP_COMPAT(SNDRV_CTL_IOCTL_ELEM_UNLOCK), + MAP_COMPAT(SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS), + MAP_COMPAT(SNDRV_CTL_IOCTL_HWDEP_INFO), + MAP_COMPAT(SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE), + MAP_COMPAT(SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE), + MAP_COMPAT(SNDRV_CTL_IOCTL_PCM_INFO), + MAP_COMPAT(SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE), + MAP_COMPAT(SNDRV_CTL_IOCTL_POWER), + MAP_COMPAT(SNDRV_CTL_IOCTL_POWER_STATE), { 0 } }; diff -Nru a/sound/core/ioctl32/ioctl32.h b/sound/core/ioctl32/ioctl32.h --- a/sound/core/ioctl32/ioctl32.h Sun Feb 9 21:13:31 2003 +++ b/sound/core/ioctl32/ioctl32.h Sun Feb 9 21:13:31 2003 @@ -69,6 +69,7 @@ oldseg = get_fs();\ set_fs(KERNEL_DS);\ err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)&data);\ + set_fs(oldseg);\ if (err < 0) \ return err;\ if (native_ctl & (_IOC_READ << _IOC_DIRSHIFT)) {\ @@ -101,6 +102,7 @@ oldseg = get_fs();\ set_fs(KERNEL_DS);\ err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);\ + set_fs(oldseg);\ if (err < 0) \ goto __end;\ err = 0;\ @@ -122,12 +124,15 @@ return _snd_ioctl32_##type(fd, cmd, arg, file, native_ctl);\ } +#define MAP_COMPAT(ctl) { ctl, snd_ioctl32_compat } struct ioctl32_mapper { unsigned int cmd; int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp); int registered; }; + +int snd_ioctl32_compat(unsigned int, unsigned int, unsigned long, struct file *); int snd_ioctl32_register(struct ioctl32_mapper *mappers); void snd_ioctl32_unregister(struct ioctl32_mapper *mappers); diff -Nru a/sound/core/ioctl32/pcm32.c b/sound/core/ioctl32/pcm32.c --- a/sound/core/ioctl32/pcm32.c Sun Feb 9 21:13:33 2003 +++ b/sound/core/ioctl32/pcm32.c Sun Feb 9 21:13:33 2003 @@ -72,7 +72,7 @@ #define CVT_sndrv_pcm_hw_params()\ {\ - int i;\ + unsigned int i;\ COPY(flags);\ for (i = 0; i < numberof(dst->masks); i++)\ COPY(masks[i]);\ @@ -423,32 +423,32 @@ }; struct ioctl32_mapper pcm_mappers[] = { - { SNDRV_PCM_IOCTL_PVERSION, NULL }, - { SNDRV_PCM_IOCTL_INFO, NULL }, + MAP_COMPAT(SNDRV_PCM_IOCTL_PVERSION), + MAP_COMPAT(SNDRV_PCM_IOCTL_INFO), { SNDRV_PCM_IOCTL_HW_REFINE32, AP(pcm_hw_refine) }, { SNDRV_PCM_IOCTL_HW_PARAMS32, AP(pcm_hw_params) }, { SNDRV_PCM_IOCTL_HW_REFINE_OLD32, AP(pcm_hw_refine_old) }, { SNDRV_PCM_IOCTL_HW_PARAMS_OLD32, AP(pcm_hw_params_old) }, - { SNDRV_PCM_IOCTL_HW_FREE, NULL }, + MAP_COMPAT(SNDRV_PCM_IOCTL_HW_FREE), { SNDRV_PCM_IOCTL_SW_PARAMS32, AP(pcm_sw_params) }, { SNDRV_PCM_IOCTL_STATUS32, AP(pcm_status) }, { SNDRV_PCM_IOCTL_DELAY32, AP(pcm_delay) }, { SNDRV_PCM_IOCTL_CHANNEL_INFO32, AP(pcm_channel_info) }, - { SNDRV_PCM_IOCTL_PREPARE, NULL }, - { SNDRV_PCM_IOCTL_RESET, NULL }, - { SNDRV_PCM_IOCTL_START, NULL }, - { SNDRV_PCM_IOCTL_DROP, NULL }, - { SNDRV_PCM_IOCTL_DRAIN, NULL }, - { SNDRV_PCM_IOCTL_PAUSE, NULL }, + MAP_COMPAT(SNDRV_PCM_IOCTL_PREPARE), + MAP_COMPAT(SNDRV_PCM_IOCTL_RESET), + MAP_COMPAT(SNDRV_PCM_IOCTL_START), + MAP_COMPAT(SNDRV_PCM_IOCTL_DROP), + MAP_COMPAT(SNDRV_PCM_IOCTL_DRAIN), + MAP_COMPAT(SNDRV_PCM_IOCTL_PAUSE), { SNDRV_PCM_IOCTL_REWIND32, AP(pcm_rewind) }, - { SNDRV_PCM_IOCTL_RESUME, NULL }, - { SNDRV_PCM_IOCTL_XRUN, NULL }, + MAP_COMPAT(SNDRV_PCM_IOCTL_RESUME), + MAP_COMPAT(SNDRV_PCM_IOCTL_XRUN), { SNDRV_PCM_IOCTL_WRITEI_FRAMES32, AP(pcm_writei) }, { SNDRV_PCM_IOCTL_READI_FRAMES32, AP(pcm_readi) }, { SNDRV_PCM_IOCTL_WRITEN_FRAMES32, AP(pcm_writen) }, { SNDRV_PCM_IOCTL_READN_FRAMES32, AP(pcm_readn) }, - { SNDRV_PCM_IOCTL_LINK, NULL }, - { SNDRV_PCM_IOCTL_UNLINK, NULL }, + MAP_COMPAT(SNDRV_PCM_IOCTL_LINK), + MAP_COMPAT(SNDRV_PCM_IOCTL_UNLINK), { 0 }, }; diff -Nru a/sound/core/ioctl32/rawmidi32.c b/sound/core/ioctl32/rawmidi32.c --- a/sound/core/ioctl32/rawmidi32.c Sun Feb 9 21:13:32 2003 +++ b/sound/core/ioctl32/rawmidi32.c Sun Feb 9 21:13:32 2003 @@ -78,16 +78,16 @@ }; struct ioctl32_mapper rawmidi_mappers[] = { - { SNDRV_RAWMIDI_IOCTL_PVERSION, NULL }, - { SNDRV_RAWMIDI_IOCTL_INFO, NULL }, + MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_PVERSION), + MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_INFO), { SNDRV_RAWMIDI_IOCTL_PARAMS32, AP(rawmidi_params) }, { SNDRV_RAWMIDI_IOCTL_STATUS32, AP(rawmidi_status) }, - { SNDRV_RAWMIDI_IOCTL_DROP, NULL }, - { SNDRV_RAWMIDI_IOCTL_DRAIN, NULL }, + MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_DROP), + MAP_COMPAT(SNDRV_RAWMIDI_IOCTL_DRAIN), - { SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE, NULL }, - { SNDRV_CTL_IOCTL_RAWMIDI_INFO, NULL }, - { SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE, NULL }, + MAP_COMPAT(SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE), + MAP_COMPAT(SNDRV_CTL_IOCTL_RAWMIDI_INFO), + MAP_COMPAT(SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE), { 0 }, }; diff -Nru a/sound/core/ioctl32/seq32.c b/sound/core/ioctl32/seq32.c --- a/sound/core/ioctl32/seq32.c Sun Feb 9 21:13:37 2003 +++ b/sound/core/ioctl32/seq32.c Sun Feb 9 21:13:37 2003 @@ -79,36 +79,36 @@ }; struct ioctl32_mapper seq_mappers[] = { - { SNDRV_SEQ_IOCTL_PVERSION, NULL }, - { SNDRV_SEQ_IOCTL_CLIENT_ID, NULL }, - { SNDRV_SEQ_IOCTL_SYSTEM_INFO, NULL }, - { SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, NULL }, - { SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, NULL }, + MAP_COMPAT(SNDRV_SEQ_IOCTL_PVERSION), + MAP_COMPAT(SNDRV_SEQ_IOCTL_CLIENT_ID), + MAP_COMPAT(SNDRV_SEQ_IOCTL_SYSTEM_INFO), + MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_CLIENT_INFO), + MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_CLIENT_INFO), { SNDRV_SEQ_IOCTL_CREATE_PORT32, AP(create_port) }, { SNDRV_SEQ_IOCTL_DELETE_PORT32, AP(delete_port) }, { SNDRV_SEQ_IOCTL_GET_PORT_INFO32, AP(get_port_info) }, { SNDRV_SEQ_IOCTL_SET_PORT_INFO32, AP(set_port_info) }, - { SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, NULL }, - { SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, NULL }, - { SNDRV_SEQ_IOCTL_CREATE_QUEUE, NULL }, - { SNDRV_SEQ_IOCTL_DELETE_QUEUE, NULL }, - { SNDRV_SEQ_IOCTL_GET_QUEUE_INFO, NULL }, - { SNDRV_SEQ_IOCTL_SET_QUEUE_INFO, NULL }, - { SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE, NULL }, - { SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS, NULL }, - { SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO, NULL }, - { SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO, NULL }, - { SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER, NULL }, - { SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER, NULL }, - { SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT, NULL }, - { SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT, NULL }, - { SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, NULL }, - { SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, NULL }, - { SNDRV_SEQ_IOCTL_REMOVE_EVENTS, NULL }, - { SNDRV_SEQ_IOCTL_QUERY_SUBS, NULL }, - { SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION, NULL }, - { SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, NULL }, + MAP_COMPAT(SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT), + MAP_COMPAT(SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT), + MAP_COMPAT(SNDRV_SEQ_IOCTL_CREATE_QUEUE), + MAP_COMPAT(SNDRV_SEQ_IOCTL_DELETE_QUEUE), + MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_INFO), + MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_INFO), + MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE), + MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS), + MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO), + MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO), + MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER), + MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER), + MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT), + MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT), + MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_CLIENT_POOL), + MAP_COMPAT(SNDRV_SEQ_IOCTL_SET_CLIENT_POOL), + MAP_COMPAT(SNDRV_SEQ_IOCTL_REMOVE_EVENTS), + MAP_COMPAT(SNDRV_SEQ_IOCTL_QUERY_SUBS), + MAP_COMPAT(SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION), + MAP_COMPAT(SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT), { SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32, AP(query_next_port) }, - { SNDRV_SEQ_IOCTL_RUNNING_MODE, NULL }, + MAP_COMPAT(SNDRV_SEQ_IOCTL_RUNNING_MODE), { 0 }, }; diff -Nru a/sound/core/ioctl32/timer32.c b/sound/core/ioctl32/timer32.c --- a/sound/core/ioctl32/timer32.c Sun Feb 9 21:13:32 2003 +++ b/sound/core/ioctl32/timer32.c Sun Feb 9 21:13:32 2003 @@ -87,14 +87,14 @@ }; struct ioctl32_mapper timer_mappers[] = { - { SNDRV_TIMER_IOCTL_PVERSION, NULL }, - { SNDRV_TIMER_IOCTL_NEXT_DEVICE, NULL }, - { SNDRV_TIMER_IOCTL_SELECT, NULL }, + MAP_COMPAT(SNDRV_TIMER_IOCTL_PVERSION), + MAP_COMPAT(SNDRV_TIMER_IOCTL_NEXT_DEVICE), + MAP_COMPAT(SNDRV_TIMER_IOCTL_SELECT), { SNDRV_TIMER_IOCTL_INFO32, AP(timer_info) }, - { SNDRV_TIMER_IOCTL_PARAMS, NULL }, + MAP_COMPAT(SNDRV_TIMER_IOCTL_PARAMS), { SNDRV_TIMER_IOCTL_STATUS32, AP(timer_status) }, - { SNDRV_TIMER_IOCTL_START, NULL }, - { SNDRV_TIMER_IOCTL_STOP, NULL }, - { SNDRV_TIMER_IOCTL_CONTINUE, NULL }, + MAP_COMPAT(SNDRV_TIMER_IOCTL_START), + MAP_COMPAT(SNDRV_TIMER_IOCTL_STOP), + MAP_COMPAT(SNDRV_TIMER_IOCTL_CONTINUE), { 0 }, }; diff -Nru a/sound/core/isadma.c b/sound/core/isadma.c --- a/sound/core/isadma.c Sun Feb 9 21:13:37 2003 +++ b/sound/core/isadma.c Sun Feb 9 21:13:37 2003 @@ -30,10 +30,15 @@ #include #include -/* +/** + * snd_dma_program - program an ISA DMA transfer + * @dma: the dma number + * @addr: the physical address of the buffer + * @size: the DMA transfer size + * @mode: the DMA transfer mode, DMA_MODE_XXX * + * Programs an ISA DMA transfer for the given buffer. */ - void snd_dma_program(unsigned long dma, unsigned long addr, unsigned int size, unsigned short mode) @@ -51,6 +56,12 @@ release_dma_lock(flags); } +/** + * snd_dma_disable - stop the ISA DMA transfer + * @dma: the dma number + * + * Stops the ISA DMA transfer. + */ void snd_dma_disable(unsigned long dma) { unsigned long flags; @@ -61,7 +72,14 @@ release_dma_lock(flags); } -unsigned int snd_dma_residue(unsigned long dma) +/** + * snd_dma_pointer - return the current pointer to DMA transfer buffer in bytes + * @dma: the dma number + * @size: the dma transfer size + * + * Returns the current pointer in DMA tranfer buffer in bytes + */ +unsigned int snd_dma_pointer(unsigned long dma, unsigned int size) { unsigned long flags; unsigned int result; @@ -74,5 +92,9 @@ if (!isa_dma_bridge_buggy) enable_dma(dma); release_dma_lock(flags); - return result; +#ifdef CONFIG_SND_DEBUG + if (result > size) + snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size); +#endif + return result >= size ? 0 : result; } diff -Nru a/sound/core/memory.c b/sound/core/memory.c --- a/sound/core/memory.c Sun Feb 9 21:13:28 2003 +++ b/sound/core/memory.c Sun Feb 9 21:13:28 2003 @@ -264,7 +264,15 @@ #endif /* CONFIG_SND_DEBUG_MEMORY */ - +/** + * snd_malloc_pages - allocate pages with the given size + * @size: the size to allocate in bytes + * @dma_flags: the allocation conditions, GFP_XXX + * + * Allocates the physically contiguous pages with the given size. + * + * Returns the pointer of the buffer, or NULL if no enoguh memory. + */ void *snd_malloc_pages(unsigned long size, unsigned int dma_flags) { int pg; @@ -285,6 +293,19 @@ return res; } +/** + * snd_malloc_pages_fallback - allocate pages with the given size with fallback + * @size: the requested size to allocate in bytes + * @dma_flags: the allocation conditions, GFP_XXX + * @res_size: the pointer to store the size of buffer actually allocated + * + * Allocates the physically contiguous pages with the given request + * size. When no space is left, this function reduces the size and + * tries to allocate again. The size actually allocated is stored in + * res_size argument. + * + * Returns the pointer of the buffer, or NULL if no enoguh memory. + */ void *snd_malloc_pages_fallback(unsigned long size, unsigned int dma_flags, unsigned long *res_size) { void *res; @@ -301,6 +322,13 @@ return NULL; } +/** + * snd_free_pages - release the pages + * @ptr: the buffer pointer to release + * @size: the allocated buffer size + * + * Releases the buffer allocated via snd_malloc_pages(). + */ void snd_free_pages(void *ptr, unsigned long size) { int pg; @@ -321,6 +349,16 @@ #if defined(CONFIG_ISA) && ! defined(CONFIG_PCI) +/** + * snd_malloc_isa_pages - allocate pages for ISA bus with the given size + * @size: the size to allocate in bytes + * @dma_addr: the pointer to store the physical address of the buffer + * + * Allocates the physically contiguous pages with the given size for + * ISA bus. + * + * Returns the pointer of the buffer, or NULL if no enoguh memory. + */ void *snd_malloc_isa_pages(unsigned long size, dma_addr_t *dma_addr) { void *dma_area; @@ -329,6 +367,19 @@ return dma_area; } +/** + * snd_malloc_isa_pages_fallback - allocate pages with the given size with fallback for ISA bus + * @size: the requested size to allocate in bytes + * @dma_addr: the pointer to store the physical address of the buffer + * @res_size: the pointer to store the size of buffer actually allocated + * + * Allocates the physically contiguous pages with the given request + * size for PCI bus. When no space is left, this function reduces the size and + * tries to allocate again. The size actually allocated is stored in + * res_size argument. + * + * Returns the pointer of the buffer, or NULL if no enoguh memory. + */ void *snd_malloc_isa_pages_fallback(unsigned long size, dma_addr_t *dma_addr, unsigned long *res_size) @@ -343,6 +394,17 @@ #ifdef CONFIG_PCI +/** + * snd_malloc_pci_pages - allocate pages for PCI bus with the given size + * @pci: the pci device pointer + * @size: the size to allocate in bytes + * @dma_addr: the pointer to store the physical address of the buffer + * + * Allocates the physically contiguous pages with the given size for + * PCI bus. + * + * Returns the pointer of the buffer, or NULL if no enoguh memory. + */ void *snd_malloc_pci_pages(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr) @@ -366,6 +428,20 @@ return res; } +/** + * snd_malloc_pci_pages_fallback - allocate pages with the given size with fallback for PCI bus + * @pci: pci device pointer + * @size: the requested size to allocate in bytes + * @dma_addr: the pointer to store the physical address of the buffer + * @res_size: the pointer to store the size of buffer actually allocated + * + * Allocates the physically contiguous pages with the given request + * size for PCI bus. When no space is left, this function reduces the size and + * tries to allocate again. The size actually allocated is stored in + * res_size argument. + * + * Returns the pointer of the buffer, or NULL if no enoguh memory. + */ void *snd_malloc_pci_pages_fallback(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr, @@ -384,6 +460,15 @@ return NULL; } +/** + * snd_free_pci_pages - release the pages + * @pci: pci device pointer + * @size: the allocated buffer size + * @ptr: the buffer pointer to release + * @dma_addr: the physical address of the buffer + * + * Releases the buffer allocated via snd_malloc_pci_pages(). + */ void snd_free_pci_pages(struct pci_dev *pci, unsigned long size, void *ptr, @@ -409,6 +494,17 @@ #ifdef CONFIG_SBUS +/** + * snd_malloc_sbus_pages - allocate pages for SBUS with the given size + * @sdev: sbus device pointer + * @size: the size to allocate in bytes + * @dma_addr: the pointer to store the physical address of the buffer + * + * Allocates the physically contiguous pages with the given size for + * SBUS. + * + * Returns the pointer of the buffer, or NULL if no enoguh memory. + */ void *snd_malloc_sbus_pages(struct sbus_dev *sdev, unsigned long size, dma_addr_t *dma_addr) @@ -432,6 +528,20 @@ return res; } +/** + * snd_malloc_pci_pages_fallback - allocate pages with the given size with fallback for SBUS + * @sdev: sbus device pointer + * @size: the requested size to allocate in bytes + * @dma_addr: the pointer to store the physical address of the buffer + * @res_size: the pointer to store the size of buffer actually allocated + * + * Allocates the physically contiguous pages with the given request + * size for SBUS. When no space is left, this function reduces the size and + * tries to allocate again. The size actually allocated is stored in + * res_size argument. + * + * Returns the pointer of the buffer, or NULL if no enoguh memory. + */ void *snd_malloc_sbus_pages_fallback(struct sbus_dev *sdev, unsigned long size, dma_addr_t *dma_addr, @@ -450,6 +560,15 @@ return NULL; } +/** + * snd_free_sbus_pages - release the pages + * @sdev: sbus device pointer + * @size: the allocated buffer size + * @ptr: the buffer pointer to release + * @dma_addr: the physical address of the buffer + * + * Releases the buffer allocated via snd_malloc_pci_pages(). + */ void snd_free_sbus_pages(struct sbus_dev *sdev, unsigned long size, void *ptr, @@ -473,6 +592,15 @@ #endif /* CONFIG_SBUS */ +/** + * snd_kcalloc - memory allocation and zero-clear + * @size: the size to allocate in bytes + * @flags: allocation conditions, GFP_XXX + * + * Allocates a memory chunk via kmalloc() and initializes it to zero. + * + * Returns the pointer, or NULL if no enoguh memory. + */ void *snd_kcalloc(size_t size, int flags) { void *ptr; @@ -483,6 +611,15 @@ return ptr; } +/** + * snd_kmalloc_strdup - copy the string + * @string: the original string + * @flags: allocation conditions, GFP_XXX + * + * Allocates a memory chunk via kmalloc() and copies the string to it. + * + * Returns the pointer, or NULL if no enoguh memory. + */ char *snd_kmalloc_strdup(const char *string, int flags) { size_t len; @@ -497,6 +634,16 @@ return ptr; } +/** + * copy_to_user_fromio - copy data from mmio-space to user-space + * @dst: the destination pointer on user-space + * @src: the source pointer on mmio + * @count: the data size to copy in bytes + * + * Copies the data from mmio-space to user-space. + * + * Returns zero if successful, or non-zero on failure. + */ int copy_to_user_fromio(void *dst, unsigned long src, size_t count) { #if defined(__i386__) || defined(CONFIG_SPARC32) @@ -518,6 +665,16 @@ #endif } +/** + * copy_from_user_toio - copy data from user-space to mmio-space + * @dst: the destination pointer on mmio-space + * @src: the source pointer on user-space + * @count: the data size to copy in bytes + * + * Copies the data from user-space to mmio-space. + * + * Returns zero if successful, or non-zero on failure. + */ int copy_from_user_toio(unsigned long dst, const void *src, size_t count) { #if defined(__i386__) || defined(CONFIG_SPARC32) @@ -538,3 +695,81 @@ return 0; #endif } + + +#ifdef CONFIG_PCI + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) && defined(__i386__) +/* + * on ix86, we allocate a page with GFP_KERNEL to assure the + * allocation. the code is almost same with kernel/i386/pci-dma.c but + * it allocates only a single page and checks the validity of the + * page address with the given pci dma mask. + */ + +/** + * snd_malloc_pci_page - allocate a page in the valid pci dma mask + * @pci: pci device pointer + * @addrp: the pointer to store the physical address of the buffer + * + * Allocates a single page for the given PCI device and returns + * the virtual address and stores the physical address on addrp. + * + * This function cannot be called from interrupt handlers or + * within spinlocks. + */ +void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *addrp) +{ + void *ptr; + dma_addr_t addr; + unsigned long rmask; + + rmask = ~(unsigned long)(pci ? pci->dma_mask : 0x00ffffff); + ptr = (void *)__get_free_page(GFP_KERNEL); + if (ptr) { + addr = virt_to_phys(ptr); + if (((unsigned long)addr + PAGE_SIZE - 1) & rmask) { + /* try to reallocate with the GFP_DMA */ + free_page((unsigned long)ptr); + ptr = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); + if (ptr) /* ok, the address must be within lower 16MB... */ + addr = virt_to_phys(ptr); + else + addr = 0; + } + } else + addr = 0; + if (ptr) { + struct page *page = virt_to_page(ptr); + memset(ptr, 0, PAGE_SIZE); + SetPageReserved(page); +#ifdef CONFIG_SND_DEBUG_MEMORY + snd_alloc_pages++; +#endif + } + *addrp = addr; + return ptr; +} +#else +/* on other architectures, call snd_malloc_pci_pages() helper function + * which uses pci_alloc_consistent(). + */ +void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *addrp) +{ + return snd_malloc_pci_pages(pci, PAGE_SIZE, addrp); +} +#endif /* 2.4 && i386 */ + +#if 0 /* for kernel-doc */ +/** + * snd_free_pci_page - release a page + * @pci: pci device pointer + * @ptr: the buffer pointer to release + * @dma_addr: the physical address of the buffer + * + * Releases the buffer allocated via snd_malloc_pci_page(). + */ +void snd_free_pci_page(struct pci_dev *pci, void *ptr, dma_addr_t dma_addr); +#endif /* for kernel-doc */ + +#endif /* CONFIG_PCI */ diff -Nru a/sound/core/oss/Makefile b/sound/core/oss/Makefile --- a/sound/core/oss/Makefile Sun Feb 9 21:13:28 2003 +++ b/sound/core/oss/Makefile Sun Feb 9 21:13:28 2003 @@ -3,8 +3,6 @@ # Copyright (c) 1999 by Jaroslav Kysela # -export-objs := mixer_oss.o - snd-mixer-oss-objs := mixer_oss.o snd-pcm-oss-objs := pcm_oss.o pcm_plugin.o \ diff -Nru a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c --- a/sound/core/oss/mixer_oss.c Sun Feb 9 21:13:33 2003 +++ b/sound/core/oss/mixer_oss.c Sun Feb 9 21:13:33 2003 @@ -56,14 +56,8 @@ fmixer->card = card; fmixer->mixer = card->mixer_oss; file->private_data = fmixer; -#ifdef LINUX_2_2 - MOD_INC_USE_COUNT; -#endif if (!try_module_get(card->module)) { kfree(fmixer); -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif snd_card_file_remove(card, file); return -EFAULT; } @@ -77,9 +71,6 @@ if (file->private_data) { fmixer = (snd_mixer_oss_file_t *) file->private_data; module_put(fmixer->card->module); -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif snd_card_file_remove(fmixer->card, file); kfree(fmixer); } @@ -473,7 +464,7 @@ struct slot { unsigned int signature; unsigned int present; - int channels; + unsigned int channels; snd_kcontrol_t *kcontrol[SNDRV_MIXER_OSS_ITEM_COUNT]; unsigned int capture_item; struct snd_mixer_oss_assign_table *assigned; @@ -741,7 +732,7 @@ return 0; } -static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, int *active_index) +static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int *active_index) { snd_card_t *card = fmixer->card; snd_mixer_oss_t *mixer = fmixer->mixer; @@ -787,7 +778,7 @@ return err; } -static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, int active_index) +static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int active_index) { snd_card_t *card = fmixer->card; snd_mixer_oss_t *mixer = fmixer->mixer; @@ -796,7 +787,8 @@ struct slot *slot = NULL; snd_ctl_elem_info_t *uinfo; snd_ctl_elem_value_t *uctl; - int err, idx; + int err; + unsigned int idx; uinfo = snd_kcalloc(sizeof(*uinfo), GFP_KERNEL); uctl = snd_kcalloc(sizeof(*uctl), GFP_KERNEL); @@ -1164,7 +1156,7 @@ static struct snd_mixer_oss_assign_table fm_table = { SOUND_MIXER_SYNTH, "FM", 0 }; - int idx; + unsigned int idx; for (idx = 0; idx < sizeof(table) / sizeof(struct snd_mixer_oss_assign_table); idx++) snd_mixer_oss_build_input(mixer, &table[idx], 0); diff -Nru a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c --- a/sound/core/oss/pcm_oss.c Sun Feb 9 21:13:35 2003 +++ b/sound/core/oss/pcm_oss.c Sun Feb 9 21:13:35 2003 @@ -251,6 +251,43 @@ return 0; } +static int choose_rate(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t *params, unsigned int best_rate) +{ + snd_interval_t *it; + snd_pcm_hw_params_t *save; + unsigned int rate; + + save = kmalloc(sizeof(*save), GFP_KERNEL); + if (save == NULL) + return -ENOMEM; + *save = *params; + it = hw_param_interval(save, SNDRV_PCM_HW_PARAM_RATE); + + /* try multiples of the best rate */ + rate = best_rate; + for (;;) { + if (it->max < rate || (it->max == rate && it->openmax)) + break; + if (it->min < rate || (it->min == rate && !it->openmin)) { + int ret; + ret = snd_pcm_hw_param_set(substream, params, + SNDRV_PCM_HW_PARAM_RATE, + rate, 0); + if (ret == (int)rate) { + kfree(save); + return rate; + } + *params = *save; + } + rate += best_rate; + } + + /* not found, use the nearest rate */ + kfree(save); + return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, 0); +} + static int snd_pcm_oss_change_params(snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime = substream->runtime; @@ -287,7 +324,7 @@ snd_printd("No usable accesses\n"); return -EINVAL; } - snd_pcm_hw_param_near(substream, &sparams, SNDRV_PCM_HW_PARAM_RATE, runtime->oss.rate, 0); + choose_rate(substream, &sparams, runtime->oss.rate); snd_pcm_hw_param_near(substream, &sparams, SNDRV_PCM_HW_PARAM_CHANNELS, runtime->oss.channels, 0); format = snd_pcm_oss_format_from(runtime->oss.format); @@ -679,7 +716,7 @@ tmp = runtime->oss.period_bytes - runtime->oss.buffer_used; if (tmp > 0) { if (copy_from_user(runtime->oss.buffer + runtime->oss.buffer_used, buf, tmp)) - return xfer > 0 ? xfer : -EFAULT; + return xfer > 0 ? (snd_pcm_sframes_t)xfer : -EFAULT; } runtime->oss.buffer_used += tmp; buf += tmp; @@ -688,14 +725,14 @@ if (runtime->oss.buffer_used == runtime->oss.period_bytes) { tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1); if (tmp <= 0) - return xfer > 0 ? xfer : tmp; + return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; runtime->oss.bytes += tmp; runtime->oss.buffer_used = 0; } } else { tmp = snd_pcm_oss_write2(substream, (char *)buf, runtime->oss.period_bytes, 0); if (tmp <= 0) - return xfer > 0 ? xfer : tmp; + return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; runtime->oss.bytes += tmp; buf += tmp; bytes -= tmp; @@ -751,7 +788,7 @@ if (runtime->oss.buffer_used == 0) { tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1); if (tmp <= 0) - return xfer > 0 ? xfer : tmp; + return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; runtime->oss.bytes += tmp; runtime->oss.buffer_used = runtime->oss.period_bytes; } @@ -759,7 +796,7 @@ if ((size_t) tmp > runtime->oss.buffer_used) tmp = runtime->oss.buffer_used; if (copy_to_user(buf, runtime->oss.buffer + (runtime->oss.period_bytes - runtime->oss.buffer_used), tmp)) - return xfer > 0 ? xfer : -EFAULT; + return xfer > 0 ? (snd_pcm_sframes_t)xfer : -EFAULT; buf += tmp; bytes -= tmp; xfer += tmp; @@ -767,7 +804,7 @@ } else { tmp = snd_pcm_oss_read2(substream, (char *)buf, runtime->oss.period_bytes, 0); if (tmp <= 0) - return xfer > 0 ? xfer : tmp; + return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; runtime->oss.bytes += tmp; buf += tmp; bytes -= tmp; @@ -890,7 +927,7 @@ return substream->runtime->oss.rate; } -static int snd_pcm_oss_set_channels(snd_pcm_oss_file_t *pcm_oss_file, int channels) +static int snd_pcm_oss_set_channels(snd_pcm_oss_file_t *pcm_oss_file, unsigned int channels) { int idx; if (channels < 1) @@ -1540,9 +1577,6 @@ device = SNDRV_MINOR_OSS_DEVICE(minor) == SNDRV_MINOR_OSS_PCM1 ? adsp_map[cardnum] : dsp_map[cardnum]; -#ifdef LINUX_2_2 - MOD_INC_USE_COUNT; -#endif pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + device]; if (pcm == NULL) { err = -ENODEV; @@ -1611,13 +1645,10 @@ return err; __error: - module_put(pcm->card->module); + module_put(pcm->card->module); __error2: snd_card_file_remove(pcm->card, file); __error1: -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif return err; } @@ -1640,9 +1671,6 @@ wake_up(&pcm->open_wait); module_put(pcm->card->module); snd_card_file_remove(pcm->card, file); -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif return 0; } @@ -2123,7 +2151,7 @@ static int snd_pcm_oss_register_minor(snd_pcm_t * pcm) { pcm->oss.reg = 0; - if (dsp_map[pcm->card->number] == pcm->device) { + if (dsp_map[pcm->card->number] == (int)pcm->device) { char name[128]; int duplex; register_oss_dsp(pcm, 0); @@ -2139,7 +2167,7 @@ pcm->oss.reg++; pcm->oss.reg_mask |= 1; } - if (adsp_map[pcm->card->number] == pcm->device) { + if (adsp_map[pcm->card->number] == (int)pcm->device) { register_oss_dsp(pcm, 1); pcm->oss.reg++; pcm->oss.reg_mask |= 2; @@ -2172,7 +2200,7 @@ { snd_pcm_oss_disconnect_minor(pcm); if (pcm->oss.reg) { - if (dsp_map[pcm->card->number] == pcm->device) { + if (dsp_map[pcm->card->number] == (int)pcm->device) { #ifdef SNDRV_OSS_INFO_DEV_AUDIO snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_AUDIO, pcm->card->number); #endif diff -Nru a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c --- a/sound/core/oss/pcm_plugin.c Sun Feb 9 21:13:30 2003 +++ b/sound/core/oss/pcm_plugin.c Sun Feb 9 21:13:30 2003 @@ -811,7 +811,7 @@ } frames = err; if (!plugin->prev) { - if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final) < 0)) + if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final)) < 0) return err; } } else { diff -Nru a/sound/core/pcm.c b/sound/core/pcm.c --- a/sound/core/pcm.c Sun Feb 9 21:13:37 2003 +++ b/sound/core/pcm.c Sun Feb 9 21:13:37 2003 @@ -105,7 +105,7 @@ if (subdevice >= pstr->substream_count) return -ENXIO; for (substream = pstr->substream; substream; substream = substream->next) - if (substream->number == subdevice) + if (substream->number == (int)subdevice) break; if (substream == NULL) return -ENXIO; @@ -542,6 +542,19 @@ return 0; } +/** + * snd_pcm_new_stream - create a new PCM stream + * @pcm: the pcm instance + * @stream: the stream direction, SNDRV_PCM_STREAM_XXX + * @substream_count: the number of substreams + * + * Creates a new stream for the pcm. + * The corresponding stream on the pcm must have been empty before + * calling this, i.e. zero must be given to the argument of + * snd_pcm_new(). + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count) { int idx, err; @@ -582,7 +595,7 @@ snd_magic_kfree(substream); return err; } - substream->dma_type = SNDRV_PCM_DMA_TYPE_ISA; + substream->dma_type = SNDRV_PCM_DMA_TYPE_UNKNOWN; substream->dma_private = NULL; spin_lock_init(&substream->timer_lock); prev = substream; @@ -590,6 +603,22 @@ return 0; } +/** + * snd_pcm_new - create a new PCM instance + * @card: the card instance + * @id: the id string + * @device: the device index (zero based) + * @playback_count: the number of substreams for playback + * @capture_count: the number of substreams for capture + * @rpcm: the pointer to store the new pcm instance + * + * Creates a new PCM instance. + * + * The pcm operators have to be set afterwards to the new instance + * via snd_pcm_set_ops(). + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_new(snd_card_t * card, char *id, int device, int playback_count, int capture_count, snd_pcm_t ** rpcm) @@ -660,6 +689,7 @@ snd_assert(pcm != NULL, return -ENXIO); if (pcm->private_free) pcm->private_free(pcm); + snd_pcm_lib_preallocate_free_for_all(pcm); snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]); snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_CAPTURE]); snd_magic_kfree(pcm); @@ -774,6 +804,7 @@ runtime->status->state = SNDRV_PCM_STATE_OPEN; substream->runtime = runtime; + substream->private_data = pcm->private_data; pstr->substream_opened++; *rsubstream = substream; return 0; diff -Nru a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c --- a/sound/core/pcm_lib.c Sun Feb 9 21:13:31 2003 +++ b/sound/core/pcm_lib.c Sun Feb 9 21:13:31 2003 @@ -119,7 +119,7 @@ delta = hw_ptr_interrupt - new_hw_ptr; if (delta > 0) { - if (delta < runtime->buffer_size / 2) { + if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) { snd_printd("Unexpected hw_pointer value (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2); return 0; } @@ -183,7 +183,7 @@ delta = old_hw_ptr - new_hw_ptr; if (delta > 0) { - if (delta < runtime->buffer_size / 2) { + if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) { snd_printd("Unexpected hw_pointer value (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2); return 0; } @@ -214,10 +214,14 @@ return 0; } -/* - * Operations +/** + * snd_pcm_set_ops - set the PCM operators + * @pcm: the pcm instance + * @direction: stream direction, SNDRV_PCM_STREAM_XXX + * @ops: the operator table + * + * Sets the given PCM operators to the pcm instance. */ - void snd_pcm_set_ops(snd_pcm_t *pcm, int direction, snd_pcm_ops_t *ops) { snd_pcm_str_t *stream = &pcm->streams[direction]; @@ -227,10 +231,13 @@ substream->ops = ops; } -/* - * Sync + +/** + * snd_pcm_sync - set the PCM sync id + * @substream: the pcm substream + * + * Sets the PCM sync identifier for the card. */ - void snd_pcm_set_sync(snd_pcm_substream_t * substream) { snd_pcm_runtime_t *runtime = substream->runtime; @@ -354,7 +361,17 @@ return changed; } -/* r <- v */ +/** + * snd_interval_refine - refine the interval value of configurator + * @i: the interval value to refine + * @v: the interval value to refer to + * + * Refines the interval value with the reference value. + * The interval is changed to the range satisfying both intervals. + * The interval status (min, max, integer, etc.) are evaluated. + * + * Returns non-zero if the value is changed, zero if not changed. + */ int snd_interval_refine(snd_interval_t *i, const snd_interval_t *v) { int changed = 0; @@ -445,6 +462,13 @@ c->integer = (a->integer && b->integer); } +/** + * snd_interval_div - refine the interval value with division + * + * c = a / b + * + * Returns non-zero if the value is changed, zero if not changed. + */ void snd_interval_div(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c) { unsigned int r; @@ -469,7 +493,13 @@ c->integer = 0; } -/* a * b / k */ +/** + * snd_interval_muldivk - refine the interval value + * + * c = a * b / k + * + * Returns non-zero if the value is changed, zero if not changed. + */ void snd_interval_muldivk(const snd_interval_t *a, const snd_interval_t *b, unsigned int k, snd_interval_t *c) { @@ -490,7 +520,13 @@ c->integer = 0; } -/* a * k / b */ +/** + * snd_interval_mulkdiv - refine the interval value + * + * c = a * k / b + * + * Returns non-zero if the value is changed, zero if not changed. + */ void snd_interval_mulkdiv(const snd_interval_t *a, unsigned int k, const snd_interval_t *b, snd_interval_t *c) { @@ -520,6 +556,11 @@ /* ---- */ +/** + * snd_interval_ratnum - refine the interval value + * + * Returns non-zero if the value is changed, zero if not changed. + */ int snd_interval_ratnum(snd_interval_t *i, unsigned int rats_count, ratnum_t *rats, unsigned int *nump, unsigned int *denp) @@ -612,6 +653,11 @@ return err; } +/** + * snd_interval_ratden - refine the interval value + * + * Returns non-zero if the value is changed, zero if not changed. + */ int snd_interval_ratden(snd_interval_t *i, unsigned int rats_count, ratden_t *rats, unsigned int *nump, unsigned int *denp) @@ -698,6 +744,19 @@ return err; } +/** + * snd_interval_list - refine the interval value from the list + * @i: the interval value to refine + * @count: the number of elements in the list + * @list: the value list + * @mask: the bit-mask to evaluate + * + * Refines the interval value from the list. + * When mask is non-zero, only the elements corresponding to bit 1 are + * evaluated. + * + * Returns non-zero if the value is changed, zero if not changed. + */ int snd_interval_list(snd_interval_t *i, unsigned int count, unsigned int *list, unsigned int mask) { unsigned int k; @@ -762,6 +821,17 @@ /* Info constraints helpers */ +/** + * snd_pcm_hw_rule_add - add the hw-constraint rule + * @runtime: the pcm runtime instance + * @cond: condition bits + * @var: the variable to evaluate + * @func: the evaluation function + * @private: the private data pointer passed to function + * @dep: the dependent variables + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_hw_rule_add(snd_pcm_runtime_t *runtime, unsigned int cond, int var, snd_pcm_hw_rule_func_t func, void *private, @@ -808,6 +878,9 @@ return 0; } +/** + * snd_pcm_hw_constraint_mask + */ int snd_pcm_hw_constraint_mask(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var, u_int32_t mask) { @@ -820,6 +893,9 @@ return 0; } +/** + * snd_pcm_hw_constraint_mask64 + */ int snd_pcm_hw_constraint_mask64(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var, u_int64_t mask) { @@ -833,12 +909,18 @@ return 0; } +/** + * snd_pcm_hw_constraint_integer + */ int snd_pcm_hw_constraint_integer(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var) { snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints; return snd_interval_setinteger(constrs_interval(constrs, var)); } +/** + * snd_pcm_hw_constraint_minmax + */ int snd_pcm_hw_constraint_minmax(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var, unsigned int min, unsigned int max) { @@ -859,6 +941,9 @@ } +/** + * snd_pcm_hw_constraint_list + */ int snd_pcm_hw_constraint_list(snd_pcm_runtime_t *runtime, unsigned int cond, snd_pcm_hw_param_t var, @@ -884,6 +969,9 @@ return err; } +/** + * snd_pcm_hw_constraint_ratnums + */ int snd_pcm_hw_constraint_ratnums(snd_pcm_runtime_t *runtime, unsigned int cond, snd_pcm_hw_param_t var, @@ -908,6 +996,9 @@ return err; } +/** + * snd_pcm_hw_constraint_ratdens + */ int snd_pcm_hw_constraint_ratdens(snd_pcm_runtime_t *runtime, unsigned int cond, snd_pcm_hw_param_t var, @@ -922,7 +1013,7 @@ snd_pcm_hw_rule_t *rule) { unsigned int l = (unsigned long) rule->private; - unsigned int width = l & 0xffff; + int width = l & 0xffff; unsigned int msbits = l >> 16; snd_interval_t *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); if (snd_interval_single(i) && snd_interval_value(i) == width) @@ -930,6 +1021,9 @@ return 0; } +/** + * snd_pcm_hw_constraint_msbits + */ int snd_pcm_hw_constraint_msbits(snd_pcm_runtime_t *runtime, unsigned int cond, unsigned int width, @@ -949,6 +1043,9 @@ return snd_interval_step(hw_param_interval(params, rule->var), 0, step); } +/** + * snd_pcm_hw_constraint_step + */ int snd_pcm_hw_constraint_step(snd_pcm_runtime_t *runtime, unsigned int cond, snd_pcm_hw_param_t var, @@ -971,6 +1068,9 @@ sizeof(pow2_sizes)/sizeof(int), pow2_sizes, 0); } +/** + * snd_pcm_hw_constraint_pow2 + */ int snd_pcm_hw_constraint_pow2(snd_pcm_runtime_t *runtime, unsigned int cond, snd_pcm_hw_param_t var) @@ -1004,6 +1104,9 @@ snd_BUG(); } +/** + * snd_pcm_hw_param_any + */ int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var) { @@ -1022,16 +1125,23 @@ params->info = ~0U; } -/* Fill PARAMS with full configuration space boundaries */ +/** + * snd_pcm_hw_params_any + * + * Fill PARAMS with full configuration space boundaries + */ int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { _snd_pcm_hw_params_any(params); return snd_pcm_hw_refine(pcm, params); } -/* Return the value for field PAR if it's fixed in configuration space - defined by PARAMS. Return -EINVAL otherwise -*/ +/** + * snd_pcm_hw_param_value + * + * Return the value for field PAR if it's fixed in configuration space + * defined by PARAMS. Return -EINVAL otherwise + */ int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, int *dir) { @@ -1055,7 +1165,11 @@ return -EINVAL; } -/* Return the minimum value for field PAR. */ +/** + * snd_pcm_hw_param_value_min + * + * Return the minimum value for field PAR. + */ unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, int *dir) { @@ -1074,7 +1188,11 @@ return -EINVAL; } -/* Return the maximum value for field PAR. */ +/** + * snd_pcm_hw_param_value_max + * + * Return the maximum value for field PAR. + */ unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, int *dir) { @@ -1122,10 +1240,13 @@ return changed; } -/* Inside configuration space defined by PARAMS remove from PAR all - non integer values. Reduce configuration space accordingly. - Return -EINVAL if the configuration space is empty -*/ +/** + * snd_pcm_hw_param_setinteger + * + * Inside configuration space defined by PARAMS remove from PAR all + * non integer values. Reduce configuration space accordingly. + * Return -EINVAL if the configuration space is empty + */ int snd_pcm_hw_param_setinteger(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var) @@ -1161,10 +1282,13 @@ } -/* Inside configuration space defined by PARAMS remove from PAR all - values > minimum. Reduce configuration space accordingly. - Return the minimum. -*/ +/** + * snd_pcm_hw_param_first + * + * Inside configuration space defined by PARAMS remove from PAR all + * values > minimum. Reduce configuration space accordingly. + * Return the minimum. + */ int snd_pcm_hw_param_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, int *dir) @@ -1199,10 +1323,13 @@ } -/* Inside configuration space defined by PARAMS remove from PAR all - values < maximum. Reduce configuration space accordingly. - Return the maximum. -*/ +/** + * snd_pcm_hw_param_last + * + * Inside configuration space defined by PARAMS remove from PAR all + * values < maximum. Reduce configuration space accordingly. + * Return the maximum. + */ int snd_pcm_hw_param_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, int *dir) @@ -1247,10 +1374,13 @@ return changed; } -/* Inside configuration space defined by PARAMS remove from PAR all - values < VAL. Reduce configuration space accordingly. - Return new minimum or -EINVAL if the configuration space is empty -*/ +/** + * snd_pcm_hw_param_min + * + * Inside configuration space defined by PARAMS remove from PAR all + * values < VAL. Reduce configuration space accordingly. + * Return new minimum or -EINVAL if the configuration space is empty + */ int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, unsigned int val, int *dir) { @@ -1297,10 +1427,13 @@ return changed; } -/* Inside configuration space defined by PARAMS remove from PAR all - values >= VAL + 1. Reduce configuration space accordingly. - Return new maximum or -EINVAL if the configuration space is empty -*/ +/** + * snd_pcm_hw_param_max + * + * Inside configuration space defined by PARAMS remove from PAR all + * values >= VAL + 1. Reduce configuration space accordingly. + * Return new maximum or -EINVAL if the configuration space is empty + */ int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, unsigned int val, int *dir) { @@ -1364,10 +1497,13 @@ return changed; } -/* Inside configuration space defined by PARAMS remove from PAR all - values != VAL. Reduce configuration space accordingly. - Return VAL or -EINVAL if the configuration space is empty -*/ +/** + * snd_pcm_hw_param_set + * + * Inside configuration space defined by PARAMS remove from PAR all + * values != VAL. Reduce configuration space accordingly. + * Return VAL or -EINVAL if the configuration space is empty + */ int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, unsigned int val, int dir) { @@ -1395,13 +1531,16 @@ return changed; } -/* Inside configuration space defined by PARAMS remove from PAR all values - not contained in MASK. Reduce configuration space accordingly. - This function can be called only for SNDRV_PCM_HW_PARAM_ACCESS, - SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT. - Return 0 on success or -EINVAL - if the configuration space is empty -*/ +/** + * snd_pcm_hw_param_mask + * + * Inside configuration space defined by PARAMS remove from PAR all values + * not contained in MASK. Reduce configuration space accordingly. + * This function can be called only for SNDRV_PCM_HW_PARAM_ACCESS, + * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT. + * Return 0 on success or -EINVAL + * if the configuration space is empty + */ int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, const snd_mask_t *val) { @@ -1464,12 +1603,15 @@ return boundary_lt(dmin, dmindir, dmax, dmaxdir); } -/* Inside configuration space defined by PARAMS set PAR to the available value - nearest to VAL. Reduce configuration space accordingly. - This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS, - SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT. - Return the value found. - */ +/** + * snd_pcm_hw_param_near + * + * Inside configuration space defined by PARAMS set PAR to the available value + * nearest to VAL. Reduce configuration space accordingly. + * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS, + * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT. + * Return the value found. + */ int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, unsigned int best, int *dir) { @@ -1537,17 +1679,14 @@ return v; } -/* Choose one configuration from configuration space defined by PARAMS - The configuration choosen is that obtained fixing in this order: - first access - first format - first subformat - min channels - min rate - min period time - max buffer size - min tick time -*/ +/** + * snd_pcm_hw_param_choose + * + * Choose one configuration from configuration space defined by PARAMS + * The configuration choosen is that obtained fixing in this order: + * first access, first format, first subformat, min channels, + * min rate, min period time, max buffer size, min tick time + */ int snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { int err; @@ -1630,6 +1769,17 @@ return 0; } +/** + * snd_pcm_lib_ioctl - a generic PCM ioctl callback + * @substream: the pcm substream instance + * @cmd: ioctl command + * @arg: ioctl argument + * + * Processes the generic ioctl commands for PCM. + * Can be passed as the ioctl callback for PCM ops. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_ioctl(snd_pcm_substream_t *substream, unsigned int cmd, void *arg) { @@ -1648,30 +1798,74 @@ * Conditions */ +/** + * snd_pcm_playback_ready - check whether the playback buffer is available + * @substream: the pcm substream instance + * + * Checks whether enough free space is available on the playback buffer. + * + * Returns non-zero if available, or zero if not. + */ int snd_pcm_playback_ready(snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime = substream->runtime; return snd_pcm_playback_avail(runtime) >= runtime->control->avail_min; } +/** + * snd_pcm_capture_ready - check whether the capture buffer is available + * @substream: the pcm substream instance + * + * Checks whether enough capture data is available on the capture buffer. + * + * Returns non-zero if available, or zero if not. + */ int snd_pcm_capture_ready(snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime = substream->runtime; return snd_pcm_capture_avail(runtime) >= runtime->control->avail_min; } +/** + * snd_pcm_playback_data - check whether any data exists on the playback buffer + * @substream: the pcm substream instance + * + * Checks whether any data exists on the playback buffer. If stop_threshold + * is bigger or equal to boundary, then this function returns always non-zero. + * + * Returns non-zero if exists, or zero if not. + */ int snd_pcm_playback_data(snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime = substream->runtime; + + if (runtime->stop_threshold >= runtime->boundary) + return 1; return snd_pcm_playback_avail(runtime) < runtime->buffer_size; } +/** + * snd_pcm_playback_empty - check whether the playback buffer is empty + * @substream: the pcm substream instance + * + * Checks whether the playback buffer is empty. + * + * Returns non-zero if empty, or zero if not. + */ int snd_pcm_playback_empty(snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime = substream->runtime; return snd_pcm_playback_avail(runtime) >= runtime->buffer_size; } +/** + * snd_pcm_capture_empty - check whether the capture buffer is empty + * @substream: the pcm substream instance + * + * Checks whether the capture buffer is empty. + * + * Returns non-zero if empty, or zero if not. + */ int snd_pcm_capture_empty(snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime = substream->runtime; @@ -1711,7 +1905,7 @@ runtime->silenced_size < runtime->buffer_size) { snd_pcm_sframes_t noise_dist; noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silenced_size; - snd_assert(noise_dist <= runtime->silence_threshold, ); + snd_assert(noise_dist <= (snd_pcm_sframes_t)runtime->silence_threshold, ); frames = noise_dist - runtime->silence_threshold; } avail = snd_pcm_playback_avail(runtime); @@ -1720,12 +1914,12 @@ } if (avail < runtime->control->avail_min) { snd_pcm_sframes_t n = runtime->control->avail_min - avail; - if (n > 0 && frames > n) + if (n > 0 && frames > (snd_pcm_uframes_t)n) frames = n; } if (avail < runtime->buffer_size) { snd_pcm_sframes_t n = runtime->buffer_size - avail; - if (n > 0 && frames > n) + if (n > 0 && frames > (snd_pcm_uframes_t)n) frames = n; } if (frames == ULONG_MAX) { @@ -1766,6 +1960,17 @@ spin_unlock_irq(&runtime->lock); } +/** + * snd_pcm_period_elapsed - update the pcm status for the next period + * @substream: the pcm substream instance + * + * This function is called from the interrupt handler when the + * PCM has processed the period size. It will update the current + * pointer, set up the tick, wake up sleepers, etc. + * + * Even if more than one periods have elapsed since the last call, you + * have to call this only once. + */ void snd_pcm_period_elapsed(snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime; @@ -1956,7 +2161,7 @@ size -= frames; xfer += frames; if (runtime->status->state == SNDRV_PCM_STATE_PREPARED && - snd_pcm_playback_hw_avail(runtime) >= runtime->start_threshold) { + snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) { err = snd_pcm_start(substream); if (err < 0) goto _end_unlock; @@ -1968,7 +2173,7 @@ _end_unlock: spin_unlock_irq(&runtime->lock); _end: - return xfer > 0 ? xfer : err; + return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; } snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream, const void *buf, snd_pcm_uframes_t size) @@ -2254,7 +2459,7 @@ _end_unlock: spin_unlock_irq(&runtime->lock); _end: - return xfer > 0 ? xfer : err; + return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; } snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream, void *buf, snd_pcm_uframes_t size) @@ -2377,6 +2582,7 @@ EXPORT_SYMBOL(snd_pcm_hw_param_first); EXPORT_SYMBOL(snd_pcm_hw_param_last); EXPORT_SYMBOL(snd_pcm_hw_param_near); +EXPORT_SYMBOL(snd_pcm_hw_param_set); EXPORT_SYMBOL(snd_pcm_hw_refine); EXPORT_SYMBOL(snd_pcm_hw_constraints_init); EXPORT_SYMBOL(snd_pcm_hw_constraints_complete); diff -Nru a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c --- a/sound/core/pcm_memory.c Sun Feb 9 21:13:34 2003 +++ b/sound/core/pcm_memory.c Sun Feb 9 21:13:34 2003 @@ -26,6 +26,9 @@ #include #include #include +#ifdef CONFIG_PCI +#include +#endif static int preallocate_dma = 1; MODULE_PARM(preallocate_dma, "i"); @@ -37,36 +40,127 @@ MODULE_PARM_DESC(maximum_substreams, "Maximum substreams with preallocated DMA memory."); MODULE_PARM_SYNTAX(maximum_substreams, SNDRV_BOOLEAN_TRUE_DESC); -static int snd_minimum_buffer = 16384; +const static size_t snd_minimum_buffer = 16384; -static void snd_pcm_lib_preallocate_dma_free(snd_pcm_substream_t *substream) +/* + * allocate pages on the specified bus + */ +static int alloc_pcm_pages(snd_pcm_substream_t *substream, size_t size, + void **dma_area, dma_addr_t *dma_addr) +{ + switch (substream->dma_type) { + case SNDRV_PCM_DMA_TYPE_CONTINUOUS: + *dma_area = snd_malloc_pages(size, (unsigned int)((unsigned long)substream->dma_private & 0xffffffff)); + *dma_addr = 0UL; /* not valid */ + break; +#ifdef CONFIG_ISA + case SNDRV_PCM_DMA_TYPE_ISA: + *dma_area = snd_malloc_isa_pages(size, dma_addr); + break; +#endif +#ifdef CONFIG_PCI + case SNDRV_PCM_DMA_TYPE_PCI: + *dma_area = snd_malloc_pci_pages((struct pci_dev *)substream->dma_private, size, dma_addr); + break; + case SNDRV_PCM_DMA_TYPE_PCI_SG: + *dma_area = snd_pcm_sgbuf_alloc_pages((struct snd_sg_buf *)substream->dma_private, size); + *dma_addr = 0; + break; +#endif +#ifdef CONFIG_SBUS + case SNDRV_PCM_DMA_TYPE_SBUS: + *dma_area = snd_malloc_sbus_pages((struct sbus_dev *)substream->dma_private, size, dma_addr); + break; +#endif + default: + *dma_area = NULL; + *dma_addr = 0; + return -ENXIO; + } + return 0; +} + +/* + * try to allocate as the large pages as possible. + * stores the resultant memory size in *res_size. + * + * the minimum size is snd_minimum_buffer. it should be power of 2. + */ +static void *alloc_pcm_pages_fallback(snd_pcm_substream_t *substream, + size_t size, dma_addr_t *addrp, + size_t *res_size) +{ + void *res; + + snd_assert(size > 0, return NULL); + snd_assert(res_size != NULL, return NULL); + do { + if (alloc_pcm_pages(substream, size, &res, addrp) < 0) + return NULL; + if (res) { + *res_size = size; + return res; + } + size >>= 1; + } while (size >= snd_minimum_buffer); + *res_size = 0; /* tell error */ + return NULL; +} + +/* + * release the pages on the specified bus + */ +static void free_pcm_pages(snd_pcm_substream_t *substream, size_t size, + void *dma_area, dma_addr_t dma_addr) { - if (substream->dma_area == NULL) - return; switch (substream->dma_type) { case SNDRV_PCM_DMA_TYPE_CONTINUOUS: - snd_free_pages(substream->dma_area, substream->dma_bytes); + snd_free_pages(dma_area, size); break; #ifdef CONFIG_ISA case SNDRV_PCM_DMA_TYPE_ISA: - snd_free_isa_pages(substream->dma_bytes, substream->dma_area, substream->dma_addr); + snd_free_isa_pages(size, dma_area, dma_addr); break; #endif #ifdef CONFIG_PCI case SNDRV_PCM_DMA_TYPE_PCI: - snd_free_pci_pages((struct pci_dev *)substream->dma_private, substream->dma_bytes, substream->dma_area, substream->dma_addr); + snd_free_pci_pages((struct pci_dev *)substream->dma_private, + size, dma_area, dma_addr); + break; + case SNDRV_PCM_DMA_TYPE_PCI_SG: + snd_pcm_sgbuf_free_pages((struct snd_sg_buf *)substream->dma_private, dma_area); break; #endif #ifdef CONFIG_SBUS case SNDRV_PCM_DMA_TYPE_SBUS: - snd_free_sbus_pages((struct sbus_dev *)substream->dma_private, substream->dma_bytes, substream->dma_area, substream->dma_addr); + snd_free_sbus_pages((struct sbus_dev *)substream->dma_private, + size, dma_area, dma_addr); break; #endif } +} + +/* + * release the preallocated buffer if not yet done. + */ +static void snd_pcm_lib_preallocate_dma_free(snd_pcm_substream_t *substream) +{ + if (substream->dma_area == NULL) + return; + free_pcm_pages(substream, substream->dma_bytes, + substream->dma_area, substream->dma_addr); substream->dma_area = NULL; } +/** + * snd_pcm_lib_preallocate_free - release the preallocated buffer of the specified substream. + * @substream: the pcm substream instance + * + * Releases the pre-allocated buffer of the given substream. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_preallocate_free(snd_pcm_substream_t *substream) { snd_pcm_lib_preallocate_dma_free(substream); @@ -74,9 +168,22 @@ snd_info_unregister(substream->proc_prealloc_entry); substream->proc_prealloc_entry = NULL; } +#ifdef CONFIG_PCI + if (substream->dma_type == SNDRV_PCM_DMA_TYPE_PCI_SG) + snd_pcm_sgbuf_delete((struct snd_sg_buf *)substream->dma_private); +#endif + substream->dma_type = SNDRV_PCM_DMA_TYPE_UNKNOWN; return 0; } +/** + * snd_pcm_lib_preallocate_free_for_all - release all pre-allocated buffers on the pcm + * @pcm: the pcm instance + * + * Releases all the pre-allocated buffers on the given pcm. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_preallocate_free_for_all(snd_pcm_t *pcm) { snd_pcm_substream_t *substream; @@ -88,6 +195,11 @@ return 0; } +/* + * read callback for prealloc proc file + * + * prints the current allocated size in kB. + */ static void snd_pcm_lib_preallocate_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer) { @@ -95,6 +207,11 @@ snd_iprintf(buffer, "%lu\n", (unsigned long) substream->dma_bytes / 1024); } +/* + * write callback for prealloc proc file + * + * accepts the preallocation size in kB. + */ static void snd_pcm_lib_preallocate_proc_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer) { @@ -118,27 +235,7 @@ if (substream->dma_bytes == size) return; if (size > 0) { - switch (substream->dma_type) { - case SNDRV_PCM_DMA_TYPE_CONTINUOUS: - dma_area = snd_malloc_pages(size, (unsigned int)((unsigned long)substream->dma_private & 0xffffffff)); - dma_addr = 0UL; /* not valid */ - break; -#ifdef CONFIG_ISA - case SNDRV_PCM_DMA_TYPE_ISA: - dma_area = snd_malloc_isa_pages(size, &dma_addr); - break; -#endif -#ifdef CONFIG_PCI - case SNDRV_PCM_DMA_TYPE_PCI: - dma_area = snd_malloc_pci_pages((struct pci_dev *)substream->dma_private, size, &dma_addr); - break; -#endif -#ifdef CONFIG_SBUS - case SNDRV_PCM_DMA_TYPE_SBUS: - dma_area = snd_malloc_sbus_pages((struct sbus_dev *)substream->dma_private, size, &dma_addr); - break; -#endif - default: + if (alloc_pcm_pages(substream, size, &dma_area, &dma_addr) < 0) { dma_area = NULL; dma_addr = 0UL; } @@ -160,45 +257,19 @@ } } +/* + * pre-allocate the buffer and create a proc file for the substream + */ static int snd_pcm_lib_preallocate_pages1(snd_pcm_substream_t *substream, size_t size, size_t max) { - unsigned long rsize = 0; + size_t rsize = 0; void *dma_area = NULL; dma_addr_t dma_addr = 0UL; snd_info_entry_t *entry; - if (!size || !preallocate_dma || substream->number >= maximum_substreams) { - size = 0; - } else { - switch (substream->dma_type) { - case SNDRV_PCM_DMA_TYPE_CONTINUOUS: - dma_area = snd_malloc_pages_fallback(size, (unsigned int)((unsigned long)substream->dma_private & 0xffffffff), &rsize); - dma_addr = 0UL; /* not valid */ - break; -#ifdef CONFIG_ISA - case SNDRV_PCM_DMA_TYPE_ISA: - dma_area = snd_malloc_isa_pages_fallback(size, &dma_addr, &rsize); - break; -#endif -#ifdef CONFIG_PCI - case SNDRV_PCM_DMA_TYPE_PCI: - dma_area = snd_malloc_pci_pages_fallback((struct pci_dev *)substream->dma_private, size, &dma_addr, &rsize); - break; -#endif -#ifdef CONFIG_SBUS - case SNDRV_PCM_DMA_TYPE_SBUS: - dma_area = snd_malloc_sbus_pages_fallback((struct sbus_dev *)substream->dma_private, size, &dma_addr, &rsize); - break; -#endif - default: - size = 0; - } - if (rsize < snd_minimum_buffer) { - snd_pcm_lib_preallocate_dma_free(substream); - size = 0; - } - } + if (size > 0 && preallocate_dma && substream->number < maximum_substreams) + dma_area = alloc_pcm_pages_fallback(substream, size, &dma_addr, &rsize); substream->dma_area = dma_area; substream->dma_addr = dma_addr; substream->dma_bytes = rsize; @@ -220,6 +291,17 @@ return 0; } +/** + * snd_pcm_lib_preallocate_pages - pre-allocation for the continuous memory type + * @substream: the pcm substream instance + * @size: the requested pre-allocation size in bytes + * @max: the max. allowed pre-allocation size + * @flags: allocation condition, GFP_XXX + * + * Do pre-allocation for the continuous memory type. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_preallocate_pages(snd_pcm_substream_t *substream, size_t size, size_t max, unsigned int flags) @@ -229,6 +311,18 @@ return snd_pcm_lib_preallocate_pages1(substream, size, max); } +/** + * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams) + * @pcm: pcm to assign the buffer + * @size: the requested pre-allocation size in bytes + * @max: max. buffer size acceptable for the changes via proc file + * @flags: allocation condition, GFP_XXX + * + * Do pre-allocation to all substreams of the given pcm for the + * continuous memory type. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_preallocate_pages_for_all(snd_pcm_t *pcm, size_t size, size_t max, unsigned int flags) @@ -244,6 +338,16 @@ } #ifdef CONFIG_ISA +/** + * snd_pcm_lib_preallocate_isa_pages - pre-allocation for the ISA bus + * @substream: substream to assign the buffer + * @size: the requested pre-allocation size in bytes + * @max: max. buffer size acceptable for the changes via proc file + * + * Do pre-allocation for the ISA bus. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_preallocate_isa_pages(snd_pcm_substream_t *substream, size_t size, size_t max) { @@ -252,6 +356,18 @@ return snd_pcm_lib_preallocate_pages1(substream, size, max); } +/* + * FIXME: the function name is too long for docbook! + * + * snd_pcm_lib_preallocate_isa_pages_for_all - pre-allocation for the ISA bus (all substreams) + * @pcm: pcm to assign the buffer + * @max: max. buffer size acceptable for the changes via proc file + * + * Do pre-allocation to all substreams of the given pcm for the + * ISA bus. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_preallocate_isa_pages_for_all(snd_pcm_t *pcm, size_t size, size_t max) { @@ -266,12 +382,24 @@ } #endif /* CONFIG_ISA */ +/** + * snd_pcm_lib_malloc_pages - allocate the DMA buffer + * @substream: the substream to allocate the DMA buffer to + * @size: the requested buffer size in bytes + * + * Allocates the DMA buffer on the BUS type given by + * snd_pcm_lib_preallocate_xxx_pages(). + * + * Returns 1 if the buffer is changed, 0 if not changed, or a negative + * code on failure. + */ int snd_pcm_lib_malloc_pages(snd_pcm_substream_t *substream, size_t size) { snd_pcm_runtime_t *runtime; void *dma_area = NULL; dma_addr_t dma_addr = 0UL; + snd_assert(substream->dma_type != SNDRV_PCM_DMA_TYPE_UNKNOWN, return -EINVAL); snd_assert(substream != NULL, return -EINVAL); runtime = substream->runtime; snd_assert(runtime != NULL, return -EINVAL); @@ -287,29 +415,7 @@ dma_area = substream->dma_area; dma_addr = substream->dma_addr; } else { - switch (substream->dma_type) { - case SNDRV_PCM_DMA_TYPE_CONTINUOUS: - dma_area = snd_malloc_pages(size, (unsigned int)((unsigned long)substream->dma_private & 0xffffffff)); - dma_addr = 0UL; /* not valid */ - break; -#ifdef CONFIG_ISA - case SNDRV_PCM_DMA_TYPE_ISA: - dma_area = snd_malloc_isa_pages(size, &dma_addr); - break; -#endif -#ifdef CONFIG_PCI - case SNDRV_PCM_DMA_TYPE_PCI: - dma_area = snd_malloc_pci_pages((struct pci_dev *)substream->dma_private, size, &dma_addr); - break; -#endif -#ifdef CONFIG_SBUS - case SNDRV_PCM_DMA_TYPE_SBUS: - dma_area = snd_malloc_sbus_pages((struct sbus_dev *)substream->dma_private, size, &dma_addr); - break; -#endif - default: - return -ENXIO; - } + alloc_pcm_pages(substream, size, &dma_area, &dma_addr); } if (! dma_area) return -ENOMEM; @@ -319,6 +425,14 @@ return 1; /* area was changed */ } +/** + * snd_pcm_lib_free_pages - release the allocated DMA buffer. + * @substream: the substream to release the DMA buffer + * + * Releases the DMA buffer allocated via snd_pcm_lib_malloc_pages(). + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_free_pages(snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime; @@ -328,25 +442,9 @@ snd_assert(runtime != NULL, return -EINVAL); if (runtime->dma_area == NULL) return 0; - if (runtime->dma_area != substream->dma_area) { - switch (substream->dma_type) { -#ifdef CONFIG_ISA - case SNDRV_PCM_DMA_TYPE_ISA: - snd_free_isa_pages(runtime->dma_bytes, runtime->dma_area, runtime->dma_addr); - break; -#endif -#ifdef CONFIG_PCI - case SNDRV_PCM_DMA_TYPE_PCI: - snd_free_pci_pages((struct pci_dev *)substream->dma_private, runtime->dma_bytes, runtime->dma_area, runtime->dma_addr); - break; -#endif -#ifdef CONFIG_SBUS - case SNDRV_PCM_DMA_TYPE_SBUS: - snd_free_sbus_pages((struct sbus_dev *)substream->dma_private, runtime->dma_bytes, runtime->dma_area, runtime->dma_addr); - break; -#endif - } - } + if (runtime->dma_area != substream->dma_area) + free_pcm_pages(substream, runtime->dma_bytes, + runtime->dma_area, runtime->dma_addr); runtime->dma_area = NULL; runtime->dma_addr = 0UL; runtime->dma_bytes = 0; @@ -354,7 +452,18 @@ } #ifdef CONFIG_PCI - +/** + * snd_pcm_lib_preallocate_pci_pages - pre-allocation for the PCI bus + * + * @pci: pci device + * @substream: substream to assign the buffer + * @size: the requested pre-allocation size in bytes + * @max: max. buffer size acceptable for the changes via proc file + * + * Do pre-allocation for the PCI bus. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_preallocate_pci_pages(struct pci_dev *pci, snd_pcm_substream_t *substream, size_t size, size_t max) @@ -364,6 +473,20 @@ return snd_pcm_lib_preallocate_pages1(substream, size, max); } +/* + * FIXME: the function name is too long for docbook! + * + * snd_pcm_lib_preallocate_pci_pages_for_all - pre-allocation for the PCI bus (all substreams) + * @pci: pci device + * @pcm: pcm to assign the buffer + * @size: the requested pre-allocation size in bytes + * @max: max. buffer size acceptable for the changes via proc file + * + * Do pre-allocation to all substreams of the given pcm for the + * PCI bus. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_preallocate_pci_pages_for_all(struct pci_dev *pci, snd_pcm_t *pcm, size_t size, size_t max) @@ -381,7 +504,17 @@ #endif /* CONFIG_PCI */ #ifdef CONFIG_SBUS - +/** + * snd_pcm_lib_preallocate_sbus_pages - pre-allocation for the SBUS bus + * + * @sbus: SBUS device + * @substream: substream to assign the buffer + * @max: max. buffer size acceptable for the changes via proc file + * + * Do pre-allocation for the SBUS. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_preallocate_sbus_pages(struct sbus_dev *sdev, snd_pcm_substream_t *substream, size_t size, size_t max) @@ -391,6 +524,20 @@ return snd_pcm_lib_preallocate_pages1(substream, size, max); } +/* + * FIXME: the function name is too long for docbook! + * + * snd_pcm_lib_preallocate_sbus_pages_for_all - pre-allocation for the SBUS bus (all substreams) + * @sbus: SBUS device + * @pcm: pcm to assign the buffer + * @size: the requested pre-allocation size in bytes + * @max: max. buffer size acceptable for the changes via proc file + * + * Do pre-allocation to all substreams of the given pcm for the + * SUBS. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_pcm_lib_preallocate_sbus_pages_for_all(struct sbus_dev *sdev, snd_pcm_t *pcm, size_t size, size_t max) diff -Nru a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c --- a/sound/core/pcm_misc.c Sun Feb 9 21:13:35 2003 +++ b/sound/core/pcm_misc.c Sun Feb 9 21:13:35 2003 @@ -30,6 +30,13 @@ #define snd_enum_to_int(v) (v) #define snd_int_to_enum(v) (v) +/** + * snd_pcm_format_signed - Check the PCM format is signed linear + * @format: the format to check + * + * Returns 1 if the given PCM format is signed linear, 0 if unsigned + * linear, and a negative error code for non-linear formats. + */ int snd_pcm_format_signed(snd_pcm_format_t format) { switch (snd_enum_to_int(format)) { @@ -66,6 +73,13 @@ } } +/** + * snd_pcm_format_unsigned - Check the PCM format is unsigned linear + * @format: the format to check + * + * Returns 1 if the given PCM format is unsigned linear, 0 if signed + * linear, and a negative error code for non-linear formats. + */ int snd_pcm_format_unsigned(snd_pcm_format_t format) { int val; @@ -76,11 +90,24 @@ return !val; } +/** + * snd_pcm_format_linear - Check the PCM format is linear + * @format: the format to check + * + * Returns 1 if the given PCM format is linear, 0 if not. + */ int snd_pcm_format_linear(snd_pcm_format_t format) { return snd_pcm_format_signed(format) >= 0; } +/** + * snd_pcm_format_little_endian - Check the PCM format is little-endian + * @format: the format to check + * + * Returns 1 if the given PCM format is little-endian, 0 if + * big-endian, or a negative error code if endian not specified. + */ int snd_pcm_format_little_endian(snd_pcm_format_t format) { switch (snd_enum_to_int(format)) { @@ -121,6 +148,13 @@ } } +/** + * snd_pcm_format_big_endian - Check the PCM format is big-endian + * @format: the format to check + * + * Returns 1 if the given PCM format is big-endian, 0 if + * little-endian, or a negative error code if endian not specified. + */ int snd_pcm_format_big_endian(snd_pcm_format_t format) { int val; @@ -131,6 +165,13 @@ return !val; } +/** + * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian + * @format: the format to check + * + * Returns 1 if the given PCM format is CPU-endian, 0 if + * opposite, or a negative error code if endian not specified. + */ int snd_pcm_format_cpu_endian(snd_pcm_format_t format) { #ifdef SNDRV_LITTLE_ENDIAN @@ -140,6 +181,13 @@ #endif } +/** + * snd_pcm_format_width - return the bit-width of the format + * @format: the format to check + * + * Returns the bit-width of the format, or a negative error code + * if unknown format. + */ int snd_pcm_format_width(snd_pcm_format_t format) { switch (snd_enum_to_int(format)) { @@ -193,6 +241,13 @@ } } +/** + * snd_pcm_format_physical_width - return the physical bit-width of the format + * @format: the format to check + * + * Returns the physical bit-width of the format, or a negative error code + * if unknown format. + */ int snd_pcm_format_physical_width(snd_pcm_format_t format) { switch (snd_enum_to_int(format)) { @@ -243,6 +298,13 @@ } } +/** + * snd_pcm_format_size - return the byte size of samples on the given format + * @format: the format to check + * + * Returns the byte size of the given samples for the format, or a + * negative error code if unknown format. + */ ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples) { switch (snd_enum_to_int(format)) { @@ -296,6 +358,12 @@ } } +/** + * snd_pcm_format_silence_64 - return the silent data in 64bit integer + * @format: the format to check + * + * Returns the silent data in 64bit integer for the given format. + */ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format) { switch (snd_enum_to_int(format)) { @@ -451,6 +519,16 @@ return (u_int8_t)snd_pcm_format_silence_64(format); } +/** + * snd_pcm_format_set_silence - set the silence data on the buffer + * @format: the PCM format + * @data: the buffer pointer + * @samples: the number of samples to set silence + * + * Sets the silence data on the buffer for the given samples. + * + * Returns zero if sucessful, or a negative error code on failure. + */ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples) { if (samples == 0) @@ -497,6 +575,7 @@ #endif } } + break; } case 32: { u_int32_t silence = snd_pcm_format_silence_64(format); @@ -543,6 +622,14 @@ SNDRV_PCM_FORMAT_U32_BE }; +/** + * snd_pcm_build_linear_format - return the suitable linear format for the given condition + * @width: the bit-width + * @unsignd: 1 if unsigned, 0 if signed. + * @big_endian: 1 if big-endian, 0 if little-endian + * + * Returns the suitable linear format for the given condition. + */ snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian) { switch (width) { diff -Nru a/sound/core/pcm_native.c b/sound/core/pcm_native.c --- a/sound/core/pcm_native.c Sun Feb 9 21:13:30 2003 +++ b/sound/core/pcm_native.c Sun Feb 9 21:13:30 2003 @@ -76,6 +76,8 @@ set_fs(fs); } + + int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info) { snd_pcm_runtime_t * runtime; @@ -674,6 +676,9 @@ snd_pcm_tick_prepare(substream); } +/** + * snd_pcm_sart + */ int snd_pcm_start(snd_pcm_substream_t *substream) { SND_PCM_ACTION(start, substream, 0); @@ -703,6 +708,9 @@ wake_up(&runtime->sleep); } +/** + * snd_pcm_stop + */ int snd_pcm_stop(snd_pcm_substream_t *substream, int state) { SND_PCM_ACTION(stop, substream, state); @@ -779,11 +787,17 @@ wake_up(&runtime->sleep); } +/** + * snd_pcm_suspend + */ int snd_pcm_suspend(snd_pcm_substream_t *substream) { SND_PCM_ACTION(suspend, substream, 0); } +/** + * snd_pcm_suspend_all + */ int snd_pcm_suspend_all(snd_pcm_t *pcm) { snd_pcm_substream_t *substream; @@ -976,6 +990,9 @@ runtime->status->state = SNDRV_PCM_STATE_PREPARED; } +/** + * snd_pcm_prepare + */ int snd_pcm_prepare(snd_pcm_substream_t *substream) { int res; @@ -1081,6 +1098,8 @@ /* Fall through */ case SNDRV_PCM_STATE_SETUP: goto _end; + default: + break; } if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) { @@ -1183,6 +1202,8 @@ spin_lock_irq(&runtime->lock); } goto _xrun_recovery; + default: + break; } runtime->control->appl_ptr = runtime->status->hw_ptr; _end: @@ -1236,6 +1257,8 @@ spin_lock_irq(&runtime->lock); } goto _xrun_recovery; + default: + break; } _end: spin_unlock_irq(&runtime->lock); @@ -1278,6 +1301,8 @@ case SNDRV_PCM_STATE_XRUN: snd_pcm_change_state(substream, SNDRV_PCM_STATE_SETUP); break; + default: + break; } runtime->control->appl_ptr = runtime->status->hw_ptr; _end: @@ -1779,9 +1804,6 @@ snd_pcm_file_t *pcm_file; wait_queue_t wait; -#ifdef LINUX_2_2 - MOD_INC_USE_COUNT; -#endif snd_runtime_check(device >= SNDRV_MINOR_PCM_PLAYBACK && device < SNDRV_MINOR_DEVICES, return -ENXIO); pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)]; if (pcm == NULL) { @@ -1829,9 +1851,6 @@ __error2: snd_card_file_remove(pcm->card, file); __error1: -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif return err; } @@ -1857,9 +1876,6 @@ wake_up(&pcm->open_wait); module_put(pcm->card->module); snd_card_file_remove(pcm->card, file); -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif return 0; } @@ -1895,7 +1911,7 @@ ret = 0; goto __end; } - if (frames > hw_avail) + if (frames > (snd_pcm_uframes_t)hw_avail) frames = hw_avail; else frames -= frames % runtime->xfer_align; @@ -1944,7 +1960,7 @@ ret = 0; goto __end; } - if (frames > hw_avail) + if (frames > (snd_pcm_uframes_t)hw_avail) frames = hw_avail; else frames -= frames % runtime->xfer_align; @@ -2724,7 +2740,7 @@ offset = area->vm_offset; #endif dma_bytes = PAGE_ALIGN(runtime->dma_bytes); - if (size > dma_bytes) + if ((size_t)size > dma_bytes) return -EINVAL; if (offset > dma_bytes - size) return -EINVAL; diff -Nru a/sound/core/pcm_sgbuf.c b/sound/core/pcm_sgbuf.c --- a/sound/core/pcm_sgbuf.c Sun Feb 9 21:13:36 2003 +++ b/sound/core/pcm_sgbuf.c Sun Feb 9 21:13:36 2003 @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -30,358 +31,200 @@ #define SGBUF_TBL_ALIGN 32 #define sgbuf_align_table(tbl) ((((tbl) + SGBUF_TBL_ALIGN - 1) / SGBUF_TBL_ALIGN) * SGBUF_TBL_ALIGN) -/* - * shrink to the given pages. - * free the unused pages - */ -static void sgbuf_shrink(struct snd_sg_buf *sgbuf, int pages) -{ - snd_assert(sgbuf, return); - if (! sgbuf->table) - return; - while (sgbuf->pages > pages) { - sgbuf->pages--; - snd_free_pci_pages(sgbuf->pci, PAGE_SIZE, - sgbuf->table[sgbuf->pages].buf, - sgbuf->table[sgbuf->pages].addr); - } -} /* - * initialize the sg buffer - * assigned to substream->dma_private. - * initialize the table with the given size. + * snd_pcm_sgbuf_new - constructor of the sgbuf instance + * @pci: pci device pointer + * + * Initializes the SG-buffer instance to be assigned to + * substream->dma_private. + * + * Returns the pointer of the instance, or NULL at error. */ -int snd_pcm_sgbuf_init(snd_pcm_substream_t *substream, struct pci_dev *pci, int tblsize) +struct snd_sg_buf *snd_pcm_sgbuf_new(struct pci_dev *pci) { struct snd_sg_buf *sgbuf; - tblsize = sgbuf_align_table(tblsize); sgbuf = snd_magic_kcalloc(snd_pcm_sgbuf_t, 0, GFP_KERNEL); if (! sgbuf) - return -ENOMEM; - substream->dma_private = sgbuf; + return NULL; sgbuf->pci = pci; sgbuf->pages = 0; - sgbuf->tblsize = tblsize; - sgbuf->table = kmalloc(sizeof(struct snd_sg_page) * tblsize, GFP_KERNEL); - if (! sgbuf->table) { - snd_pcm_sgbuf_delete(substream); - return -ENOMEM; - } - memset(sgbuf->table, 0, sizeof(struct snd_sg_page) * tblsize); - return 0; -} + sgbuf->tblsize = 0; -/* - * release all pages and free the sgbuf instance - */ -int snd_pcm_sgbuf_delete(snd_pcm_substream_t *substream) -{ - struct snd_sg_buf *sgbuf; - - /* return in case, when sgbuf is not initialized */ - if (substream->dma_private == NULL) - return -EINVAL; - sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL); - sgbuf_shrink(sgbuf, 0); - if (sgbuf->table) - kfree(sgbuf->table); - snd_magic_kfree(sgbuf); - substream->dma_private = NULL; - return 0; + return sgbuf; } /* - * snd_pci_alloc_page - allocate a page in the valid pci dma mask + * snd_pcm_sgbuf_delete - destructor of sgbuf instance + * @sgbuf: the SG-buffer instance * - * returns the virtual address and stores the physical address on - * addrp. this function cannot be called from interrupt handlers or - * within spinlocks. + * Destructor Releaes all pages and free the sgbuf instance. */ -#ifdef __i386__ -/* - * on ix86, we allocate a page with GFP_KERNEL to assure the - * allocation. the code is almost same with kernel/i386/pci-dma.c but - * it allocates only a single page and checkes the validity of the - * page address with the given pci dma mask. - */ -inline static void *snd_pci_alloc_page(struct pci_dev *pci, dma_addr_t *addrp) +void snd_pcm_sgbuf_delete(struct snd_sg_buf *sgbuf) { - void *ptr; - dma_addr_t addr; - unsigned long rmask; - - if (pci) - rmask = ~(unsigned long)pci->dma_mask; - else - rmask = 0; - ptr = (void *)__get_free_page(GFP_KERNEL); - if (ptr) { - addr = virt_to_phys(ptr); - if (((unsigned long)addr + PAGE_SIZE - 1) & rmask) { - /* try to reallocate with the GFP_DMA */ - free_page((unsigned long)ptr); - ptr = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); - if (ptr) /* ok, the address must be within lower 16MB... */ - addr = virt_to_phys(ptr); - else - addr = 0; - } - } else - addr = 0; - if (ptr) - memset(ptr, 0, PAGE_SIZE); - *addrp = addr; - return ptr; + snd_pcm_sgbuf_free_pages(sgbuf, NULL); + snd_magic_kfree(sgbuf); } -#else -/* on other architectures, call snd_malloc_pci_pages() helper function - * which uses pci_alloc_consistent(). - */ -#define snd_pci_alloc_page(pci, addrp) snd_malloc_pci_pages(pci, PAGE_SIZE, addrp) -#endif -/* - * allocate sg buffer table with the given byte size. - * if the buffer table already exists, try to resize it. - * call this from hw_params callback. +/** + * snd_pcm_sgbuf_alloc_pages - allocate the pages for the SG buffer + * @sgbuf: the sgbuf instance + * @size: the requested buffer size in bytes + * + * Allocates the buffer pages for the given size and updates the + * sg buffer table. The pages are mapped to the virtually continuous + * memory. + * + * This function is usually called from snd_pcm_lib_malloc_pages(). + * + * Returns the mapped virtual address of the buffer if allocation was + * successful, or NULL at error. */ -int snd_pcm_sgbuf_alloc(snd_pcm_substream_t *substream, size_t size) +void *snd_pcm_sgbuf_alloc_pages(struct snd_sg_buf *sgbuf, size_t size) { - struct snd_sg_buf *sgbuf; - unsigned int pages; - unsigned int tblsize; - int changed = 0; + unsigned int i, pages; + void *vmaddr; - sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL); pages = snd_pcm_sgbuf_pages(size); - tblsize = sgbuf_align_table(pages); - if (pages < sgbuf->pages) { - /* release unsed pages */ - sgbuf_shrink(sgbuf, pages); - if (substream->runtime) - substream->runtime->dma_bytes = size; - return 1; /* changed */ - } else if (pages > sgbuf->tblsize) { - /* bigger than existing one. reallocate the table. */ - struct snd_sg_page *table; - table = kmalloc(sizeof(*table) * tblsize, GFP_KERNEL); - if (! table) - return -ENOMEM; - memcpy(table, sgbuf->table, sizeof(*table) * sgbuf->tblsize); - kfree(sgbuf->table); - sgbuf->table = table; - sgbuf->tblsize = tblsize; - } + sgbuf->tblsize = sgbuf_align_table(pages); + sgbuf->table = snd_kcalloc(sizeof(*sgbuf->table) * sgbuf->tblsize, GFP_KERNEL); + if (! sgbuf->table) + goto _failed; + sgbuf->page_table = snd_kcalloc(sizeof(*sgbuf->page_table) * sgbuf->tblsize, GFP_KERNEL); + if (! sgbuf->page_table) + goto _failed; + /* allocate each page */ - while (sgbuf->pages < pages) { + for (i = 0; i < pages; i++) { void *ptr; dma_addr_t addr; - ptr = snd_pci_alloc_page(sgbuf->pci, &addr); + ptr = snd_malloc_pci_page(sgbuf->pci, &addr); if (! ptr) - return -ENOMEM; - sgbuf->table[sgbuf->pages].buf = ptr; - sgbuf->table[sgbuf->pages].addr = addr; + goto _failed; + sgbuf->table[i].buf = ptr; + sgbuf->table[i].addr = addr; + sgbuf->page_table[i] = virt_to_page(ptr); sgbuf->pages++; - changed = 1; } + sgbuf->size = size; - if (substream->runtime) - substream->runtime->dma_bytes = size; - return changed; + vmaddr = vmap(sgbuf->page_table, sgbuf->pages); + if (! vmaddr) + goto _failed; + return vmaddr; + + _failed: + snd_pcm_sgbuf_free_pages(sgbuf, NULL); /* free the table */ + return NULL; } -/* - * free the sg buffer - * the table is kept. - * call this from hw_free callback. +/** + * snd_pcm_sgbuf_free_pages - free the sg buffer + * @sgbuf: the sgbuf instance + * @vmaddr: the mapped virtual address + * + * Releases the pages and the mapped tables. + * + * This function is called usually from snd_pcm_lib_free_pages(). + * + * Returns zero if successful, or a negative error code on failure. */ -int snd_pcm_sgbuf_free(snd_pcm_substream_t *substream) +int snd_pcm_sgbuf_free_pages(struct snd_sg_buf *sgbuf, void *vmaddr) { - struct snd_sg_buf *sgbuf; + if (vmaddr) + vunmap(vmaddr); - sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL); - sgbuf_shrink(sgbuf, 0); + while (sgbuf->pages > 0) { + sgbuf->pages--; + snd_free_pci_page(sgbuf->pci, sgbuf->table[sgbuf->pages].buf, + sgbuf->table[sgbuf->pages].addr); + } + if (sgbuf->table) + kfree(sgbuf->table); + sgbuf->table = NULL; + if (sgbuf->page_table) + kfree(sgbuf->page_table); + sgbuf->page_table = NULL; + sgbuf->tblsize = 0; + sgbuf->pages = 0; + sgbuf->size = 0; + return 0; } -/* - * get the page pointer on the given offset - */ -static void *sgbuf_get_addr(snd_pcm_substream_t *substream, unsigned long offset) -{ - struct snd_sg_buf *sgbuf; - unsigned int idx; - - sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return NULL); - idx = offset >> PAGE_SHIFT; - if (idx >= sgbuf->pages) - return 0; - return sgbuf->table[idx].buf; -} - -/* - * get the page struct at the given offset - * used as the page callback of pcm ops +/** + * snd_pcm_sgbuf_ops_page - get the page struct at the given offset + * @substream: the pcm substream instance + * @offset: the buffer offset + * + * Returns the page struct at the given buffer offset. + * Used as the page callback of PCM ops. */ struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset) { - void *addr = sgbuf_get_addr(substream, offset); - if (addr) - return virt_to_page(addr); - else - return 0; -} + struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return NULL); -/* - * do copy_from_user to the sg buffer - */ -static int copy_from_user_sg_buf(snd_pcm_substream_t *substream, - char *buf, size_t hwoff, ssize_t bytes) -{ - int len; - char *addr; - size_t p = (hwoff >> PAGE_SHIFT) << PAGE_SHIFT; - hwoff -= p; - len = PAGE_SIZE - hwoff; - for (;;) { - addr = sgbuf_get_addr(substream, p); - if (! addr) - return -EFAULT; - if (len > bytes) - len = bytes; - if (copy_from_user(addr + hwoff, buf, len)) - return -EFAULT; - bytes -= len; - if (bytes <= 0) - break; - buf += len; - p += PAGE_SIZE; - len = PAGE_SIZE; - hwoff = 0; - } - return 0; + unsigned int idx = offset >> PAGE_SHIFT; + if (idx >= (unsigned int)sgbuf->pages) + return NULL; + return sgbuf->page_table[idx]; } -/* - * do copy_to_user from the sg buffer - */ -static int copy_to_user_sg_buf(snd_pcm_substream_t *substream, - char *buf, size_t hwoff, ssize_t bytes) -{ - int len; - char *addr; - size_t p = (hwoff >> PAGE_SHIFT) << PAGE_SHIFT; - hwoff -= p; - len = PAGE_SIZE - hwoff; - for (;;) { - addr = sgbuf_get_addr(substream, p); - if (! addr) - return -EFAULT; - if (len > bytes) - len = bytes; - if (copy_to_user(buf, addr + hwoff, len)) - return -EFAULT; - bytes -= len; - if (bytes <= 0) - break; - buf += len; - p += PAGE_SIZE; - len = PAGE_SIZE; - hwoff = 0; - } - return 0; -} -/* - * set silence on the sg buffer +/** + * snd_pcm_lib_preallocate_sg_pages - initialize SG-buffer for the PCI bus + * + * @pci: pci device + * @substream: substream to assign the buffer + * + * Initializes SG-buffer for the PCI bus. + * + * Returns zero if successful, or a negative error code on failure. */ -static int set_silence_sg_buf(snd_pcm_substream_t *substream, - size_t hwoff, ssize_t samples) +int snd_pcm_lib_preallocate_sg_pages(struct pci_dev *pci, + snd_pcm_substream_t *substream) { - snd_pcm_runtime_t *runtime = substream->runtime; - int len, page_len; - char *addr; - size_t p = (hwoff >> PAGE_SHIFT) << PAGE_SHIFT; - hwoff -= p; - len = bytes_to_samples(substream->runtime, PAGE_SIZE - hwoff); - page_len = bytes_to_samples(substream->runtime, PAGE_SIZE); - for (;;) { - addr = sgbuf_get_addr(substream, p); - if (! addr) - return -EFAULT; - if (len > samples) - len = samples; - snd_pcm_format_set_silence(runtime->format, addr + hwoff, len); - samples -= len; - if (samples <= 0) - break; - p += PAGE_SIZE; - len = page_len; - hwoff = 0; - } + if ((substream->dma_private = snd_pcm_sgbuf_new(pci)) == NULL) + return -ENOMEM; + substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI_SG; + substream->dma_area = 0; + substream->dma_addr = 0; + substream->dma_bytes = 0; + substream->buffer_bytes_max = UINT_MAX; + substream->dma_max = 0; return 0; } /* - * copy callback for playback pcm ops - */ -int snd_pcm_sgbuf_ops_copy_playback(snd_pcm_substream_t *substream, int channel, - snd_pcm_uframes_t hwoff, void *buf, snd_pcm_uframes_t count) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - if (channel < 0) { - return copy_from_user_sg_buf(substream, buf, frames_to_bytes(runtime, hwoff), frames_to_bytes(runtime, count)); - } else { - size_t dma_csize = runtime->dma_bytes / runtime->channels; - size_t c_ofs = (channel * dma_csize) + samples_to_bytes(runtime, hwoff); - return copy_from_user_sg_buf(substream, buf, c_ofs, samples_to_bytes(runtime, count)); - } -} - -/* - * copy callback for capture pcm ops + * FIXME: the function name is too long for docbook! + * + * snd_pcm_lib_preallocate_sg_pages_for_all - initialize SG-buffer for the PCI bus (all substreams) + * @pci: pci device + * @pcm: pcm to assign the buffer + * + * Initialize the SG-buffer to all substreams of the given pcm for the + * PCI bus. + * + * Returns zero if successful, or a negative error code on failure. */ -int snd_pcm_sgbuf_ops_copy_capture(snd_pcm_substream_t *substream, int channel, - snd_pcm_uframes_t hwoff, void *buf, snd_pcm_uframes_t count) +int snd_pcm_lib_preallocate_sg_pages_for_all(struct pci_dev *pci, + snd_pcm_t *pcm) { - snd_pcm_runtime_t *runtime = substream->runtime; - if (channel < 0) { - return copy_to_user_sg_buf(substream, buf, frames_to_bytes(runtime, hwoff), frames_to_bytes(runtime, count)); - } else { - size_t dma_csize = runtime->dma_bytes / runtime->channels; - size_t c_ofs = (channel * dma_csize) + samples_to_bytes(runtime, hwoff); - return copy_to_user_sg_buf(substream, buf, c_ofs, samples_to_bytes(runtime, count)); - } -} + snd_pcm_substream_t *substream; + int stream, err; -/* - * silence callback for pcm ops - */ -int snd_pcm_sgbuf_ops_silence(snd_pcm_substream_t *substream, int channel, - snd_pcm_uframes_t hwoff, snd_pcm_uframes_t count) -{ - snd_pcm_runtime_t *runtime = substream->runtime; - if (channel < 0) { - return set_silence_sg_buf(substream, frames_to_bytes(runtime, hwoff), - frames_to_bytes(runtime, count)); - } else { - size_t dma_csize = runtime->dma_bytes / runtime->channels; - size_t c_ofs = (channel * dma_csize) + samples_to_bytes(runtime, hwoff); - return set_silence_sg_buf(substream, c_ofs, samples_to_bytes(runtime, count)); - } + for (stream = 0; stream < 2; stream++) + for (substream = pcm->streams[stream].substream; substream; substream = substream->next) + if ((err = snd_pcm_lib_preallocate_sg_pages(pci, substream)) < 0) + return err; + return 0; } /* * Exported symbols */ -EXPORT_SYMBOL(snd_pcm_sgbuf_init); -EXPORT_SYMBOL(snd_pcm_sgbuf_delete); -EXPORT_SYMBOL(snd_pcm_sgbuf_alloc); -EXPORT_SYMBOL(snd_pcm_sgbuf_free); -EXPORT_SYMBOL(snd_pcm_sgbuf_ops_copy_playback); -EXPORT_SYMBOL(snd_pcm_sgbuf_ops_copy_capture); -EXPORT_SYMBOL(snd_pcm_sgbuf_ops_silence); +EXPORT_SYMBOL(snd_pcm_lib_preallocate_sg_pages); +EXPORT_SYMBOL(snd_pcm_lib_preallocate_sg_pages_for_all); EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); diff -Nru a/sound/core/rawmidi.c b/sound/core/rawmidi.c --- a/sound/core/rawmidi.c Sun Feb 9 21:13:29 2003 +++ b/sound/core/rawmidi.c Sun Feb 9 21:13:29 2003 @@ -181,9 +181,6 @@ if (rfile) rfile->input = rfile->output = NULL; -#ifdef LINUX_2_2 - MOD_INC_USE_COUNT; -#endif rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device]; if (rmidi == NULL) { err = -ENODEV; @@ -199,7 +196,7 @@ err = -ENXIO; goto __error; } - if (subdevice >= 0 && subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_count) { + if (subdevice >= 0 && (unsigned int)subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substream_count) { err = -ENODEV; goto __error; } @@ -214,7 +211,7 @@ err = -ENXIO; goto __error; } - if (subdevice >= 0 && subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_count) { + if (subdevice >= 0 && (unsigned int)subdevice >= rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_count) { err = -ENODEV; goto __error; } @@ -342,9 +339,6 @@ module_put(rmidi->card->module); up(&rmidi->open_mutex); __error1: -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif return err; } @@ -499,9 +493,6 @@ } up(&rmidi->open_mutex); module_put(rmidi->card->module); -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif return 0; } @@ -571,7 +562,7 @@ return -ENXIO; list_for_each(list, &pstr->substreams) { substream = list_entry(list, snd_rawmidi_substream_t, list); - if (substream->number == info->subdevice) + if ((unsigned int)substream->number == info->subdevice) return snd_rawmidi_info(substream, info); } return -ENXIO; @@ -824,6 +815,16 @@ return -ENOIOCTLCMD; } +/** + * snd_rawmidi_receive - receive the input data from the device + * @substream: the rawmidi substream + * @buffer: the buffer pointer + * @count: the data size to read + * + * Reads the data from the internal buffer. + * + * Returns the size of read data, or a negative error code on failure. + */ int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, const unsigned char *buffer, int count) { unsigned long flags; @@ -850,7 +851,7 @@ count1 = runtime->buffer_size - runtime->hw_ptr; if (count1 > count) count1 = count; - if (count1 > runtime->buffer_size - runtime->avail) + if (count1 > (int)(runtime->buffer_size - runtime->avail)) count1 = runtime->buffer_size - runtime->avail; memcpy(runtime->buffer + runtime->hw_ptr, buffer, count1); runtime->hw_ptr += count1; @@ -861,7 +862,7 @@ if (count > 0) { buffer += count1; count1 = count; - if (count1 > runtime->buffer_size - runtime->avail) { + if (count1 > (int)(runtime->buffer_size - runtime->avail)) { count1 = runtime->buffer_size - runtime->avail; runtime->xruns = count - count1; } @@ -895,7 +896,7 @@ if (count1 > count) count1 = count; spin_lock_irqsave(&runtime->lock, flags); - if (count1 > runtime->avail) + if (count1 > (int)runtime->avail) count1 = runtime->avail; if (kernel) { memcpy(buf + result, runtime->buffer + runtime->appl_ptr, count1); @@ -968,6 +969,12 @@ return result; } +/** + * snd_rawmidi_transmit_empty - check whether the output buffer is empty + * @substream: the rawmidi substream + * + * Returns 1 if the internal output buffer is empty, 0 if not. + */ int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream) { snd_rawmidi_runtime_t *runtime = substream->runtime; @@ -986,6 +993,20 @@ return result; } +/** + * snd_rawmidi_transmit_peek - copy data from the internal buffer + * @substream: the rawmidi substream + * @buffer: the buffer pointer + * @count: data size to transfer + * + * Copies data from the internal output buffer to the given buffer. + * + * Call this in the interrupt handler when the midi output is ready, + * and call snd_rawmidi_transmit_ack() after the transmission is + * finished. + * + * Returns the size of copied data, or a negative error code on failure. + */ int snd_rawmidi_transmit_peek(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count) { unsigned long flags; @@ -1010,7 +1031,7 @@ count1 = runtime->buffer_size - runtime->hw_ptr; if (count1 > count) count1 = count; - if (count1 > runtime->buffer_size - runtime->avail) + if (count1 > (int)(runtime->buffer_size - runtime->avail)) count1 = runtime->buffer_size - runtime->avail; memcpy(buffer, runtime->buffer + runtime->hw_ptr, count1); count -= count1; @@ -1023,6 +1044,17 @@ return result; } +/** + * snd_rawmidi_transmit_ack - acknowledge the transmission + * @substream: the rawmidi substream + * @count: the tranferred count + * + * Advances the hardware pointer for the internal output buffer with + * the given size and updates the condition. + * Call after the transmission is finished. + * + * Returns the advanced size if successful, or a negative error code on failure. + */ int snd_rawmidi_transmit_ack(snd_rawmidi_substream_t * substream, int count) { unsigned long flags; @@ -1050,6 +1082,16 @@ return count; } +/** + * snd_rawmidi_transmit - copy from the buffer to the device + * @substream: the rawmidi substream + * @buf: the buffer pointer + * @count: the data size to transfer + * + * Copies data from the buffer to the device and advances the pointer. + * + * Returns the copied size if successful, or a negative error code on failure. + */ int snd_rawmidi_transmit(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count) { count = snd_rawmidi_transmit_peek(substream, buffer, count); @@ -1070,7 +1112,7 @@ result = 0; spin_lock_irqsave(&runtime->lock, flags); if (substream->append) { - if (runtime->avail < count) { + if ((long)runtime->avail < count) { spin_unlock_irqrestore(&runtime->lock, flags); return -EAGAIN; } @@ -1079,7 +1121,7 @@ count1 = runtime->buffer_size - runtime->appl_ptr; if (count1 > count) count1 = count; - if (count1 > runtime->avail) + if (count1 > (long)runtime->avail) count1 = runtime->avail; if (kernel) { memcpy(runtime->buffer + runtime->appl_ptr, buf, count1); @@ -1153,7 +1195,7 @@ continue; result += count1; buf += count1; - if (count1 < count && (file->f_flags & O_NONBLOCK)) + if ((size_t)count1 < count && (file->f_flags & O_NONBLOCK)) break; count -= count1; } @@ -1313,6 +1355,20 @@ return 0; } +/** + * snd_rawmidi_new - create a rawmidi instance + * @card: the card instance + * @id: the id string + * @device: the device index + * @output_count: the number of output streams + * @input_count: the number of input streams + * @rrawmidi: the pointer to store the new rawmidi instance + * + * Creates a new rawmidi instance. + * Use snd_rawmidi_set_ops() to set the operators to the new instance. + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_rawmidi_new(snd_card_t * card, char *id, int device, int output_count, int input_count, snd_rawmidi_t ** rrawmidi) @@ -1424,7 +1480,7 @@ } #ifdef CONFIG_SND_OSSEMUL rmidi->ossreg = 0; - if (rmidi->device == midi_map[rmidi->card->number]) { + if ((int)rmidi->device == midi_map[rmidi->card->number]) { if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 0, &snd_rawmidi_reg, name) < 0) { snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0); @@ -1435,7 +1491,7 @@ #endif } } - if (rmidi->device == amidi_map[rmidi->card->number]) { + if ((int)rmidi->device == amidi_map[rmidi->card->number]) { if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 1, &snd_rawmidi_reg, name) < 0) { snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1); @@ -1498,13 +1554,13 @@ } #ifdef CONFIG_SND_OSSEMUL if (rmidi->ossreg) { - if (rmidi->device == midi_map[rmidi->card->number]) { + if ((int)rmidi->device == midi_map[rmidi->card->number]) { snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 0); #ifdef SNDRV_OSS_INFO_DEV_MIDI snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_MIDI, rmidi->card->number); #endif } - if (rmidi->device == amidi_map[rmidi->card->number]) + if ((int)rmidi->device == amidi_map[rmidi->card->number]) snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, rmidi->card, 1); rmidi->ossreg = 0; } @@ -1522,6 +1578,14 @@ return snd_rawmidi_free(rmidi); } +/** + * snd_rawmidi_set_ops - set the rawmidi operators + * @rmidi: the rawmidi instance + * @stream: the stream direction, SNDRV_RAWMIDI_STREAM_XXX + * @ops: the operator table + * + * Sets the rawmidi operators for the given stream direction. + */ void snd_rawmidi_set_ops(snd_rawmidi_t *rmidi, int stream, snd_rawmidi_ops_t *ops) { struct list_head *list; diff -Nru a/sound/core/rtctimer.c b/sound/core/rtctimer.c --- a/sound/core/rtctimer.c Sun Feb 9 21:13:35 2003 +++ b/sound/core/rtctimer.c Sun Feb 9 21:13:35 2003 @@ -37,9 +37,6 @@ #include #endif -/* use tasklet for interrupt handling */ -#define USE_TASKLET - #define RTC_FREQ 1024 /* default frequency */ #define NANO_SEC 1000000000L /* 10^9 in sec */ @@ -69,10 +66,6 @@ static atomic_t rtc_inc = ATOMIC_INIT(0); static rtc_task_t rtc_task; -/* tasklet */ -#ifdef USE_TASKLET -static struct tasklet_struct rtc_tq; -#endif static int rtctimer_open(snd_timer_t *t) @@ -83,7 +76,6 @@ if (err < 0) return err; t->private_data = &rtc_task; - MOD_INC_USE_COUNT; return 0; } @@ -95,7 +87,6 @@ rtc_unregister(rtc); t->private_data = NULL; } - MOD_DEC_USE_COUNT; return 0; } @@ -124,31 +115,13 @@ */ static void rtctimer_interrupt(void *private_data) { - atomic_inc(&rtc_inc); -#ifdef USE_TASKLET - tasklet_hi_schedule(&rtc_tq); -#else - { - int ticks = atomic_read(&rtc_inc); - snd_timer_interrupt((snd_timer_t*)private_data, ticks); - atomic_sub(ticks, &rtc_inc); - } -#endif /* USE_TASKLET */ -} - -#ifdef USE_TASKLET -static void rtctimer_interrupt2(unsigned long private_data) -{ - snd_timer_t *timer = (snd_timer_t *)private_data; int ticks; - snd_assert(timer != NULL, return); - do { - ticks = atomic_read(&rtc_inc); - snd_timer_interrupt(timer, ticks); - } while (!atomic_sub_and_test(ticks, &rtc_inc)); + atomic_inc(&rtc_inc); + ticks = atomic_read(&rtc_inc); + snd_timer_interrupt((snd_timer_t*)private_data, ticks); + atomic_sub(ticks, &rtc_inc); } -#endif /* USE_TASKLET */ /* @@ -174,10 +147,6 @@ err = snd_timer_global_new("rtc", SNDRV_TIMER_GLOBAL_RTC, &timer); if (err < 0) return err; - -#ifdef USE_TASKLET - tasklet_init(&rtc_tq, rtctimer_interrupt2, (unsigned long)timer); -#endif /* USE_TASKLET */ strcpy(timer->name, "RTC timer"); timer->hw = rtc_hw; diff -Nru a/sound/core/seq/Makefile b/sound/core/seq/Makefile --- a/sound/core/seq/Makefile Sun Feb 9 21:13:36 2003 +++ b/sound/core/seq/Makefile Sun Feb 9 21:13:36 2003 @@ -8,9 +8,6 @@ obj-$(CONFIG_SND_SEQUENCER) += oss/ endif -export-objs := seq_device.o seq.o seq_instr.o seq_midi_emul.o \ - seq_midi_event.o seq_virmidi.o - snd-seq-device-objs := seq_device.o snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \ seq_fifo.o seq_prioq.o seq_timer.o \ @@ -22,6 +19,17 @@ snd-seq-dummy-objs := seq_dummy.o snd-seq-virmidi-objs := seq_virmidi.o +RAWMIDI_OBJS = snd-seq-midi.o snd-seq-midi-event.o +OPL3_OBJS = snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o + +# +# this function returns: +# "m" - CONFIG_SND_SEQUENCER is m +# - CONFIG_SND_SEQUENCER is undefined +# otherwise parameter #1 value +# +sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) + obj-$(CONFIG_SND_SEQUENCER) += snd-seq.o snd-seq-device.o ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) obj-$(CONFIG_SND_SEQUENCER) += snd-seq-midi-event.o @@ -29,53 +37,52 @@ obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o # Toplevel Module Dependency -RAWMIDI_OBJS = snd-seq-midi.o snd-seq-midi-event.o -OPL3_OBJS = snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o -obj-$(CONFIG_SND_SERIAL_U16550) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_MTPAV) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_MPU401) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_ALS100) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_AZT2320) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_DT019X) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_ES18XX) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_OPL3SA2) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_AD1816A) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_CS4231) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_CS4232) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_CS4236) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_PC98_CS4232) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_ES1688) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_GUSCLASSIC) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_GUSMAX) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_GUSEXTREME) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_INTERWAVE) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_INTERWAVE_STB) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_OPTI92X_AD1848) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_OPTI92X_CS4231) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_OPTI93X) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_SB8) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_SB16) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_SBAWE) += $(RAWMIDI_OBJS) $(OPL3_OBJS) snd-seq-virmidi.o -obj-$(CONFIG_SND_ES968) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_WAVEFRONT) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_ALS4000) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_CMIPCI) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_CS4281) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_ENS1370) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_ENS1371) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_ES1938) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_ES1968) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_FM801) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_ICE1712) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_INTEL8X0) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_SONICVIBES) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_VIA82XX) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_ALI5451) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_CS46XX) += $(RAWMIDI_OBJS) -obj-$(CONFIG_SND_EMU10K1) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-virmidi.o -obj-$(CONFIG_SND_TRIDENT) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-instr.o -obj-$(CONFIG_SND_YMFPCI) += $(RAWMIDI_OBJS) $(OPL3_OBJS) -obj-$(CONFIG_SND_USB_AUDIO) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_SERIAL_U16550)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_MTPAV)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_MPU401)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_ALS100)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_AZT2320)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_DT019X)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_ES18XX)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_OPL3SA2)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_AD1816A)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_CS4231)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_CS4232)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_CS4236)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_PC98_CS4232)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_ES1688)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_GUSEXTREME)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_INTERWAVE)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_INTERWAVE_STB)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_OPTI92X_AD1848)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_OPTI92X_CS4231)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_OPTI93X)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_SB8)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_SB16)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) snd-seq-virmidi.o +obj-$(call sequencer,$(CONFIG_SND_ES968)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_WAVEFRONT)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_ALS4000)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_CMIPCI)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_CS4281)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_ENS1370)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_ENS1371)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_ES1938)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_ES1968)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_FM801)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_ICE1712)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_INTEL8X0)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_SONICVIBES)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_VIA82XX)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_ALI5451)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_CS46XX)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-virmidi.o +obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-instr.o +obj-$(call sequencer,$(CONFIG_SND_YMFPCI)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) +obj-$(call sequencer,$(CONFIG_SND_USB_AUDIO)) += $(RAWMIDI_OBJS) +obj-$(call sequencer,$(CONFIG_SND_HDSP)) += $(RAWMIDI_OBJS) obj-m := $(sort $(obj-m)) diff -Nru a/sound/core/seq/instr/Makefile b/sound/core/seq/instr/Makefile --- a/sound/core/seq/instr/Makefile Sun Feb 9 21:13:35 2003 +++ b/sound/core/seq/instr/Makefile Sun Feb 9 21:13:35 2003 @@ -3,43 +3,49 @@ # Copyright (c) 1999 by Jaroslav Kysela # -export-objs := ainstr_fm.o ainstr_simple.o ainstr_gf1.o ainstr_iw.o - snd-ainstr-fm-objs := ainstr_fm.o snd-ainstr-simple-objs := ainstr_simple.o snd-ainstr-gf1-objs := ainstr_gf1.o snd-ainstr-iw-objs := ainstr_iw.o +# +# this function returns: +# "m" - CONFIG_SND_SEQUENCER is m +# - CONFIG_SND_SEQUENCER is undefined +# otherwise parameter #1 value +# +sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) + # Toplevel Module Dependency -obj-$(CONFIG_SND_ALS100) += snd-ainstr-fm.o -obj-$(CONFIG_SND_AZT2320) += snd-ainstr-fm.o -obj-$(CONFIG_SND_DT019X) += snd-ainstr-fm.o -obj-$(CONFIG_SND_ES18XX) += snd-ainstr-fm.o -obj-$(CONFIG_SND_OPL3SA2) += snd-ainstr-fm.o -obj-$(CONFIG_SND_AD1816A) += snd-ainstr-fm.o -obj-$(CONFIG_SND_CS4232) += snd-ainstr-fm.o -obj-$(CONFIG_SND_CS4236) += snd-ainstr-fm.o -obj-$(CONFIG_SND_PC98_CS4232) += snd-ainstr-fm.o -obj-$(CONFIG_SND_ES1688) += snd-ainstr-fm.o -obj-$(CONFIG_SND_GUSCLASSIC) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o -obj-$(CONFIG_SND_GUSMAX) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o -obj-$(CONFIG_SND_GUSEXTREME) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o snd-ainstr-fm.o -obj-$(CONFIG_SND_INTERWAVE) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o -obj-$(CONFIG_SND_INTERWAVE_STB) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o -obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-ainstr-fm.o -obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-ainstr-fm.o -obj-$(CONFIG_SND_OPTI93X) += snd-ainstr-fm.o -obj-$(CONFIG_SND_SB8) += snd-ainstr-fm.o -obj-$(CONFIG_SND_SB16) += snd-ainstr-fm.o -obj-$(CONFIG_SND_SBAWE) += snd-ainstr-fm.o -obj-$(CONFIG_SND_WAVEFRONT) += snd-ainstr-fm.o -obj-$(CONFIG_SND_ALS4000) += snd-ainstr-fm.o -obj-$(CONFIG_SND_CMIPCI) += snd-ainstr-fm.o -obj-$(CONFIG_SND_CS4281) += snd-ainstr-fm.o -obj-$(CONFIG_SND_ES1938) += snd-ainstr-fm.o -obj-$(CONFIG_SND_FM801) += snd-ainstr-fm.o -obj-$(CONFIG_SND_SONICVIBES) += snd-ainstr-fm.o -obj-$(CONFIG_SND_TRIDENT) += snd-ainstr-simple.o -obj-$(CONFIG_SND_YMFPCI) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_ALS100)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_AZT2320)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_DT019X)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_ES18XX)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_OPL3SA2)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_AD1816A)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_CS4232)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_CS4236)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_PC98_CS4232)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_ES1688)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o +obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o +obj-$(call sequencer,$(CONFIG_SND_GUSEXTREME)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_INTERWAVE)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o +obj-$(call sequencer,$(CONFIG_SND_INTERWAVE_STB)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o +obj-$(call sequencer,$(CONFIG_SND_OPTI92X_AD1848)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_OPTI92X_CS4231)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_OPTI93X)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_SB8)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_SB16)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_WAVEFRONT)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_ALS4000)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_CMIPCI)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_CS4281)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_ES1938)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_FM801)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_SONICVIBES)) += snd-ainstr-fm.o +obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-ainstr-simple.o +obj-$(call sequencer,$(CONFIG_SND_YMFPCI)) += snd-ainstr-fm.o obj-m := $(sort $(obj-m)) diff -Nru a/sound/core/seq/instr/ainstr_fm.c b/sound/core/seq/instr/ainstr_fm.c --- a/sound/core/seq/instr/ainstr_fm.c Sun Feb 9 21:13:31 2003 +++ b/sound/core/seq/instr/ainstr_fm.c Sun Feb 9 21:13:31 2003 @@ -44,7 +44,7 @@ if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE) return -EINVAL; /* copy instrument data */ - if (len < sizeof(ix)) + if (len < (long)sizeof(ix)) return -EINVAL; if (copy_from_user(&ix, instr_data, sizeof(ix))) return -EFAULT; @@ -85,7 +85,7 @@ if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL) return -EINVAL; - if (len < sizeof(ix)) + if (len < (long)sizeof(ix)) return -ENOMEM; memset(&ix, 0, sizeof(ix)); ip = (fm_instrument_t *)KINSTR_DATA(instr); diff -Nru a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c --- a/sound/core/seq/instr/ainstr_gf1.c Sun Feb 9 21:13:34 2003 +++ b/sound/core/seq/instr/ainstr_gf1.c Sun Feb 9 21:13:34 2003 @@ -58,7 +58,7 @@ unsigned int real_size; gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; - if (*len < sizeof(xp)) + if (*len < (long)sizeof(xp)) return -EINVAL; if (copy_from_user(&xp, *data, sizeof(xp))) return -EFAULT; @@ -95,7 +95,7 @@ wp->scale_frequency = le16_to_cpu(xp.scale_frequency); wp->scale_factor = le16_to_cpu(xp.scale_factor); real_size = snd_seq_gf1_size(wp->size, wp->format); - if (real_size > *len) { + if ((long)real_size > *len) { kfree(wp); return -ENOMEM; } @@ -152,7 +152,7 @@ return -EINVAL; gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; /* copy instrument data */ - if (len < sizeof(ix)) + if (len < (long)sizeof(ix)) return -EINVAL; if (copy_from_user(&ix, instr_data, sizeof(ix))) return -EFAULT; @@ -168,7 +168,7 @@ ip->effect2 = ix.effect2; ip->effect2_depth = ix.effect2_depth; /* copy layers */ - while (len > sizeof(__u32)) { + while (len > (long)sizeof(__u32)) { __u32 stype; if (copy_from_user(&stype, instr_data, sizeof(stype))) @@ -202,7 +202,7 @@ unsigned int real_size; for (wp = ip->wave; wp; wp = wp->next) { - if (*len < sizeof(xp)) + if (*len < (long)sizeof(xp)) return -ENOMEM; memset(&xp, 0, sizeof(xp)); xp.stype = GF1_STRU_WAVE; @@ -238,7 +238,7 @@ *data += sizeof(xp); *len -= sizeof(xp); real_size = snd_seq_gf1_size(wp->size, wp->format); - if (*len < real_size) + if (*len < (long)real_size) return -ENOMEM; if (ops->get_sample) { err = ops->get_sample(ops->private_data, wp, @@ -261,7 +261,7 @@ if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL) return -EINVAL; - if (len < sizeof(ix)) + if (len < (long)sizeof(ix)) return -ENOMEM; memset(&ix, 0, sizeof(ix)); ip = (gf1_instrument_t *)KINSTR_DATA(instr); diff -Nru a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c --- a/sound/core/seq/instr/ainstr_iw.c Sun Feb 9 21:13:32 2003 +++ b/sound/core/seq/instr/ainstr_iw.c Sun Feb 9 21:13:32 2003 @@ -76,7 +76,7 @@ ep->index = ex->index; rp_last = NULL; while (1) { - if (*len < sizeof(__u32)) + if (*len < (long)sizeof(__u32)) return -EINVAL; if (copy_from_user(&stype, data, sizeof(stype))) return -EFAULT; @@ -87,7 +87,7 @@ stype == IWFFFF_STRU_ENV_RECV) return 0; } - if (*len < sizeof(rx)) + if (*len < (long)sizeof(rx)) return -EINVAL; if (copy_from_user(&rx, *data, sizeof(rx))) return -EFAULT; @@ -136,7 +136,7 @@ unsigned int real_size; gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; - if (*len < sizeof(xp)) + if (*len < (long)sizeof(xp)) return -EINVAL; if (copy_from_user(&xp, *data, sizeof(xp))) return -EFAULT; @@ -162,7 +162,7 @@ wp->high_note = xp.high_note; real_size = snd_seq_iwffff_size(wp->size, wp->format); if (!(wp->format & IWFFFF_WAVE_ROM)) { - if (real_size > *len) { + if ((long)real_size > *len) { kfree(wp); return -ENOMEM; } @@ -243,7 +243,7 @@ return -EINVAL; gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; /* copy instrument data */ - if (len < sizeof(ix)) + if (len < (long)sizeof(ix)) return -EINVAL; if (copy_from_user(&ix, instr_data, sizeof(ix))) return -EFAULT; @@ -262,7 +262,7 @@ /* copy layers */ prev_lp = NULL; while (len > 0) { - if (len < sizeof(iwffff_xlayer_t)) { + if (len < (long)sizeof(iwffff_xlayer_t)) { snd_seq_iwffff_instr_free(ops, ip, atomic); return -EINVAL; } @@ -315,7 +315,7 @@ snd_seq_iwffff_instr_free(ops, ip, atomic); return err; } - while (len > sizeof(__u32)) { + while (len > (long)sizeof(__u32)) { __u32 stype; if (copy_from_user(&stype, instr_data, sizeof(stype))) @@ -363,7 +363,7 @@ ex->mode = ep->mode; ex->index = ep->index; for (rp = ep->record; rp; rp = rp->next) { - if (*len < sizeof(rx)) + if (*len < (long)sizeof(rx)) return -ENOMEM; memset(&rx, 0, sizeof(rx)); rx.stype = req_stype; @@ -405,7 +405,7 @@ unsigned int real_size; for (wp = lp->wave; wp; wp = wp->next) { - if (*len < sizeof(xp)) + if (*len < (long)sizeof(xp)) return -ENOMEM; memset(&xp, 0, sizeof(xp)); xp.stype = IWFFFF_STRU_WAVE; @@ -431,7 +431,7 @@ *len -= sizeof(xp); real_size = snd_seq_iwffff_size(wp->size, wp->format); if (!(wp->format & IWFFFF_WAVE_ROM)) { - if (*len < real_size) + if (*len < (long)real_size) return -ENOMEM; } if (ops->get_sample) { @@ -461,7 +461,7 @@ if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL) return -EINVAL; - if (len < sizeof(ix)) + if (len < (long)sizeof(ix)) return -ENOMEM; memset(&ix, 0, sizeof(ix)); ip = (iwffff_instrument_t *)KINSTR_DATA(instr); @@ -478,7 +478,7 @@ instr_data += sizeof(ix); len -= sizeof(ix); for (lp = ip->layer; lp; lp = lp->next) { - if (len < sizeof(lx)) + if (len < (long)sizeof(lx)) return -ENOMEM; memset(&lx, 0, sizeof(lx)); lx.stype = IWFFFF_STRU_LAYER; diff -Nru a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c --- a/sound/core/seq/instr/ainstr_simple.c Sun Feb 9 21:13:35 2003 +++ b/sound/core/seq/instr/ainstr_simple.c Sun Feb 9 21:13:35 2003 @@ -67,7 +67,7 @@ return -EINVAL; gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; /* copy instrument data */ - if (len < sizeof(ix)) + if (len < (long)sizeof(ix)) return -EINVAL; if (copy_from_user(&ix, instr_data, sizeof(ix))) return -EFAULT; @@ -91,7 +91,7 @@ ip->effect2 = ix.effect2; ip->effect2_depth = ix.effect2_depth; real_size = snd_seq_simple_size(ip->size, ip->format); - if (len < real_size) + if (len < (long)real_size) return -EINVAL; if (ops->put_sample) { err = ops->put_sample(ops->private_data, ip, @@ -113,7 +113,7 @@ if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL) return -EINVAL; - if (len < sizeof(ix)) + if (len < (long)sizeof(ix)) return -ENOMEM; memset(&ix, 0, sizeof(ix)); ip = (simple_instrument_t *)KINSTR_DATA(instr); @@ -137,7 +137,7 @@ instr_data += sizeof(ix); len -= sizeof(ix); real_size = snd_seq_simple_size(ip->size, ip->format); - if (len < real_size) + if (len < (long)real_size) return -ENOMEM; if (ops->get_sample) { err = ops->get_sample(ops->private_data, ip, diff -Nru a/sound/core/seq/oss/Makefile b/sound/core/seq/oss/Makefile --- a/sound/core/seq/oss/Makefile Sun Feb 9 21:13:31 2003 +++ b/sound/core/seq/oss/Makefile Sun Feb 9 21:13:31 2003 @@ -7,6 +7,4 @@ seq_oss_event.o seq_oss_rw.o seq_oss_synth.o \ seq_oss_midi.o seq_oss_readq.o seq_oss_writeq.o -ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) - obj-$(CONFIG_SND_SEQUENCER) += snd-seq-oss.o -endif +obj-$(CONFIG_SND_SEQUENCER) += snd-seq-oss.o diff -Nru a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c --- a/sound/core/seq/oss/seq_oss_init.c Sun Feb 9 21:13:28 2003 +++ b/sound/core/seq/oss/seq_oss_init.c Sun Feb 9 21:13:28 2003 @@ -275,9 +275,6 @@ client_table[dp->index] = dp; num_clients++; -#ifdef LINUX_2_2 - MOD_INC_USE_COUNT; -#endif debug_printk(("open done\n")); @@ -434,9 +431,6 @@ if (dp->queue >= 0) delete_seq_queue(dp); -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif debug_printk(("release done\n")); } diff -Nru a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c --- a/sound/core/seq/oss/seq_oss_midi.c Sun Feb 9 21:13:28 2003 +++ b/sound/core/seq/oss/seq_oss_midi.c Sun Feb 9 21:13:28 2003 @@ -217,7 +217,6 @@ midi_devs[mdev->seq_device] = mdev; spin_unlock_irqrestore(®ister_lock, flags); - /*MOD_INC_USE_COUNT;*/ return 0; } diff -Nru a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c --- a/sound/core/seq/seq_clientmgr.c Sun Feb 9 21:13:29 2003 +++ b/sound/core/seq/seq_clientmgr.c Sun Feb 9 21:13:29 2003 @@ -339,10 +339,6 @@ /* make others aware this new client */ snd_seq_system_client_ev_client_start(c); -#ifdef LINUX_2_2 - MOD_INC_USE_COUNT; -#endif - return 0; } @@ -358,9 +354,6 @@ kfree(client); } -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif return 0; } @@ -1013,7 +1006,7 @@ if (snd_seq_ev_is_variable(&event)) { int extlen = event.data.ext.len & ~SNDRV_SEQ_EXT_MASK; - if (extlen + len > count) { + if ((size_t)(extlen + len) > count) { /* back out, will get an error this time or next */ err = -EINVAL; break; diff -Nru a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c --- a/sound/core/seq/seq_instr.c Sun Feb 9 21:13:31 2003 +++ b/sound/core/seq/seq_instr.c Sun Feb 9 21:13:31 2003 @@ -145,7 +145,7 @@ static int instr_free_compare(snd_seq_kinstr_t *instr, snd_seq_instr_header_t *ifree, - int client) + unsigned int client) { switch (ifree->cmd) { case SNDRV_SEQ_INSTR_FREE_CMD_ALL: @@ -193,7 +193,7 @@ instr = list->hash[idx]; prev = flist = NULL; while (instr) { - while (instr && instr_free_compare(instr, ifree, client)) { + while (instr && instr_free_compare(instr, ifree, (unsigned int)client)) { prev = instr; instr = instr->next; } diff -Nru a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c --- a/sound/core/seq/seq_midi.c Sun Feb 9 21:13:35 2003 +++ b/sound/core/seq/seq_midi.c Sun Feb 9 21:13:35 2003 @@ -280,7 +280,8 @@ seq_midisynth_t *msynth, *ms; snd_seq_port_info_t port; snd_rawmidi_info_t info; - int newclient = 0, p, ports; + int newclient = 0; + unsigned int p, ports; snd_seq_client_callback_t callbacks; snd_seq_port_callback_t pcallbacks; snd_seq_client_info_t inf; diff -Nru a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c --- a/sound/core/seq/seq_midi_emul.c Sun Feb 9 21:13:36 2003 +++ b/sound/core/seq/seq_midi_emul.c Sun Feb 9 21:13:36 2003 @@ -506,7 +506,7 @@ len--; /* GM on */ - if (len >= sizeof(gm_on_macro) && + if (len >= (int)sizeof(gm_on_macro) && memcmp(buf, gm_on_macro, sizeof(gm_on_macro)) == 0) { if (chset->midi_mode != SNDRV_MIDI_MODE_GS && chset->midi_mode != SNDRV_MIDI_MODE_XG) { @@ -568,7 +568,7 @@ } /* XG on */ - else if (len >= sizeof(xg_on_macro) && + else if (len >= (int)sizeof(xg_on_macro) && memcmp(buf, xg_on_macro, sizeof(xg_on_macro)) == 0) { int i; chset->midi_mode = SNDRV_MIDI_MODE_XG; diff -Nru a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c --- a/sound/core/seq/seq_midi_event.c Sun Feb 9 21:13:28 2003 +++ b/sound/core/seq/seq_midi_event.c Sun Feb 9 21:13:28 2003 @@ -108,8 +108,6 @@ /*{SNDRV_SEQ_EVENT_REGPARAM, extra_decode_rpn},*/ }; -#define numberof(ary) (sizeof(ary)/sizeof(ary[0])) - /* * new/delete record */ @@ -349,16 +347,16 @@ */ long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count, snd_seq_event_t *ev) { - int cmd, type; + unsigned int cmd, type; if (ev->type == SNDRV_SEQ_EVENT_NONE) return -ENOENT; - for (type = 0; type < numberof(status_event); type++) { + for (type = 0; type < ARRAY_SIZE(status_event); type++) { if (ev->type == status_event[type].event) goto __found; } - for (type = 0; type < numberof(extra_event); type++) { + for (type = 0; type < ARRAY_SIZE(extra_event); type++) { if (ev->type == extra_event[type].event) return extra_event[type].decode(dev, buf, count, ev); } diff -Nru a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c --- a/sound/core/seq/seq_ports.c Sun Feb 9 21:13:34 2003 +++ b/sound/core/seq/seq_ports.c Sun Feb 9 21:13:34 2003 @@ -610,8 +610,7 @@ /* exported */ int snd_seq_event_port_attach(int client, snd_seq_port_callback_t *pcbp, - int cap, - int type, + int cap, int type, int midi_channels, char *portname) { snd_seq_port_info_t portinfo; @@ -628,6 +627,7 @@ portinfo.capability = cap; portinfo.type = type; portinfo.kernel = pcbp; + portinfo.midi_channels = midi_channels; /* Create it */ ret = snd_seq_kernel_client_ctl(client, diff -Nru a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c --- a/sound/core/seq/seq_queue.c Sun Feb 9 21:13:35 2003 +++ b/sound/core/seq/seq_queue.c Sun Feb 9 21:13:35 2003 @@ -47,8 +47,6 @@ #include "seq_timer.h" #include "seq_info.h" -static void snd_seq_check_queue_in_tasklet(unsigned long private_data); - /* list of allocated queues */ static queue_t *queue_list[SNDRV_SEQ_MAX_QUEUES]; static spinlock_t queue_list_lock = SPIN_LOCK_UNLOCKED; @@ -123,7 +121,6 @@ spin_lock_init(&q->check_lock); init_MUTEX(&q->timer_mutex); snd_use_lock_init(&q->use_lock); - tasklet_init(&q->taskq, snd_seq_check_queue_in_tasklet, (unsigned long)q); q->queue = -1; q->tickq = snd_seq_prioq_new(); @@ -148,7 +145,7 @@ static void queue_delete(queue_t *q) { /* stop and release the timer */ - snd_seq_timer_stop(q->timer, 0); + snd_seq_timer_stop(q->timer); snd_seq_timer_close(q); /* wait until access free */ snd_use_lock_sync(&q->use_lock); @@ -258,8 +255,6 @@ void snd_seq_check_queue(queue_t *q, int atomic, int hop) { unsigned long flags; - int dequeue; - int rc; snd_seq_event_cell_t *cell; if (q == NULL) @@ -275,27 +270,13 @@ q->check_blocked = 1; spin_unlock_irqrestore(&q->check_lock, flags); - if (atomic) - dequeue = SNDRV_SEQ_MAX_DEQUEUE; - else - dequeue = 0x7fffffff; /* XXX */ - __again: /* Process tick queue... */ - - /* limit the number of elements dequeued per pass to save the machine from lockups */ - while (dequeue > 0) { - - cell = snd_seq_prioq_cell_peek(q->tickq); - if (cell == NULL) - break; + while ((cell = snd_seq_prioq_cell_peek(q->tickq)) != NULL) { if (snd_seq_compare_tick_time(&q->timer->tick.cur_tick, &cell->event.time.tick)) { cell = snd_seq_prioq_cell_out(q->tickq); - if (cell != NULL) { - rc = snd_seq_dispatch_event(cell, atomic, hop); - if (rc > 0) - dequeue -= rc; - } + if (cell) + snd_seq_dispatch_event(cell, atomic, hop); } else { /* event remains in the queue */ break; @@ -304,20 +285,11 @@ /* Process time queue... */ - - /* limit the number of elements dequeued per pass to save the machine from lockups */ - while (dequeue > 0) { - cell = snd_seq_prioq_cell_peek(q->timeq); - if (cell == NULL) - break; + while ((cell = snd_seq_prioq_cell_peek(q->timeq)) != NULL) { if (snd_seq_compare_real_time(&q->timer->cur_time, &cell->event.time.time)) { cell = snd_seq_prioq_cell_out(q->timeq); - if (cell != NULL) { - rc = snd_seq_dispatch_event(cell, atomic, hop); - if (rc > 0) - dequeue -= rc; - } - + if (cell) + snd_seq_dispatch_event(cell, atomic, hop); } else { /* event remains in the queue */ break; @@ -326,23 +298,15 @@ /* free lock */ spin_lock_irqsave(&q->check_lock, flags); - if (q->check_again && dequeue > 0) { + if (q->check_again) { q->check_again = 0; spin_unlock_irqrestore(&q->check_lock, flags); goto __again; } q->check_blocked = 0; - if (dequeue <= 0 && atomic) - tasklet_hi_schedule(&q->taskq); spin_unlock_irqrestore(&q->check_lock, flags); } -/* tasklet */ -static void snd_seq_check_queue_in_tasklet(unsigned long private_data) -{ - queue_t *q = (queue_t *)private_data; - snd_seq_check_queue(q, 0, 0); -} /* enqueue a event to singe queue */ int snd_seq_enqueue_event(snd_seq_event_cell_t *cell, int atomic, int hop) @@ -606,7 +570,7 @@ spin_unlock_irqrestore(&q->owner_lock, flags); if (q->owner == client) { if (q->timer->running) - snd_seq_timer_stop(q->timer, 0); + snd_seq_timer_stop(q->timer); snd_seq_timer_reset(q->timer); } queuefree(q); @@ -716,17 +680,17 @@ case SNDRV_SEQ_EVENT_START: snd_seq_prioq_leave(q->tickq, ev->source.client, 1); snd_seq_prioq_leave(q->timeq, ev->source.client, 1); - if (! snd_seq_timer_start(q->timer, atomic)) + if (! snd_seq_timer_start(q->timer)) queue_broadcast_event(q, ev, from_timer_port, atomic, hop); break; case SNDRV_SEQ_EVENT_CONTINUE: - if (! snd_seq_timer_continue(q->timer, atomic)) + if (! snd_seq_timer_continue(q->timer)) queue_broadcast_event(q, ev, from_timer_port, atomic, hop); break; case SNDRV_SEQ_EVENT_STOP: - snd_seq_timer_stop(q->timer, atomic); + snd_seq_timer_stop(q->timer); queue_broadcast_event(q, ev, from_timer_port, atomic, hop); break; diff -Nru a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h --- a/sound/core/seq/seq_queue.h Sun Feb 9 21:13:30 2003 +++ b/sound/core/seq/seq_queue.h Sun Feb 9 21:13:30 2003 @@ -57,8 +57,6 @@ struct semaphore timer_mutex; snd_use_lock_t use_lock; - - struct tasklet_struct taskq; }; diff -Nru a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c --- a/sound/core/seq/seq_timer.c Sun Feb 9 21:13:35 2003 +++ b/sound/core/seq/seq_timer.c Sun Feb 9 21:13:35 2003 @@ -88,7 +88,7 @@ t->running = 0; /* reset time */ - snd_seq_timer_stop(t, 0); + snd_seq_timer_stop(t); snd_seq_timer_reset(t); kfree(t); @@ -133,10 +133,10 @@ /* called by timer interrupt routine. the period time since previous invocation is passed */ static void snd_seq_timer_interrupt(snd_timer_instance_t *timeri, unsigned long resolution, - unsigned long ticks, void *data) + unsigned long ticks) { unsigned long flags; - queue_t *q = (queue_t *)data; + queue_t *q = (queue_t *)timeri->callback_data; seq_timer_t *tmr; if (q == NULL) @@ -180,7 +180,7 @@ if (tempo <= 0) return -EINVAL; spin_lock_irqsave(&tmr->lock, flags); - if (tempo != tmr->tempo) { + if ((unsigned int)tempo != tmr->tempo) { tmr->tempo = tempo; snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1); } @@ -312,17 +312,14 @@ return 0; } -int snd_seq_timer_stop(seq_timer_t * tmr, int in_callback) +int snd_seq_timer_stop(seq_timer_t * tmr) { if (! tmr->timeri) return -EINVAL; if (!tmr->running) return 0; tmr->running = 0; - if (in_callback) - snd_timer_del(tmr->timeri); - else - snd_timer_stop(tmr->timeri); + snd_timer_stop(tmr->timeri); return 0; } @@ -348,12 +345,12 @@ return 0; } -int snd_seq_timer_start(seq_timer_t * tmr, int in_callback) +int snd_seq_timer_start(seq_timer_t * tmr) { if (! tmr->timeri) return -EINVAL; if (tmr->running) - snd_seq_timer_stop(tmr, in_callback); + snd_seq_timer_stop(tmr); snd_seq_timer_reset(tmr); if (initialize_timer(tmr) < 0) return -EINVAL; @@ -363,7 +360,7 @@ return 0; } -int snd_seq_timer_continue(seq_timer_t * tmr, int in_callback) +int snd_seq_timer_continue(seq_timer_t * tmr) { if (! tmr->timeri) return -EINVAL; diff -Nru a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h --- a/sound/core/seq/seq_timer.h Sun Feb 9 21:13:34 2003 +++ b/sound/core/seq/seq_timer.h Sun Feb 9 21:13:34 2003 @@ -127,9 +127,9 @@ int snd_seq_timer_midi_close(queue_t *q); void snd_seq_timer_defaults(seq_timer_t *tmr); void snd_seq_timer_reset(seq_timer_t *tmr); -int snd_seq_timer_stop(seq_timer_t *tmr, int in_callback); -int snd_seq_timer_start(seq_timer_t *tmr, int in_callback); -int snd_seq_timer_continue(seq_timer_t *tmr, int in_callback); +int snd_seq_timer_stop(seq_timer_t *tmr); +int snd_seq_timer_start(seq_timer_t *tmr); +int snd_seq_timer_continue(seq_timer_t *tmr); int snd_seq_timer_set_tempo(seq_timer_t *tmr, int tempo); int snd_seq_timer_set_ppq(seq_timer_t *tmr, int ppq); int snd_seq_timer_set_position_tick(seq_timer_t *tmr, snd_seq_tick_time_t position); diff -Nru a/sound/core/sound.c b/sound/core/sound.c --- a/sound/core/sound.c Sun Feb 9 21:13:34 2003 +++ b/sound/core/sound.c Sun Feb 9 21:13:34 2003 @@ -73,6 +73,13 @@ #ifdef CONFIG_KMOD +/** + * snd_request_card - try to load the card module + * @card: the card number + * + * Tries to load the module "snd-card-X" for the given card number + * via KMOD. Returns immediately if already loaded. + */ void snd_request_card(int card) { char str[32]; @@ -83,7 +90,7 @@ read_unlock(&snd_card_rwlock); if (locked) return; - if (card < 0 || card >= snd_ecards_limit) + if (card < 0 || card >= cards_limit) return; sprintf(str, "snd-card-%i", card); request_module(str); @@ -188,6 +195,19 @@ return minor; } +/** + * snd_register_device - Register the ALSA device file for the card + * @type: the device type, SNDRV_DEVICE_TYPE_XXX + * @card: the card instance + * @dev: the device index + * @reg: the snd_minor_t record + * @name: the device file name + * + * Registers an ALSA device file for the given card. + * The operators have to be set in reg parameter. + * + * Retrurns zero if successful, or a negative error code on failure. + */ int snd_register_device(int type, snd_card_t * card, int dev, snd_minor_t * reg, const char *name) { int minor = snd_kernel_minor(type, card, dev); @@ -215,6 +235,17 @@ return 0; } +/** + * snd_unregister_device - unregister the device on the given card + * @type: the device type, SNDRV_DEVICE_TYPE_XXX + * @card: the card instance + * @dev: the device index + * + * Unregisters the device file already registered via + * snd_register_device(). + * + * Returns zero if sucecessful, or a negative error code on failure + */ int snd_unregister_device(int type, snd_card_t * card, int dev) { int minor = snd_kernel_minor(type, card, dev); @@ -411,6 +442,7 @@ #ifdef CONFIG_PCI EXPORT_SYMBOL(snd_malloc_pci_pages); EXPORT_SYMBOL(snd_malloc_pci_pages_fallback); +EXPORT_SYMBOL(snd_malloc_pci_page); EXPORT_SYMBOL(snd_free_pci_pages); #endif #ifdef CONFIG_SBUS @@ -446,7 +478,7 @@ #ifdef CONFIG_ISA EXPORT_SYMBOL(snd_dma_program); EXPORT_SYMBOL(snd_dma_disable); -EXPORT_SYMBOL(snd_dma_residue); +EXPORT_SYMBOL(snd_dma_pointer); #endif /* info.c */ #ifdef CONFIG_PROC_FS @@ -463,6 +495,7 @@ EXPORT_SYMBOL(snd_info_free_device); EXPORT_SYMBOL(snd_info_register); EXPORT_SYMBOL(snd_info_unregister); +EXPORT_SYMBOL(snd_card_proc_new); #endif /* info_oss.c */ #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) diff -Nru a/sound/core/timer.c b/sound/core/timer.c --- a/sound/core/timer.c Sun Feb 9 21:13:33 2003 +++ b/sound/core/timer.c Sun Feb 9 21:13:33 2003 @@ -60,6 +60,7 @@ snd_timer_read_t *queue; spinlock_t qlock; wait_queue_head_t qchange_sleep; + struct fasync_struct *fasync; } snd_timer_user_t; /* list of timers */ @@ -97,9 +98,9 @@ } INIT_LIST_HEAD(&timeri->open_list); INIT_LIST_HEAD(&timeri->active_list); + INIT_LIST_HEAD(&timeri->ack_list); INIT_LIST_HEAD(&timeri->slave_list_head); INIT_LIST_HEAD(&timeri->slave_active_head); - timeri->in_use = (atomic_t)ATOMIC_INIT(0); timeri->timer = timer; if (timer && timer->card && !try_module_get(timer->card->module)) { @@ -185,7 +186,10 @@ slave->slave_id == master->slave_id) { list_del(&slave->open_list); list_add_tail(&slave->open_list, &master->slave_list_head); + spin_lock_irq(&slave_active_lock); slave->master = master; + slave->timer = master->timer; + spin_unlock_irq(&slave_active_lock); return; } } @@ -202,7 +206,6 @@ { snd_timer_instance_t *slave; struct list_head *p, *n; - unsigned long flags; /* check all pending slaves */ list_for_each_safe(p, n, &snd_timer_slave_list) { @@ -211,12 +214,12 @@ slave->slave_id == master->slave_id) { list_del(p); list_add_tail(p, &master->slave_list_head); - spin_lock_irqsave(&slave_active_lock, flags); - /* protected here so that timer_start() doesn't start - * this slave yet. - */ + spin_lock_irq(&slave_active_lock); slave->master = master; - spin_unlock_irqrestore(&slave_active_lock, flags); + slave->timer = master->timer; + if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) + list_add_tail(&slave->active_list, &master->slave_active_head); + spin_unlock_irq(&slave_active_lock); } } } @@ -275,6 +278,7 @@ return timeri; } +static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag); /* * close a timer instance @@ -282,7 +286,6 @@ int snd_timer_close(snd_timer_instance_t * timeri) { snd_timer_t *timer = NULL; - unsigned long flags; struct list_head *p, *n; snd_timer_instance_t *slave; @@ -303,13 +306,13 @@ /* remove slave links */ list_for_each_safe(p, n, &timeri->slave_list_head) { slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list); + spin_lock_irq(&slave_active_lock); + _snd_timer_stop(slave, 1); list_del(p); list_add_tail(p, &snd_timer_slave_list); - spin_lock_irqsave(&slave_active_lock, flags); - slave->flags &= ~SNDRV_TIMER_IFLG_RUNNING; - list_del_init(&slave->active_list); slave->master = NULL; - spin_unlock_irqrestore(&slave_active_lock, flags); + slave->timer = NULL; + spin_unlock_irq(&slave_active_lock); } up(®ister_mutex); } @@ -366,6 +369,9 @@ return 1; /* delayed start */ } +/* + * start the timer instance + */ int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks) { snd_timer_t *timer; @@ -381,96 +387,59 @@ return -EINVAL; spin_lock_irqsave(&timer->lock, flags); timeri->ticks = timeri->cticks = ticks; + timeri->pticks = 0; result = snd_timer_start1(timer, timeri, ticks); spin_unlock_irqrestore(&timer->lock, flags); return result; } -/* - * stop the timer instance. - * - * do not call this from the timer callback! - */ -int snd_timer_stop(snd_timer_instance_t * timeri) +static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag) { snd_timer_t *timer; unsigned long flags; snd_assert(timeri != NULL, return -ENXIO); - if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { - spin_lock_irqsave(&slave_active_lock, flags); - if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) { - timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; - list_del_init(&timeri->active_list); - } - spin_unlock_irqrestore(&slave_active_lock, flags); - return 0; - } timer = timeri->timer; if (! timer) return -EINVAL; spin_lock_irqsave(&timer->lock, flags); - while (atomic_read(&timeri->in_use)) { + list_del_init(&timeri->ack_list); + /* wait until the callback is finished */ + while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) { spin_unlock_irqrestore(&timer->lock, flags); udelay(10); spin_lock_irqsave(&timer->lock, flags); } - if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) { - timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; - list_del_init(&timeri->active_list); - if (!(--timer->running)) { - timer->hw.stop(timer); - if (timer->flags & SNDRV_TIMER_FLG_RESCHED) { - timer->flags &= ~SNDRV_TIMER_FLG_RESCHED; - snd_timer_reschedule(timer, 0); - if (timer->flags & SNDRV_TIMER_FLG_CHANGE) { - timer->flags &= ~SNDRV_TIMER_FLG_CHANGE; - timer->hw.start(timer); - } + list_del_init(&timeri->active_list); + if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) && + !(timeri->flags & SNDRV_TIMER_IFLG_SLAVE) && + !(--timer->running)) { + timer->hw.stop(timer); + if (timer->flags & SNDRV_TIMER_FLG_RESCHED) { + timer->flags &= ~SNDRV_TIMER_FLG_RESCHED; + snd_timer_reschedule(timer, 0); + if (timer->flags & SNDRV_TIMER_FLG_CHANGE) { + timer->flags &= ~SNDRV_TIMER_FLG_CHANGE; + timer->hw.start(timer); } } - } else if (timeri->flags & SNDRV_TIMER_IFLG_START) { - timeri->flags &= ~SNDRV_TIMER_IFLG_START; - list_del_init(&timeri->active_list); } + if (!keep_flag) + timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START); spin_unlock_irqrestore(&timer->lock, flags); return 0; } /* - * delete the timer instance from active list. + * stop the timer instance. * - * call this from the timer callback only! + * do not call this from the timer callback! */ -int snd_timer_del(snd_timer_instance_t * timeri) +int snd_timer_stop(snd_timer_instance_t * timeri) { - snd_timer_t *timer; - - snd_assert(timeri != NULL, return -ENXIO); - - if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { - timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; - list_del_init(&timeri->active_list); - return 0; - } - - timer = timeri->timer; - if (! timer) - return -EINVAL; - spin_lock(&timer->lock); - if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) { - timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; - list_del_init(&timeri->active_list); - if (!(--timer->running)) - timer->hw.stop(timer); - } else if (timeri->flags & SNDRV_TIMER_IFLG_START) { - timeri->flags &= ~SNDRV_TIMER_IFLG_START; - list_del_init(&timeri->active_list); - } - spin_unlock(&timer->lock); - return 0; + return _snd_timer_stop(timeri, 0); } /* @@ -492,6 +461,7 @@ spin_lock_irqsave(&timer->lock, flags); if (!timeri->cticks) timeri->cticks = 1; + timeri->pticks = 0; result = snd_timer_start1(timer, timeri, timer->sticks); spin_unlock_irqrestore(&timer->lock, flags); return result; @@ -532,6 +502,39 @@ timer->sticks = ticks; } +/* + * timer tasklet + * + */ +static void snd_timer_tasklet(unsigned long arg) +{ + snd_timer_t *timer = (snd_timer_t *) arg; + snd_timer_instance_t *ti; + struct list_head *p; + unsigned long resolution, ticks; + + spin_lock(&timer->lock); + /* now process all callbacks */ + while (!list_empty(&timer->sack_list_head)) { + p = timer->sack_list_head.next; /* get first item */ + ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list); + + /* remove from ack_list and make empty */ + list_del_init(p); + + ticks = ti->pticks; + ti->pticks = 0; + resolution = ti->resolution; + + ti->flags |= SNDRV_TIMER_IFLG_CALLBACK; + spin_unlock(&timer->lock); + if (ti->callback) + ti->callback(ti, resolution, ticks); + spin_lock(&timer->lock); + ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK; + } + spin_unlock(&timer->lock); +} /* * timer interrupt @@ -542,35 +545,63 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) { snd_timer_instance_t *ti, *ts; - unsigned long resolution; - LIST_HEAD(done_list_head); + unsigned long resolution, ticks; struct list_head *p, *q, *n; + int use_tasklet = 0; if (timer == NULL) return; + spin_lock(&timer->lock); + + /* remember the current resolution */ + if (timer->hw.c_resolution) + resolution = timer->hw.c_resolution(timer); + else + resolution = timer->hw.resolution; + /* loop for all active instances * here we cannot use list_for_each because the active_list of a processed * instance is relinked to done_list_head before callback is called. */ list_for_each_safe(p, n, &timer->active_list_head) { ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list); - if (ti->flags & SNDRV_TIMER_IFLG_RUNNING) { - if (ti->cticks < ticks_left) - ti->cticks = 0; - else - ti->cticks -= ticks_left; - if (!ti->cticks) { /* expired */ - if (ti->flags & SNDRV_TIMER_IFLG_AUTO) { - ti->cticks = ti->ticks; + if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING)) + continue; + ti->pticks += ticks_left; + ti->resolution = resolution; + if (ti->cticks < ticks_left) + ti->cticks = 0; + else + ti->cticks -= ticks_left; + if (ti->cticks) /* not expired */ + continue; + if (ti->flags & SNDRV_TIMER_IFLG_AUTO) { + ti->cticks = ti->ticks; + } else { + ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING; + if (--timer->running) + list_del(p); + } + if (list_empty(&ti->ack_list)) { + if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || + (ti->flags & SNDRV_TIMER_IFLG_FAST)) { + list_add_tail(&ti->ack_list, &timer->ack_list_head); + } else { + list_add_tail(&ti->ack_list, &timer->sack_list_head); + } + } + list_for_each(q, &ti->slave_active_head) { + ts = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, active_list); + ts->pticks = ti->pticks; + ts->resolution = resolution; + if (list_empty(&ts->ack_list)) { + if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || + (ti->flags & SNDRV_TIMER_IFLG_FAST)) { + list_add_tail(&ts->ack_list, &timer->ack_list_head); } else { - ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING; - timer->running--; + list_add_tail(&ts->ack_list, &timer->sack_list_head); } - /* relink to done_list */ - list_del(p); - list_add_tail(p, &done_list_head); - atomic_inc(&ti->in_use); } } } @@ -591,36 +622,32 @@ timer->hw.stop(timer); } - /* remember the current resolution */ - if (timer->hw.c_resolution) - resolution = timer->hw.c_resolution(timer); - else - resolution = timer->hw.resolution; + /* now process all fast callbacks */ + while (!list_empty(&timer->ack_list_head)) { + p = timer->ack_list_head.next; /* get first item */ + ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list); + + /* remove from ack_list and make empty */ + list_del_init(p); + + ticks = ti->pticks; + ti->pticks = 0; - /* now process all callbacks */ - list_for_each_safe(p, n, &done_list_head) { - ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list); - /* append to active_list */ - list_del(p); - if (ti->flags & SNDRV_TIMER_IFLG_RUNNING) - list_add_tail(p, &timer->active_list_head); + ti->flags |= SNDRV_TIMER_IFLG_CALLBACK; spin_unlock(&timer->lock); if (ti->callback) - ti->callback(ti, resolution, ti->ticks, ti->callback_data); - spin_lock(&slave_active_lock); - /* call callbacks of slaves */ - list_for_each(q, &ti->slave_active_head) { - ts = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, active_list); - if (ts->callback) - ts->callback(ts, resolution, ti->ticks, ts->callback_data); - } - spin_unlock(&slave_active_lock); + ti->callback(ti, resolution, ticks); spin_lock(&timer->lock); - atomic_dec(&ti->in_use); + ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK; } + + /* do we have any slow callbacks? */ + use_tasklet = !list_empty(&timer->sack_list_head); spin_unlock(&timer->lock); -} + if (use_tasklet) + tasklet_hi_schedule(&timer->task_queue); +} /* @@ -651,7 +678,10 @@ INIT_LIST_HEAD(&timer->device_list); INIT_LIST_HEAD(&timer->open_list_head); INIT_LIST_HEAD(&timer->active_list_head); + INIT_LIST_HEAD(&timer->ack_list_head); + INIT_LIST_HEAD(&timer->sack_list_head); spin_lock_init(&timer->lock); + tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer); if (card != NULL) { if ((err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)) < 0) { snd_timer_free(timer); @@ -815,7 +845,7 @@ static struct _snd_timer_hardware snd_timer_system = { - .flags = SNDRV_TIMER_HW_FIRST, + .flags = SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET, .resolution = 1000000000L / HZ, .ticks = 10000000L, .start = snd_timer_s_start, @@ -904,23 +934,26 @@ static void snd_timer_user_interrupt(snd_timer_instance_t *timeri, unsigned long resolution, - unsigned long ticks, - void *data) + unsigned long ticks) { - unsigned long flags; - snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, data, return); + snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, timeri->callback_data, return); snd_timer_read_t *r; + int _wake = 0; + spin_lock(&tu->qlock); if (tu->qused >= tu->queue_size) { tu->overrun++; } else { - spin_lock_irqsave(&tu->qlock, flags); r = &tu->queue[tu->qtail++]; tu->qtail %= tu->queue_size; r->resolution = resolution; r->ticks = ticks; tu->qused++; - spin_unlock_irqrestore(&tu->qlock, flags); + _wake++; + } + spin_unlock(&tu->qlock); + if (_wake) { + kill_fasync(&tu->fasync, SIGIO, POLL_IN); wake_up(&tu->qchange_sleep); } } @@ -942,9 +975,6 @@ return -ENOMEM; } file->private_data = tu; -#ifdef LINUX_2_2 - MOD_INC_USE_COUNT; -#endif return 0; } @@ -955,15 +985,13 @@ if (file->private_data) { tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO); file->private_data = NULL; + fasync_helper(-1, file, 0, &tu->fasync); if (tu->timeri) snd_timer_close(tu->timeri); if (tu->queue) kfree(tu->queue); snd_magic_kfree(tu); } -#ifdef LINUX_2_2 - MOD_DEC_USE_COUNT; -#endif return 0; } @@ -1092,6 +1120,7 @@ tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; if ((tu->timeri = snd_timer_open(str, &tselect.id, current->pid)) == NULL) return -ENODEV; + tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; tu->timeri->callback = snd_timer_user_interrupt; tu->timeri->callback_data = (void *)tu; return 0; @@ -1151,7 +1180,7 @@ tu->timeri->flags &= ~SNDRV_TIMER_IFLG_AUTO; } spin_unlock_irqrestore(&t->lock, flags); - if (params.queue_size > 0 && tu->queue_size != params.queue_size) { + if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) { tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); if (tr) { kfree(tu->queue); @@ -1253,6 +1282,18 @@ return -ENOTTY; } +static int snd_timer_user_fasync(int fd, struct file * file, int on) +{ + snd_timer_user_t *tu; + int err; + + tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO); + err = fasync_helper(fd, file, on, &tu->fasync); + if (err < 0) + return err; + return 0; +} + static ssize_t snd_timer_user_read(struct file *file, char *buffer, size_t count, loff_t *offset) { snd_timer_user_t *tu; @@ -1260,8 +1301,8 @@ int err = 0; tu = snd_magic_cast(snd_timer_user_t, file->private_data, return -ENXIO); + spin_lock_irq(&tu->qlock); while (count - result >= sizeof(snd_timer_read_t)) { - spin_lock_irq(&tu->qlock); while (!tu->qused) { wait_queue_t wait; @@ -1275,7 +1316,7 @@ init_waitqueue_entry(&wait, current); add_wait_queue(&tu->qchange_sleep, &wait); - spin_unlock(&tu->qlock); + spin_unlock_irq(&tu->qlock); schedule(); spin_lock_irq(&tu->qlock); @@ -1297,11 +1338,12 @@ } tu->qhead %= tu->queue_size; - spin_lock_irq(&tu->qlock); - tu->qused--; - spin_unlock_irq(&tu->qlock); + result += sizeof(snd_timer_read_t); buffer += sizeof(snd_timer_read_t); + + spin_lock_irq(&tu->qlock); + tu->qused--; } return result > 0 ? result : err; } @@ -1332,6 +1374,7 @@ .release = snd_timer_user_release, .poll = snd_timer_user_poll, .ioctl = snd_timer_user_ioctl, + .fasync = snd_timer_user_fasync, }; static snd_minor_t snd_timer_reg = @@ -1399,7 +1442,6 @@ EXPORT_SYMBOL(snd_timer_resolution); EXPORT_SYMBOL(snd_timer_start); EXPORT_SYMBOL(snd_timer_stop); -EXPORT_SYMBOL(snd_timer_del); EXPORT_SYMBOL(snd_timer_continue); EXPORT_SYMBOL(snd_timer_new); EXPORT_SYMBOL(snd_timer_global_new); diff -Nru a/sound/drivers/dummy.c b/sound/drivers/dummy.c --- a/sound/drivers/dummy.c Sun Feb 9 21:13:36 2003 +++ b/sound/drivers/dummy.c Sun Feb 9 21:13:36 2003 @@ -520,7 +520,8 @@ int __init snd_card_dummy_new_mixer(snd_card_dummy_t * dummy) { snd_card_t *card = dummy->card; - int idx, err; + unsigned int idx; + int err; snd_assert(dummy != NULL, return -EINVAL); spin_lock_init(&dummy->mixer_lock); diff -Nru a/sound/drivers/mpu401/Makefile b/sound/drivers/mpu401/Makefile --- a/sound/drivers/mpu401/Makefile Sun Feb 9 21:13:37 2003 +++ b/sound/drivers/mpu401/Makefile Sun Feb 9 21:13:37 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := mpu401_uart.o - snd-mpu401-objs := mpu401.o snd-mpu401-uart-objs := mpu401_uart.o diff -Nru a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c --- a/sound/drivers/mpu401/mpu401.c Sun Feb 9 21:13:34 2003 +++ b/sound/drivers/mpu401/mpu401.c Sun Feb 9 21:13:34 2003 @@ -40,7 +40,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */ -#ifdef CONFIG_PC9800 +#ifdef CONFIG_X86_PC9800 static int pc98ii[SNDRV_CARDS]; /* PC98-II dauther board */ #endif @@ -59,7 +59,7 @@ MODULE_PARM(irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device."); MODULE_PARM_SYNTAX(irq, SNDRV_IRQ_DESC); -#ifdef CONFIG_PC9800 +#ifdef CONFIG_X86_PC9800 MODULE_PARM(pc98ii, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM_DESC(pc98ii, "Roland MPU-PC98II support."); MODULE_PARM_SYNTAX(pc98ii, SNDRV_BOOLEAN_FALSE_DESC); @@ -85,7 +85,7 @@ if (card == NULL) return -ENOMEM; if (snd_mpu401_uart_new(card, 0, -#ifdef CONFIG_PC9800 +#ifdef CONFIG_X86_PC9800 pc98ii[dev] ? MPU401_HW_PC98II : #endif MPU401_HW_MPU401, @@ -154,6 +154,9 @@ (void)(get_option(&str,&enable[nr_dev]) == 2 && get_option(&str,&index[nr_dev]) == 2 && get_id(&str,&id[nr_dev]) == 2 && +#ifdef CONFIG_X86_PC9800 + get_option(&str,&pc98ii[nr_dev]) == 2 && +#endif get_option(&str,(int *)&port[nr_dev]) == 2 && get_option(&str,&irq[nr_dev]) == 2); nr_dev++; diff -Nru a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c --- a/sound/drivers/mpu401/mpu401_uart.c Sun Feb 9 21:13:31 2003 +++ b/sound/drivers/mpu401/mpu401_uart.c Sun Feb 9 21:13:31 2003 @@ -65,15 +65,32 @@ static void _snd_mpu401_uart_interrupt(mpu401_t *mpu) { - if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) - snd_mpu401_uart_input_read(mpu); - else + if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { + if (! test_and_set_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode)) { + spin_lock(&mpu->input_lock); + snd_mpu401_uart_input_read(mpu); + spin_unlock(&mpu->input_lock); + clear_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode); + } + } else snd_mpu401_uart_clear_rx(mpu); - /* ok. for better Tx performance try do some output when input is done */ - if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) + /* ok. for better Tx performance try do some output when input is done */ + if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && + test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { + spin_lock(&mpu->output_lock); snd_mpu401_uart_output_write(mpu); + spin_unlock(&mpu->output_lock); + } } +/** + * snd_mpu401_uart_interrupt - generic MPU401-UART interrupt handler + * @irq: the irq number + * @dev_id: mpu401 instance + * @regs: the reigster + * + * Processes the interrupt for MPU401-UART i/o. + */ void snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs) { mpu401_t *mpu = snd_magic_cast(mpu401_t, dev_id, return); @@ -83,20 +100,26 @@ _snd_mpu401_uart_interrupt(mpu); } +/* + * timer callback + * reprogram the timer and call the interrupt job + */ static void snd_mpu401_uart_timer(unsigned long data) { - unsigned long flags; mpu401_t *mpu = snd_magic_cast(mpu401_t, (void *)data, return); - spin_lock_irqsave(&mpu->timer_lock, flags); + spin_lock(&mpu->timer_lock); /*mpu->mode |= MPU401_MODE_TIMER;*/ mpu->timer.expires = 1 + jiffies; add_timer(&mpu->timer); - spin_unlock_irqrestore(&mpu->timer_lock, flags); + spin_unlock(&mpu->timer_lock); if (mpu->rmidi) _snd_mpu401_uart_interrupt(mpu); } +/* + * initialize the timer callback if not programmed yet + */ static void snd_mpu401_uart_add_timer (mpu401_t *mpu, int input) { unsigned long flags; @@ -113,6 +136,9 @@ spin_unlock_irqrestore (&mpu->timer_lock, flags); } +/* + * remove the timer callback if still active + */ static void snd_mpu401_uart_remove_timer (mpu401_t *mpu, int input) { unsigned long flags; @@ -236,7 +262,7 @@ } /* - * trigger input + * trigger input callback */ static void snd_mpu401_uart_input_trigger(snd_rawmidi_substream_t * substream, int up) { @@ -245,48 +271,48 @@ int max = 64; mpu = snd_magic_cast(mpu401_t, substream->rmidi->private_data, return); - spin_lock_irqsave(&mpu->input_lock, flags); if (up) { if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) { - /* flush FIFO */ + /* first time - flush FIFO */ while (max-- > 0) inb(MPU401D(mpu)); + if (mpu->irq < 0) + snd_mpu401_uart_add_timer(mpu, 1); + } + + /* read data in advance */ + /* prevent double enter via rawmidi->event callback */ + if (! test_and_set_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode)) { + spin_lock_irqsave(&mpu->input_lock, flags); + snd_mpu401_uart_input_read(mpu); + spin_unlock_irqrestore(&mpu->input_lock, flags); + clear_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode); } - if (mpu->irq < 0) - snd_mpu401_uart_add_timer(mpu, 1); } else { if (mpu->irq < 0) snd_mpu401_uart_remove_timer(mpu, 1); clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); } - spin_unlock_irqrestore(&mpu->input_lock, flags); - if (up) - snd_mpu401_uart_input_read(mpu); } +/* + * transfer input pending data + * call with input_lock spinlock held + */ static void snd_mpu401_uart_input_read(mpu401_t * mpu) { int max = 128; unsigned char byte; - /* prevent double enter via event callback */ - if (test_and_set_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode)) - return; - spin_lock(&mpu->input_lock); while (max-- > 0) { if (snd_mpu401_input_avail(mpu)) { byte = inb(MPU401D(mpu)); - if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) { - spin_unlock(&mpu->input_lock); + if (test_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) snd_rawmidi_receive(mpu->substream_input, &byte, 1); - spin_lock(&mpu->input_lock); - } } else { break; /* input not available */ } } - spin_unlock(&mpu->input_lock); - clear_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode); } /* @@ -297,18 +323,16 @@ * SoundBlaster AWE 64 - 2 bytes (ugly hardware) */ +/* + * write output pending bytes + * call with output_lock spinlock held + */ static void snd_mpu401_uart_output_write(mpu401_t * mpu) { unsigned char byte; int max = 256, timeout; - if (!test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) - return; - /* prevent double enter */ - if (test_and_set_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode)) - return; do { - spin_lock(&mpu->output_lock); if (snd_rawmidi_transmit_peek(mpu->substream_output, &byte, 1) == 1) { for (timeout = 100; timeout > 0; timeout--) { if (snd_mpu401_output_ready(mpu)) { @@ -321,28 +345,38 @@ snd_mpu401_uart_remove_timer (mpu, 0); max = 1; /* no other data - leave the tx loop */ } - spin_unlock(&mpu->output_lock); } while (--max > 0); - clear_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode); } +/* + * output trigger callback + */ static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream, int up) { unsigned long flags; mpu401_t *mpu; mpu = snd_magic_cast(mpu401_t, substream->rmidi->private_data, return); - spin_lock_irqsave(&mpu->output_lock, flags); if (up) { set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); + /* try to add the timer at each output trigger, + * since the output timer might have been removed in + * snd_mpu401_uart_output_write(). + */ snd_mpu401_uart_add_timer(mpu, 0); + + /* output pending data */ + /* prevent double enter via rawmidi->event callback */ + if (! test_and_set_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode)) { + spin_lock_irqsave(&mpu->output_lock, flags); + snd_mpu401_uart_output_write(mpu); + spin_unlock_irqrestore(&mpu->output_lock, flags); + clear_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode); + } } else { snd_mpu401_uart_remove_timer(mpu, 0); clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); } - spin_unlock_irqrestore(&mpu->output_lock, flags); - if (up) - snd_mpu401_uart_output_write(mpu); } /* @@ -375,6 +409,25 @@ snd_magic_kfree(mpu); } +/** + * snd_mpu401_uart_new - create an MPU401-UART instance + * @card: the card instance + * @device: the device index, zero-based + * @hardware: the hardware type, MPU401_HW_XXXX + * @port: the base address of MPU401 port + * @integrated: non-zero if the port was already reserved by the chip + * @irq: the irq number, -1 if no interrupt for mpu + * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved. + * @rrawmidi: the pointer to store the new rawmidi instance + * + * Creates a new MPU-401 instance. + * + * Note that the rawmidi instance is returned on the rrawmidi argument, + * not the mpu401 instance itself. To access to the mpu401 instance, + * cast from rawmidi->private_data (with mpu401_t magic-cast). + * + * Returns zero if successful, or a negative error code. + */ int snd_mpu401_uart_new(snd_card_t * card, int device, unsigned short hardware, unsigned long port, int integrated, @@ -418,9 +471,9 @@ snd_device_free(card, rmidi); return -EBUSY; } - mpu->irq = irq; - mpu->irq_flags = irq_flags; } + mpu->irq = irq; + mpu->irq_flags = irq_flags; strcpy(rmidi->name, "MPU-401 (UART)"); snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output); snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input); diff -Nru a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c --- a/sound/drivers/mtpav.c Sun Feb 9 21:13:35 2003 +++ b/sound/drivers/mtpav.c Sun Feb 9 21:13:35 2003 @@ -503,7 +503,7 @@ { mtpav_port_t *portp; - if (mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST) + if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST) return; portp = &mcrd->ports[mcrd->inmidiport]; diff -Nru a/sound/drivers/opl3/Makefile b/sound/drivers/opl3/Makefile --- a/sound/drivers/opl3/Makefile Sun Feb 9 21:13:28 2003 +++ b/sound/drivers/opl3/Makefile Sun Feb 9 21:13:28 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := opl3_lib.o - snd-opl3-lib-objs := opl3_lib.o opl3_synth.o ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y) snd-opl3-synth-objs := opl3_seq.o opl3_midi.o opl3_drums.o diff -Nru a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c --- a/sound/drivers/opl3/opl3_oss.c Sun Feb 9 21:13:29 2003 +++ b/sound/drivers/opl3/opl3_oss.c Sun Feb 9 21:13:29 2003 @@ -101,6 +101,7 @@ SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | SNDRV_SEQ_PORT_TYPE_MIDI_GM | SNDRV_SEQ_PORT_TYPE_SYNTH, + voices, name); if (opl3->oss_chset->port < 0) { snd_midi_channel_free_set(opl3->oss_chset); @@ -228,7 +229,7 @@ mm_segment_t fs; - if (count < sizeof(sbi)) { + if (count < (int)sizeof(sbi)) { snd_printk("FM Error: Patch record too short\n"); return -EINVAL; } diff -Nru a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c --- a/sound/drivers/opl3/opl3_seq.c Sun Feb 9 21:13:33 2003 +++ b/sound/drivers/opl3/opl3_seq.c Sun Feb 9 21:13:33 2003 @@ -204,6 +204,7 @@ SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | SNDRV_SEQ_PORT_TYPE_MIDI_GM | SNDRV_SEQ_PORT_TYPE_SYNTH, + 16, name); if (opl3->chset->port < 0) { snd_midi_channel_free_set(opl3->chset); diff -Nru a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c --- a/sound/drivers/serial-u16550.c Sun Feb 9 21:13:29 2003 +++ b/sound/drivers/serial-u16550.c Sun Feb 9 21:13:29 2003 @@ -322,17 +322,20 @@ * return 0 if found * return negative error if not found */ -static int __init snd_uart16550_detect(unsigned int io_base) +static int __init snd_uart16550_detect(snd_uart16550_t *uart) { + unsigned long io_base = uart->base; int ok; unsigned char c; - if (check_region(io_base, 8)) - return -EBUSY; - /* Do some vague tests for the presence of the uart */ - if (io_base == 0) + if (io_base == 0) { return -ENODEV; /* Not configured */ + } + + uart->res_base = request_region(io_base, 8, "Serial MIDI"); + if (uart->res_base == NULL) + return -EBUSY; ok = 1; /* uart detected unless one of the following tests should fail */ /* 8 data-bits, 1 stop-bit, parity off, DLAB = 0 */ @@ -766,11 +769,13 @@ uart->card = card; spin_lock_init(&uart->open_lock); uart->irq = -1; - if ((uart->res_base = request_region(iobase, 8, "Serial MIDI")) == NULL) { - snd_printk("unable to grab ports 0x%lx-0x%lx\n", iobase, iobase + 8 - 1); - return -EBUSY; - } uart->base = iobase; + + if ((err = snd_uart16550_detect(uart)) <= 0) { + printk(KERN_ERR "no UART detected at 0x%lx\n", iobase); + return err; + } + if (irq >= 0) { if (request_irq(irq, snd_uart16550_interrupt, SA_INTERRUPT, "Serial MIDI", (void *) uart)) { @@ -887,12 +892,6 @@ strcpy(card->driver, "Serial"); strcpy(card->shortname, "Serial midi (uart16550A)"); - - if ((err = snd_uart16550_detect(port[dev])) <= 0) { - snd_card_free(card); - printk(KERN_ERR "no UART detected at 0x%lx\n", (long)port[dev]); - return err; - } if ((err = snd_uart16550_create(card, port[dev], diff -Nru a/sound/i2c/Makefile b/sound/i2c/Makefile --- a/sound/i2c/Makefile Sun Feb 9 21:13:32 2003 +++ b/sound/i2c/Makefile Sun Feb 9 21:13:32 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := i2c.o cs8427.o tea6330t.o - snd-i2c-objs := i2c.o snd-cs8427-objs := cs8427.o snd-tea6330t-objs := tea6330t.o diff -Nru a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c --- a/sound/i2c/cs8427.c Sun Feb 9 21:13:28 2003 +++ b/sound/i2c/cs8427.c Sun Feb 9 21:13:28 2003 @@ -396,7 +396,8 @@ { cs8427_t *chip = snd_magic_cast(cs8427_t, cs8427->private_data, return -ENXIO); snd_kcontrol_t *kctl; - int idx, err; + unsigned int idx; + int err; snd_assert(play_substream && cap_substream, return -EINVAL); for (idx = 0; idx < CONTROLS; idx++) { diff -Nru a/sound/i2c/l3/Makefile b/sound/i2c/l3/Makefile --- a/sound/i2c/l3/Makefile Sun Feb 9 21:13:33 2003 +++ b/sound/i2c/l3/Makefile Sun Feb 9 21:13:33 2003 @@ -2,8 +2,6 @@ # Makefile for ALSA # -export-objs += uda1341.o - snd-uda1341-objs := uda1341.o # Module Dependency diff -Nru a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c --- a/sound/i2c/l3/uda1341.c Sun Feb 9 21:13:32 2003 +++ b/sound/i2c/l3/uda1341.c Sun Feb 9 21:13:32 2003 @@ -16,7 +16,7 @@ * 2002-04-12 Tomas Kasparek Proc interface update, code cleanup */ -/* $Id: uda1341.c,v 1.5 2002/11/09 13:12:19 perex Exp $ */ +/* $Id: uda1341.c,v 1.6 2003/01/07 10:36:28 tiwai Exp $ */ #include #include @@ -128,9 +128,6 @@ snd_card_t *card; - snd_info_entry_t *proc_entry; - snd_info_entry_t *proc_regs_entry; - uda1341_cfg cfg; }; @@ -410,46 +407,10 @@ DEBUG_NAME(KERN_DEBUG "proc_init\n"); - if ((entry = snd_info_create_card_entry(card, "uda1341", card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = clnt; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 512; - entry->c.text.read = snd_uda1341_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - uda->proc_entry = entry; - if ((entry = snd_info_create_card_entry(card, "uda1341-regs", card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = clnt; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 1024; - entry->c.text.read = snd_uda1341_proc_regs_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - uda->proc_regs_entry = entry; -} - -static void snd_uda1341_proc_done(struct l3_client *clnt) -{ - struct uda1341 *uda = clnt->driver_data; - - DEBUG_NAME(KERN_DEBUG "proc_done\n"); - - if (uda->proc_regs_entry) { - snd_info_unregister(uda->proc_regs_entry); - uda->proc_regs_entry = NULL; - } - if (uda->proc_entry) { - snd_info_unregister(uda->proc_entry); - uda->proc_entry = NULL; - } + if (! snd_card_proc_new(card, "uda1341", &entry)) + snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_read); + if (! snd_card_proc_new(card, "uda1341-regs", &entry)) { + snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_regs_read); } /* }}} */ @@ -731,7 +692,6 @@ { DEBUG_NAME(KERN_DEBUG "uda1341 mixer_del\n"); - snd_uda1341_proc_done(uda1341); l3_detach_client(uda1341); snd_magic_kfree(uda1341); diff -Nru a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c --- a/sound/i2c/tea6330t.c Sun Feb 9 21:13:32 2003 +++ b/sound/i2c/tea6330t.c Sun Feb 9 21:13:32 2003 @@ -281,7 +281,8 @@ snd_i2c_device_t *device; tea6330t_t *tea; snd_kcontrol_new_t *knew; - int idx, err = -ENOMEM; + unsigned int idx; + int err = -ENOMEM; u8 default_treble, default_bass; unsigned char bytes[7]; diff -Nru a/sound/isa/ad1816a/Makefile b/sound/isa/ad1816a/Makefile --- a/sound/isa/ad1816a/Makefile Sun Feb 9 21:13:31 2003 +++ b/sound/isa/ad1816a/Makefile Sun Feb 9 21:13:31 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := ad1816a_lib.o - snd-ad1816a-lib-objs := ad1816a_lib.o snd-ad1816a-objs := ad1816a.o diff -Nru a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c --- a/sound/isa/ad1816a/ad1816a_lib.c Sun Feb 9 21:13:33 2003 +++ b/sound/isa/ad1816a/ad1816a_lib.c Sun Feb 9 21:13:33 2003 @@ -296,7 +296,7 @@ size_t ptr; if (!(chip->mode & AD1816A_MODE_PLAYBACK)) return 0; - ptr = chip->p_dma_size - snd_dma_residue(chip->dma1); + ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -306,7 +306,7 @@ size_t ptr; if (!(chip->mode & AD1816A_MODE_CAPTURE)) return 0; - ptr = chip->c_dma_size - snd_dma_residue(chip->dma2); + ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -934,7 +934,8 @@ int snd_ad1816a_mixer(ad1816a_t *chip) { snd_card_t *card; - int err, idx; + unsigned int idx; + int err; snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); diff -Nru a/sound/isa/ad1848/Makefile b/sound/isa/ad1848/Makefile --- a/sound/isa/ad1848/Makefile Sun Feb 9 21:13:30 2003 +++ b/sound/isa/ad1848/Makefile Sun Feb 9 21:13:30 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := ad1848_lib.o - snd-ad1848-lib-objs := ad1848_lib.o snd-ad1848-objs := ad1848.o diff -Nru a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c --- a/sound/isa/ad1848/ad1848_lib.c Sun Feb 9 21:13:36 2003 +++ b/sound/isa/ad1848/ad1848_lib.c Sun Feb 9 21:13:36 2003 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -604,7 +605,7 @@ if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_PLAYBACK_ENABLE)) return 0; - ptr = chip->dma_size - snd_dma_residue(chip->dma); + ptr = snd_dma_pointer(chip->dma, chip->dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -615,7 +616,7 @@ if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_CAPTURE_ENABLE)) return 0; - ptr = chip->dma_size - snd_dma_residue(chip->dma); + ptr = snd_dma_pointer(chip->dma, chip->dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -936,6 +937,12 @@ return 0; } +const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction) +{ + return direction == SNDRV_PCM_STREAM_PLAYBACK ? + &snd_ad1848_playback_ops : &snd_ad1848_capture_ops; +} + /* * MIXER part */ @@ -990,7 +997,7 @@ return change; } -int snd_ad1848_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) +static int snd_ad1848_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { int mask = (kcontrol->private_value >> 16) & 0xff; @@ -1001,7 +1008,7 @@ return 0; } -int snd_ad1848_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_ad1848_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { ad1848_t *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; @@ -1018,7 +1025,7 @@ return 0; } -int snd_ad1848_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_ad1848_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { ad1848_t *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; @@ -1041,7 +1048,7 @@ return change; } -int snd_ad1848_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) +static int snd_ad1848_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { int mask = (kcontrol->private_value >> 24) & 0xff; @@ -1052,7 +1059,7 @@ return 0; } -int snd_ad1848_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_ad1848_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { ad1848_t *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; @@ -1074,7 +1081,7 @@ return 0; } -int snd_ad1848_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +static int snd_ad1848_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { ad1848_t *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; @@ -1111,9 +1118,47 @@ return change; } -#define AD1848_CONTROLS (sizeof(snd_ad1848_controls)/sizeof(snd_kcontrol_new_t)) +/* + */ +int snd_ad1848_add_ctl(ad1848_t *chip, const char *name, int index, int type, unsigned long value) +{ + static snd_kcontrol_new_t newctls[] = { + [AD1848_MIX_SINGLE] = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_ad1848_info_single, + .get = snd_ad1848_get_single, + .put = snd_ad1848_put_single, + }, + [AD1848_MIX_DOUBLE] = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_ad1848_info_double, + .get = snd_ad1848_get_double, + .put = snd_ad1848_put_double, + }, + [AD1848_MIX_CAPTURE] = { + .info = snd_ad1848_info_mux, + .get = snd_ad1848_get_mux, + .put = snd_ad1848_put_mux, + }, + }; + snd_kcontrol_t *ctl; + int err; + + ctl = snd_ctl_new1(&newctls[type], chip); + if (! ctl) + return -ENOMEM; + strncpy(ctl->id.name, name, sizeof(ctl->id.name)-1); + ctl->id.index = index; + ctl->private_value = value; + if ((err = snd_ctl_add(chip->card, ctl)) < 0) { + snd_ctl_free_one(ctl); + return err; + } + return 0; +} + -static snd_kcontrol_new_t snd_ad1848_controls[] = { +static struct ad1848_mix_elem snd_ad1848_controls[] = { AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), AD1848_DOUBLE("PCM Playback Volume", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 0, 0, 63, 1), AD1848_DOUBLE("Aux Playback Switch", 0, AD1848_AUX1_LEFT_INPUT, AD1848_AUX1_RIGHT_INPUT, 7, 7, 1, 1), @@ -1122,11 +1167,8 @@ AD1848_DOUBLE("Aux Playback Volume", 1, AD1848_AUX2_LEFT_INPUT, AD1848_AUX2_RIGHT_INPUT, 0, 0, 31, 1), AD1848_DOUBLE("Capture Volume", 0, AD1848_LEFT_INPUT, AD1848_RIGHT_INPUT, 0, 0, 15, 0), { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", - .info = snd_ad1848_info_mux, - .get = snd_ad1848_get_mux, - .put = snd_ad1848_put_mux, + .type = AD1848_MIX_CAPTURE, }, AD1848_SINGLE("Loopback Capture Switch", 0, AD1848_LOOPBACK, 0, 1, 0), AD1848_SINGLE("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0) @@ -1136,7 +1178,8 @@ { snd_card_t *card; snd_pcm_t *pcm; - int err, idx; + unsigned int idx; + int err; snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); @@ -1145,10 +1188,10 @@ strcpy(card->mixername, pcm->name); - for (idx = 0; idx < AD1848_CONTROLS; idx++) { - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ad1848_controls[idx], chip))) < 0) + for (idx = 0; idx < ARRAY_SIZE(snd_ad1848_controls); idx++) + if ((err = snd_ad1848_add_ctl_elem(chip, &snd_ad1848_controls[idx])) < 0) return err; - } + return 0; } @@ -1160,13 +1203,9 @@ EXPORT_SYMBOL(snd_ad1848_interrupt); EXPORT_SYMBOL(snd_ad1848_create); EXPORT_SYMBOL(snd_ad1848_pcm); +EXPORT_SYMBOL(snd_ad1848_get_pcm_ops); EXPORT_SYMBOL(snd_ad1848_mixer); -EXPORT_SYMBOL(snd_ad1848_info_single); -EXPORT_SYMBOL(snd_ad1848_get_single); -EXPORT_SYMBOL(snd_ad1848_put_single); -EXPORT_SYMBOL(snd_ad1848_info_double); -EXPORT_SYMBOL(snd_ad1848_get_double); -EXPORT_SYMBOL(snd_ad1848_put_double); +EXPORT_SYMBOL(snd_ad1848_add_ctl); /* * INIT part diff -Nru a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c --- a/sound/isa/cmi8330.c Sun Feb 9 21:13:29 2003 +++ b/sound/isa/cmi8330.c Sun Feb 9 21:13:29 2003 @@ -57,6 +57,13 @@ #define SNDRV_GET_ID #include +/* + */ +/* #define ENABLE_SB_MIXER */ +#define PLAYBACK_ON_SB + +/* + */ MODULE_AUTHOR("George Talusan "); MODULE_DESCRIPTION("C-Media CMI8330"); MODULE_LICENSE("GPL"); @@ -129,8 +136,12 @@ static unsigned char snd_cmi8330_image[((CMI8330_CDINGAIN)-16) + 1] = { - 0x0, /* 16 - recording mux */ - 0x40, /* 17 - mute mux */ + 0x40, /* 16 - recording mux (SB-mixer-enabled) */ +#ifdef ENABLE_SB_MIXER + 0x40, /* 17 - mute mux (Mode2) */ +#else + 0x0, /* 17 - mute mux */ +#endif 0x0, /* 18 - vol */ 0x0, /* 19 - master volume */ 0x0, /* 20 - line-in volume */ @@ -142,11 +153,23 @@ 0x0 /* 26 - cd-in rec gain */ }; +typedef int (*snd_pcm_open_callback_t)(snd_pcm_substream_t *); + struct snd_cmi8330 { #ifdef __ISAPNP__ struct isapnp_dev *cap; struct isapnp_dev *play; #endif + snd_card_t *card; + ad1848_t *wss; + sb_t *sb; + + snd_pcm_t *pcm; + struct snd_cmi8330_stream { + snd_pcm_ops_t ops; + snd_pcm_open_callback_t open; + void *private_data; /* sb or wss */ + } streams[2]; }; static snd_card_t *snd_cmi8330_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; @@ -173,9 +196,8 @@ #endif -#define CMI8330_CONTROLS (sizeof(snd_cmi8330_controls)/sizeof(snd_kcontrol_new_t)) -static snd_kcontrol_new_t snd_cmi8330_controls[] __devinitdata = { +static struct ad1848_mix_elem snd_cmi8330_controls[] __initdata = { AD1848_DOUBLE("Master Playback Volume", 0, CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0), AD1848_SINGLE("Loud Playback Switch", 0, CMI8330_MUTEMUX, 6, 1, 1), AD1848_DOUBLE("PCM Playback Switch", 0, AD1848_LEFT_OUTPUT, AD1848_RIGHT_OUTPUT, 7, 7, 1, 1), @@ -187,7 +209,7 @@ AD1848_DOUBLE("CD Playback Switch", 0, CMI8330_MUTEMUX, CMI8330_MUTEMUX, 2, 1, 1, 0), AD1848_DOUBLE("CD Capture Switch", 0, CMI8330_RMUX3D, CMI8330_RMUX3D, 4, 3, 1, 0), AD1848_DOUBLE("CD Playback Volume", 0, CMI8330_CDINVOL, CMI8330_CDINVOL, 4, 0, 15, 0), -AD1848_DOUBLE("CD Capture Switch", 0, CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0), +AD1848_DOUBLE("CD Capture Volume", 0, CMI8330_CDINGAIN, CMI8330_CDINGAIN, 4, 0, 15, 0), AD1848_SINGLE("Mic Playback Switch", 0, CMI8330_MUTEMUX, 0, 1, 0), AD1848_SINGLE("Mic Playback Volume", 0, CMI8330_OUTPUTVOL, 0, 7, 0), AD1848_SINGLE("Mic Capture Switch", 0, CMI8330_RMUX3D, 0, 1, 0), @@ -203,16 +225,80 @@ AD1848_SINGLE("IEC958 Input Playback Switch", 0, CMI8330_MUTEMUX, 7, 1, 1), }; -static int __init snd_cmi8330_mixer(snd_card_t *card, ad1848_t *chip) +#ifdef ENABLE_SB_MIXER +static struct sbmix_elem cmi8330_sb_mixers[] __initdata = { +SB_DOUBLE("SB Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31), +SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15), +SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15), +SB_DOUBLE("SB PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31), +SB_DOUBLE("SB Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31), +SB_DOUBLE("SB CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1), +SB_DOUBLE("SB CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31), +SB_DOUBLE("SB Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1), +SB_DOUBLE("SB Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31), +SB_SINGLE("SB Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1), +SB_SINGLE("SB Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31), +SB_SINGLE("SB PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3), +SB_DOUBLE("SB Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3), +SB_DOUBLE("SB Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3), +SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1), +}; + +static unsigned char cmi8330_sb_init_values[][2] __initdata = { + { SB_DSP4_MASTER_DEV + 0, 0 }, + { SB_DSP4_MASTER_DEV + 1, 0 }, + { SB_DSP4_PCM_DEV + 0, 0 }, + { SB_DSP4_PCM_DEV + 1, 0 }, + { SB_DSP4_SYNTH_DEV + 0, 0 }, + { SB_DSP4_SYNTH_DEV + 1, 0 }, + { SB_DSP4_INPUT_LEFT, 0 }, + { SB_DSP4_INPUT_RIGHT, 0 }, + { SB_DSP4_OUTPUT_SW, 0 }, + { SB_DSP4_SPEAKER_DEV, 0 }, +}; + + +static int __init cmi8330_add_sb_mixers(sb_t *chip) { int idx, err; + unsigned long flags; + + spin_lock_irqsave(&chip->mixer_lock, flags); + snd_sbmixer_write(chip, 0x00, 0x00); /* mixer reset */ + spin_unlock_irqrestore(&chip->mixer_lock, flags); + + /* mute and zero volume channels */ + for (idx = 0; idx < ARRAY_SIZE(cmi8330_sb_init_values); idx++) { + spin_lock_irqsave(&chip->mixer_lock, flags); + snd_sbmixer_write(chip, cmi8330_sb_init_values[idx][0], + cmi8330_sb_init_values[idx][1]); + spin_unlock_irqrestore(&chip->mixer_lock, flags); + } + + for (idx = 0; idx < ARRAY_SIZE(cmi8330_sb_mixers); idx++) { + if ((err = snd_sbmixer_add_ctl_elem(chip, &cmi8330_sb_mixers[idx])) < 0) + return err; + } + return 0; +} +#endif + +static int __init snd_cmi8330_mixer(snd_card_t *card, struct snd_cmi8330 *acard) +{ + unsigned int idx; + int err; strcpy(card->mixername, "CMI8330/C3D"); - for (idx = 0; idx < CMI8330_CONTROLS; idx++) - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cmi8330_controls[idx], chip))) < 0) + for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) { + if ((err = snd_ad1848_add_ctl_elem(acard->wss, &snd_cmi8330_controls[idx])) < 0) return err; + } +#ifdef ENABLE_SB_MIXER + if ((err = cmi8330_add_sb_mixers(acard->sb)) < 0) + return err; +#endif return 0; } @@ -294,6 +380,93 @@ } #endif +/* + * PCM interface + * + * since we call the different chip interfaces for playback and capture + * directions, we need a trick. + * + * - copy the ops for each direction into a local record. + * - replace the open callback with the new one, which replaces the + * substream->private_data with the corresponding chip instance + * and calls again the original open callback of the chip. + * + */ + +#ifdef PLAYBACK_ON_SB +#define CMI_SB_STREAM SNDRV_PCM_STREAM_PLAYBACK +#define CMI_AD_STREAM SNDRV_PCM_STREAM_CAPTURE +#else +#define CMI_SB_STREAM SNDRV_PCM_STREAM_CAPTURE +#define CMI_AD_STREAM SNDRV_PCM_STREAM_PLAYBACK +#endif + +static int snd_cmi8330_playback_open(snd_pcm_substream_t * substream) +{ + struct snd_cmi8330 *chip = (struct snd_cmi8330 *)_snd_pcm_substream_chip(substream); + + /* replace the private_data and call the original open callback */ + substream->private_data = chip->streams[SNDRV_PCM_STREAM_PLAYBACK].private_data; + return chip->streams[SNDRV_PCM_STREAM_PLAYBACK].open(substream); +} + +static int snd_cmi8330_capture_open(snd_pcm_substream_t * substream) +{ + struct snd_cmi8330 *chip = (struct snd_cmi8330 *)_snd_pcm_substream_chip(substream); + + /* replace the private_data and call the original open callback */ + substream->private_data = chip->streams[SNDRV_PCM_STREAM_CAPTURE].private_data; + return chip->streams[SNDRV_PCM_STREAM_CAPTURE].open(substream); +} + +static void snd_cmi8330_pcm_free(snd_pcm_t *pcm) +{ + snd_pcm_lib_preallocate_free_for_all(pcm); +} + +static int __init snd_cmi8330_pcm(snd_card_t *card, struct snd_cmi8330 *chip) +{ + snd_pcm_t *pcm; + const snd_pcm_ops_t *ops; + int err; + static snd_pcm_open_callback_t cmi_open_callbacks[2] = { + snd_cmi8330_playback_open, + snd_cmi8330_capture_open + }; + + if ((err = snd_pcm_new(card, "CMI8330", 0, 1, 1, &pcm)) < 0) + return err; + strcpy(pcm->name, "CMI8330"); + pcm->private_data = chip; + pcm->private_free = snd_cmi8330_pcm_free; + + /* SB16 */ + ops = snd_sb16dsp_get_pcm_ops(CMI_SB_STREAM); + chip->streams[CMI_SB_STREAM].ops = *ops; + chip->streams[CMI_SB_STREAM].open = ops->open; + chip->streams[CMI_SB_STREAM].ops.open = cmi_open_callbacks[CMI_SB_STREAM]; + chip->streams[CMI_SB_STREAM].private_data = chip->sb; + + /* AD1848 */ + ops = snd_ad1848_get_pcm_ops(CMI_AD_STREAM); + chip->streams[CMI_AD_STREAM].ops = *ops; + chip->streams[CMI_AD_STREAM].open = ops->open; + chip->streams[CMI_AD_STREAM].ops.open = cmi_open_callbacks[CMI_AD_STREAM]; + chip->streams[CMI_AD_STREAM].private_data = chip->wss; + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &chip->streams[SNDRV_PCM_STREAM_PLAYBACK].ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &chip->streams[SNDRV_PCM_STREAM_CAPTURE].ops); + + snd_pcm_lib_preallocate_isa_pages_for_all(pcm, 64*1024, 128*1024); + chip->pcm = pcm; + + return 0; +} + + +/* + */ + static void snd_cmi8330_free(snd_card_t *card) { struct snd_cmi8330 *acard = (struct snd_cmi8330 *)card->private_data; @@ -309,12 +482,8 @@ { snd_card_t *card; struct snd_cmi8330 *acard; - ad1848_t *chip_wss; - sb_t *chip_sb; unsigned long flags; int i, err; - snd_pcm_t *pcm, *wss_pcm, *sb_pcm; - snd_pcm_str_t *pstr; #ifdef __ISAPNP__ if (!isapnp[dev]) { @@ -337,6 +506,7 @@ return -ENOMEM; } acard = (struct snd_cmi8330 *)card->private_data; + acard->card = card; card->private_free = snd_cmi8330_free; #ifdef __ISAPNP__ @@ -352,83 +522,56 @@ wssirq[dev], wssdma[dev], AD1848_HW_DETECT, - &chip_wss)) < 0) { + &acard->wss)) < 0) { snd_printk("(AD1848) device busy??\n"); snd_card_free(card); return err; } - if (chip_wss->hardware != AD1848_HW_CMI8330) { + if (acard->wss->hardware != AD1848_HW_CMI8330) { snd_printk("(AD1848) not found during probe\n"); snd_card_free(card); return -ENODEV; } - if ((err = snd_ad1848_pcm(chip_wss, 0, &wss_pcm)) < 0) { - snd_printk("(AD1848) no enough memory??\n"); - snd_card_free(card); - return err; - } if ((err = snd_sbdsp_create(card, sbport[dev], sbirq[dev], snd_sb16dsp_interrupt, sbdma8[dev], sbdma16[dev], - SB_HW_AUTO, &chip_sb)) < 0) { + SB_HW_AUTO, &acard->sb)) < 0) { snd_printk("(SB16) device busy??\n"); snd_card_free(card); return err; } - if ((err = snd_sb16dsp_pcm(chip_sb, 1, &sb_pcm)) < 0) { - snd_printk("(SB16) no enough memory??\n"); - snd_card_free(card); - return err; - } - - if (chip_sb->hardware != SB_HW_16) { + if (acard->sb->hardware != SB_HW_16) { snd_printk("(SB16) not found during probe\n"); snd_card_free(card); return -ENODEV; } - memcpy(&chip_wss->image[16], &snd_cmi8330_image, sizeof(snd_cmi8330_image)); - - spin_lock_irqsave(&chip_wss->reg_lock, flags); - snd_ad1848_out(chip_wss, AD1848_MISC_INFO, /* switch on MODE2 */ - chip_wss->image[AD1848_MISC_INFO] |= 0x40); - spin_unlock_irqrestore(&chip_wss->reg_lock, flags); + spin_lock_irqsave(&acard->wss->reg_lock, flags); + snd_ad1848_out(acard->wss, AD1848_MISC_INFO, 0x40); /* switch on MODE2 */ + for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++) + snd_ad1848_out(acard->wss, i, snd_cmi8330_image[i - CMI8330_RMUX3D]); + spin_unlock_irqrestore(&acard->wss->reg_lock, flags); - if ((err = snd_cmi8330_mixer(card, chip_wss)) < 0) { + if ((err = snd_cmi8330_mixer(card, acard)) < 0) { snd_printk("failed to create mixers\n"); snd_card_free(card); return err; } - spin_lock_irqsave(&chip_wss->reg_lock, flags); - for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++) - snd_ad1848_out(chip_wss, i, chip_wss->image[i]); - spin_unlock_irqrestore(&chip_wss->reg_lock, flags); - /* - * KLUDGE ALERT - * disable AD1848 playback - * disable SB16 capture - */ - pcm = wss_pcm; - pstr = &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]; - snd_magic_kfree(pstr->substream); - pstr->substream = 0; - pstr->substream_count = 0; - - pcm = sb_pcm; - pstr = &pcm->streams[SNDRV_PCM_STREAM_CAPTURE]; - snd_magic_kfree(pstr->substream); - pstr->substream = 0; - pstr->substream_count = 0; + if ((err = snd_cmi8330_pcm(card, acard)) < 0) { + snd_printk("failed to create pcms\n"); + snd_card_free(card); + return err; + } strcpy(card->driver, "CMI8330/C3D"); strcpy(card->shortname, "C-Media CMI8330/C3D"); sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", - wss_pcm->name, - chip_wss->port, + card->shortname, + acard->wss->port, wssirq[dev], wssdma[dev]); diff -Nru a/sound/isa/cs423x/Makefile b/sound/isa/cs423x/Makefile --- a/sound/isa/cs423x/Makefile Sun Feb 9 21:13:35 2003 +++ b/sound/isa/cs423x/Makefile Sun Feb 9 21:13:35 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := cs4231_lib.o cs4236_lib.o - snd-cs4231-lib-objs := cs4231_lib.o snd-cs4236-lib-objs := cs4236_lib.o snd-cs4231-objs := cs4231.o diff -Nru a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c --- a/sound/isa/cs423x/cs4231_lib.c Sun Feb 9 21:13:29 2003 +++ b/sound/isa/cs423x/cs4231_lib.c Sun Feb 9 21:13:29 2003 @@ -158,7 +158,7 @@ } else { #endif #ifdef SBUS_SUPPORT - return sbus_writeb(chip->port + (offset << 2)); + return sbus_readb(chip->port + (offset << 2)); #endif #ifdef EBUS_SUPPORT } @@ -338,13 +338,13 @@ unsigned long flags; int timeout; - spin_lock_irqsave(&chip->reg_lock, flags); for (timeout = 250; timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--) udelay(100); #ifdef CONFIG_SND_DEBUG if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) snd_printk("mce_up - auto calibration time out (0)\n"); #endif + spin_lock_irqsave(&chip->reg_lock, flags); chip->mce_bit |= CS4231_MCE; timeout = cs4231_inb(chip, CS4231P(REGSEL)); if (timeout == 0x80) @@ -360,7 +360,6 @@ int timeout; signed long time; - spin_lock_irqsave(&chip->reg_lock, flags); snd_cs4231_busy_wait(chip); #if 0 printk("(1) timeout = %i\n", timeout); @@ -369,14 +368,15 @@ if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL)); #endif + spin_lock_irqsave(&chip->reg_lock, flags); chip->mce_bit &= ~CS4231_MCE; timeout = cs4231_inb(chip, CS4231P(REGSEL)); cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); + spin_unlock_irqrestore(&chip->reg_lock, flags); if (timeout == 0x80) snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); if ((timeout & CS4231_MCE) == 0 || !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) { - spin_unlock_irqrestore(&chip->reg_lock, flags); return; } snd_cs4231_busy_wait(chip); @@ -387,7 +387,6 @@ udelay(10); if ((snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) == 0) { snd_printd("cs4231_mce_down - auto calibration time out (1)\n"); - spin_unlock_irqrestore(&chip->reg_lock, flags); return; } #if 0 @@ -395,30 +394,25 @@ #endif time = HZ / 4; while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) { - spin_unlock_irqrestore(&chip->reg_lock, flags); if (time <= 0) { snd_printk("mce_down - auto calibration time out (2)\n"); return; } set_current_state(TASK_INTERRUPTIBLE); time = schedule_timeout(time); - spin_lock_irqsave(&chip->reg_lock, flags); } #if 0 printk("(3) jiffies = %li\n", jiffies); #endif time = HZ / 10; while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) { - spin_unlock_irqrestore(&chip->reg_lock, flags); if (time <= 0) { - snd_printk("mce_down - auto calibration time out (3)\n"); + snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); return; } set_current_state(TASK_INTERRUPTIBLE); time = schedule_timeout(time); - spin_lock_irqsave(&chip->reg_lock, flags); } - spin_unlock_irqrestore(&chip->reg_lock, flags); #if 0 printk("(4) jiffies = %li\n", jiffies); snd_printk("mce_down - exit = 0x%x\n", cs4231_inb(chip, CS4231P(REGSEL))); @@ -1005,7 +999,7 @@ if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) return 0; - ptr = chip->p_dma_size - snd_dma_residue(chip->dma1); + ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -1016,7 +1010,7 @@ if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)) return 0; - ptr = chip->c_dma_size - snd_dma_residue(chip->dma2); + ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size); return bytes_to_frames(substream->runtime, ptr); } #endif /* LEGACY_SUPPORT */ @@ -1375,20 +1369,19 @@ This is the first half of copy of snd_cs4231_mce_down(), but doesn't include rescheduling. -- iwai */ - spin_lock_irqsave(&chip->reg_lock, flags); snd_cs4231_busy_wait(chip); + spin_lock_irqsave(&chip->reg_lock, flags); chip->mce_bit &= ~CS4231_MCE; timeout = cs4231_inb(chip, CS4231P(REGSEL)); cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); + spin_unlock_irqrestore(&chip->reg_lock, flags); if (timeout == 0x80) snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port); if ((timeout & CS4231_MCE) == 0 || !(chip->hardware & (CS4231_HW_CS4231_MASK | CS4231_HW_CS4232_MASK))) { - spin_unlock_irqrestore(&chip->reg_lock, flags); return; } snd_cs4231_busy_wait(chip); - spin_unlock_irqrestore(&chip->reg_lock, flags); #endif } @@ -1910,7 +1903,8 @@ int snd_cs4231_mixer(cs4231_t *chip) { snd_card_t *card; - int err, idx; + unsigned int idx; + int err; snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL); diff -Nru a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c --- a/sound/isa/cs423x/cs4236.c Sun Feb 9 21:13:29 2003 +++ b/sound/isa/cs423x/cs4236.c Sun Feb 9 21:13:29 2003 @@ -328,7 +328,7 @@ sb_port[dev] = pdev->resource[2].start; irq[dev] = pdev->irq_resource[0].start; dma1[dev] = pdev->dma_resource[0].start; - dma2[dev] = pdev->dma_resource[1].start == 4 ? -1 : pdev->dma_resource[1].start; + dma2[dev] = pdev->dma_resource[1].start == 4 ? -1 : (int)pdev->dma_resource[1].start; snd_printdd("isapnp WSS: wss port=0x%lx, fm port=0x%lx, sb port=0x%lx\n", port[dev], fm_port[dev], sb_port[dev]); snd_printdd("isapnp WSS: irq=%i, dma1=%i, dma2=%i\n", diff -Nru a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c --- a/sound/isa/cs423x/cs4236_lib.c Sun Feb 9 21:13:30 2003 +++ b/sound/isa/cs423x/cs4236_lib.c Sun Feb 9 21:13:30 2003 @@ -270,7 +270,8 @@ { cs4231_t *chip; unsigned char ver1, ver2; - int err, reg; + unsigned int reg; + int err; *rchip = NULL; if (hardware == CS4231_HW_DETECT) @@ -908,7 +909,8 @@ int snd_cs4236_mixer(cs4231_t *chip) { snd_card_t *card; - int err, idx, count; + unsigned int idx, count; + int err; snd_kcontrol_new_t *kcontrol; snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); @@ -942,7 +944,7 @@ kcontrol = snd_cs4236_3d_controls_cs4238; break; default: - count = -1; + count = 0; kcontrol = NULL; } for (idx = 0; idx < count; idx++, kcontrol++) { diff -Nru a/sound/isa/es1688/Makefile b/sound/isa/es1688/Makefile --- a/sound/isa/es1688/Makefile Sun Feb 9 21:13:34 2003 +++ b/sound/isa/es1688/Makefile Sun Feb 9 21:13:34 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := es1688_lib.o - snd-es1688-lib-objs := es1688_lib.o snd-es1688-objs := es1688.o diff -Nru a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c --- a/sound/isa/es1688/es1688_lib.c Sun Feb 9 21:13:33 2003 +++ b/sound/isa/es1688/es1688_lib.c Sun Feb 9 21:13:33 2003 @@ -346,7 +346,7 @@ } #if 0 printk("trigger: val = 0x%x, value = 0x%x\n", val, value); - printk("trigger: residue = 0x%x\n", get_dma_residue(chip->dma8)); + printk("trigger: pointer = 0x%x\n", snd_dma_pointer(chip->dma8, chip->dma_size)); #endif snd_es1688_write(chip, 0xb8, (val & 0xf0) | value); spin_unlock(&chip->reg_lock); @@ -501,7 +501,7 @@ if (chip->trigger_value != 0x05) return 0; - ptr = chip->dma_size - snd_dma_residue(chip->dma8); + ptr = snd_dma_pointer(chip->dma8, chip->dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -512,7 +512,7 @@ if (chip->trigger_value != 0x0f) return 0; - ptr = chip->dma_size - snd_dma_residue(chip->dma8); + ptr = snd_dma_pointer(chip->dma8, chip->dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -1014,7 +1014,8 @@ int snd_es1688_mixer(es1688_t *chip) { snd_card_t *card; - int err, idx; + unsigned int idx; + int err; unsigned char reg, val; snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); diff -Nru a/sound/isa/es18xx.c b/sound/isa/es18xx.c --- a/sound/isa/es18xx.c Sun Feb 9 21:13:31 2003 +++ b/sound/isa/es18xx.c Sun Feb 9 21:13:31 2003 @@ -460,6 +460,11 @@ return 0; } +static int snd_es18xx_pcm_hw_free(snd_pcm_substream_t * substream) +{ + return snd_pcm_lib_free_pages(substream); +} + static int snd_es18xx_playback1_prepare(es18xx_t *chip, snd_pcm_substream_t *substream) { @@ -796,12 +801,12 @@ if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { if (!(chip->active & DAC2)) return 0; - pos = chip->dma2_size - snd_dma_residue(chip->dma2); + pos = snd_dma_pointer(chip->dma2, chip->dma2_size); return pos >> chip->dma2_shift; } else { if (!(chip->active & DAC1)) return 0; - pos = chip->dma1_size - snd_dma_residue(chip->dma1); + pos = snd_dma_pointer(chip->dma1, chip->dma1_size); return pos >> chip->dma1_shift; } } @@ -813,7 +818,7 @@ if (!(chip->active & ADC1)) return 0; - pos = chip->dma1_size - snd_dma_residue(chip->dma1); + pos = snd_dma_pointer(chip->dma1, chip->dma1_size); return pos >> chip->dma1_shift; } @@ -1540,6 +1545,7 @@ .close = snd_es18xx_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_es18xx_playback_hw_params, + .hw_free = snd_es18xx_pcm_hw_free, .prepare = snd_es18xx_playback_prepare, .trigger = snd_es18xx_playback_trigger, .pointer = snd_es18xx_playback_pointer, @@ -1550,6 +1556,7 @@ .close = snd_es18xx_capture_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_es18xx_capture_hw_params, + .hw_free = snd_es18xx_pcm_hw_free, .prepare = snd_es18xx_capture_prepare, .trigger = snd_es18xx_capture_trigger, .pointer = snd_es18xx_capture_pointer, @@ -1606,9 +1613,8 @@ { snd_card_t *card = chip->card; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D3hot) - goto __skip; + return; snd_pcm_suspend_all(chip->pcm); @@ -1619,24 +1625,19 @@ snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_SUS); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - __skip: - snd_power_unlock(card); } static void snd_es18xx_resume(es18xx_t *chip) { snd_card_t *card = chip->card; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D0) - goto __skip; + return; /* restore PM register, we won't wake till (not 0x07) i/o activity though */ snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM); snd_power_change_state(card, SNDRV_CTL_POWER_D0); - __skip: - snd_power_unlock(card); } /* callback for control API */ @@ -1785,14 +1786,14 @@ static int __init snd_es18xx_mixer(es18xx_t *chip) { snd_card_t *card; - int err, idx; + int err; + unsigned int idx; card = chip->card; strcpy(card->mixername, chip->pcm->name); - for (idx = 0; idx < sizeof(snd_es18xx_base_controls) / - sizeof(snd_es18xx_base_controls[0]); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_base_controls); idx++) { snd_kcontrol_t *kctl; kctl = snd_ctl_new1(&snd_es18xx_base_controls[idx], chip); if (chip->caps & ES18XX_HWV) { @@ -1811,14 +1812,12 @@ return err; } if (chip->caps & ES18XX_PCM2) { - for (idx = 0; idx < sizeof(snd_es18xx_pcm2_controls) / - sizeof(snd_es18xx_pcm2_controls[0]); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_pcm2_controls); idx++) { if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm2_controls[idx], chip))) < 0) return err; } } else { - for (idx = 0; idx < sizeof(snd_es18xx_pcm1_controls) / - sizeof(snd_es18xx_pcm1_controls[0]); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_pcm1_controls); idx++) { if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_pcm1_controls[idx], chip))) < 0) return err; } @@ -1829,8 +1828,7 @@ return err; } if (chip->caps & ES18XX_RECMIX) { - for (idx = 0; idx < sizeof(snd_es18xx_recmix_controls) / - sizeof(snd_es18xx_recmix_controls[0]); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_recmix_controls); idx++) { if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip))) < 0) return err; } @@ -1847,15 +1845,13 @@ break; } if (chip->caps & ES18XX_SPATIALIZER) { - for (idx = 0; idx < sizeof(snd_es18xx_spatializer_controls) / - sizeof(snd_es18xx_spatializer_controls[0]); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_spatializer_controls); idx++) { if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_spatializer_controls[idx], chip))) < 0) return err; } } if (chip->caps & ES18XX_HWV) { - for (idx = 0; idx < sizeof(snd_es18xx_hw_volume_controls) / - sizeof(snd_es18xx_hw_volume_controls[0]); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_hw_volume_controls); idx++) { snd_kcontrol_t *kctl; kctl = snd_ctl_new1(&snd_es18xx_hw_volume_controls[idx], chip); if (idx == 0) diff -Nru a/sound/isa/gus/Makefile b/sound/isa/gus/Makefile --- a/sound/isa/gus/Makefile Sun Feb 9 21:13:37 2003 +++ b/sound/isa/gus/Makefile Sun Feb 9 21:13:37 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := gus_main.o gus_volume.o - snd-gus-lib-objs := gus_main.o \ gus_io.o gus_irq.o gus_timer.o \ gus_mem.o gus_mem_proc.o gus_dram.o gus_dma.o gus_volume.o \ @@ -19,18 +17,24 @@ snd-interwave-objs := interwave.o snd-interwave-stb-objs := interwave-stb.o +# +# this function returns: +# "m" - CONFIG_SND_SEQUENCER is m +# - CONFIG_SND_SEQUENCER is undefined +# otherwise parameter #1 value +# +sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) + # Toplevel Module Dependency obj-$(CONFIG_SND_GUSCLASSIC) += snd-gusclassic.o snd-gus-lib.o +obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += snd-gus-synth.o obj-$(CONFIG_SND_GUSMAX) += snd-gusmax.o snd-gus-lib.o +obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += snd-gus-synth.o obj-$(CONFIG_SND_GUSEXTREME) += snd-gusextreme.o snd-gus-lib.o +obj-$(call sequencer,$(CONFIG_SND_GUSEXTREME)) += snd-gus-synth.o obj-$(CONFIG_SND_INTERWAVE) += snd-interwave.o snd-gus-lib.o +obj-$(call sequencer,$(CONFIG_SND_INTERWAVE)) += snd-gus-synth.o obj-$(CONFIG_SND_INTERWAVE_STB) += snd-interwave-stb.o snd-gus-lib.o -ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y) - obj-$(CONFIG_SND_GUSCLASSIC) += snd-gus-synth.o - obj-$(CONFIG_SND_GUSMAX) += snd-gus-synth.o - obj-$(CONFIG_SND_GUSEXTREME) += snd-gus-synth.o - obj-$(CONFIG_SND_INTERWAVE) += snd-gus-synth.o - obj-$(CONFIG_SND_INTERWAVE_STB) += snd-gus-synth.o -endif +obj-$(call sequencer,$(CONFIG_SND_INTERWAVE_STB)) += snd-gus-synth.o obj-m := $(sort $(obj-m)) diff -Nru a/sound/isa/gus/gus_irq.c b/sound/isa/gus/gus_irq.c --- a/sound/isa/gus/gus_irq.c Sun Feb 9 21:13:36 2003 +++ b/sound/isa/gus/gus_irq.c Sun Feb 9 21:13:36 2003 @@ -132,26 +132,8 @@ { snd_info_entry_t *entry; - gus->irq_entry = NULL; - entry = snd_info_create_card_entry(gus->card, "gusirq", gus->card->proc_root); - if (entry) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->c.text.read_size = 512; - entry->c.text.read = snd_gus_irq_info_read; - entry->private_data = gus; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - gus->irq_entry = entry; + if (! snd_card_proc_new(gus->card, "gusirq", &entry)) + snd_info_set_text_ops(entry, gus, snd_gus_irq_info_read); } -void snd_gus_irq_profile_done(snd_gus_card_t *gus) -{ - if (gus->irq_entry) { - snd_info_unregister(gus->irq_entry); - gus->irq_entry = NULL; - } -} #endif diff -Nru a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c --- a/sound/isa/gus/gus_main.c Sun Feb 9 21:13:29 2003 +++ b/sound/isa/gus/gus_main.c Sun Feb 9 21:13:29 2003 @@ -41,18 +41,14 @@ int snd_gus_use_inc(snd_gus_card_t * gus) { - MOD_INC_USE_COUNT; - if (!try_module_get(gus->card->module)) { - MOD_DEC_USE_COUNT; + if (!try_module_get(gus->card->module)) return 0; - } return 1; } void snd_gus_use_dec(snd_gus_card_t * gus) { module_put(gus->card->module); - MOD_DEC_USE_COUNT; } static int snd_gus_joystick_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) diff -Nru a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c --- a/sound/isa/gus/gus_mem.c Sun Feb 9 21:13:31 2003 +++ b/sound/isa/gus/gus_mem.c Sun Feb 9 21:13:31 2003 @@ -169,7 +169,7 @@ if (ptr1 >= ptr2) continue; size1 = ptr2 - ptr1; - if (size <= size1) { + if ((int)size <= size1) { block->ptr = ptr1; block->size = size; return 0; @@ -196,7 +196,7 @@ if (share_id != NULL) { nblock = snd_gf1_mem_share(alloc, share_id); if (nblock != NULL) { - if (size != nblock->size) { + if (size != (int)nblock->size) { /* TODO: remove in the future */ snd_printk("snd_gf1_mem_alloc - share: sizes differ\n"); goto __std; @@ -264,19 +264,10 @@ if (snd_gf1_mem_xalloc(alloc, &block) == NULL) return -ENOMEM; #ifdef CONFIG_SND_DEBUG - alloc->info_entry = NULL; - entry = snd_info_create_card_entry(gus->card, "gusmem", gus->card->proc_root); - if (entry) { - entry->content = SNDRV_INFO_CONTENT_TEXT; + if (! snd_card_proc_new(gus->card, "gusmem", &entry)) { + snd_info_set_text_ops(entry, gus, snd_gf1_mem_info_read); entry->c.text.read_size = 256 * 1024; - entry->c.text.read = snd_gf1_mem_info_read; - entry->private_data = gus; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } } - alloc->info_entry = entry; #endif return 0; } @@ -293,10 +284,6 @@ snd_gf1_mem_xfree(alloc, block); block = nblock; } -#ifdef CONFIG_SND_DEBUG - if (alloc->info_entry) - snd_info_unregister(alloc->info_entry); -#endif return 0; } diff -Nru a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c --- a/sound/isa/gus/gus_mem_proc.c Sun Feb 9 21:13:33 2003 +++ b/sound/isa/gus/gus_mem_proc.c Sun Feb 9 21:13:33 2003 @@ -96,73 +96,40 @@ gus_proc_private_t *priv; snd_info_entry_t *entry; - memset(&gus->gf1.rom_entries, 0, sizeof(gus->gf1.rom_entries)); - memset(&gus->gf1.ram_entries, 0, sizeof(gus->gf1.ram_entries)); for (idx = 0; idx < 4; idx++) { if (gus->gf1.mem_alloc.banks_8[idx].size > 0) { priv = snd_magic_kcalloc(gus_proc_private_t, 0, GFP_KERNEL); - if (priv == NULL) { - snd_gf1_mem_proc_done(gus); + if (priv == NULL) return -ENOMEM; - } priv->gus = gus; sprintf(name, "gus-ram-%i", idx); - entry = snd_info_create_card_entry(gus->card, name, gus->card->proc_root); - if (entry) { + if (! snd_card_proc_new(gus->card, name, &entry)) { entry->content = SNDRV_INFO_CONTENT_DATA; entry->private_data = priv; entry->private_free = snd_gf1_mem_proc_free; entry->c.ops = &snd_gf1_mem_proc_ops; priv->address = gus->gf1.mem_alloc.banks_8[idx].address; priv->size = entry->size = gus->gf1.mem_alloc.banks_8[idx].size; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } } - gus->gf1.ram_entries[idx] = entry; } } for (idx = 0; idx < 4; idx++) { if (gus->gf1.rom_present & (1 << idx)) { priv = snd_magic_kcalloc(gus_proc_private_t, 0, GFP_KERNEL); - if (priv == NULL) { - snd_gf1_mem_proc_done(gus); + if (priv == NULL) return -ENOMEM; - } priv->rom = 1; priv->gus = gus; sprintf(name, "gus-rom-%i", idx); - entry = snd_info_create_card_entry(gus->card, name, gus->card->proc_root); - if (entry) { + if (! snd_card_proc_new(gus->card, name, &entry)) { entry->content = SNDRV_INFO_CONTENT_DATA; entry->private_data = priv; entry->private_free = snd_gf1_mem_proc_free; entry->c.ops = &snd_gf1_mem_proc_ops; priv->address = idx * 4096 * 1024; priv->size = entry->size = gus->gf1.rom_memory; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } } - gus->gf1.rom_entries[idx] = entry; } - } - return 0; -} - -int snd_gf1_mem_proc_done(snd_gus_card_t * gus) -{ - int idx; - - for (idx = 0; idx < 4; idx++) { - if (gus->gf1.ram_entries[idx]) - snd_info_unregister(gus->gf1.ram_entries[idx]); - } - for (idx = 0; idx < 4; idx++) { - if (gus->gf1.rom_entries[idx]) - snd_info_unregister(gus->gf1.rom_entries[idx]); } return 0; } diff -Nru a/sound/isa/gus/gus_mixer.c b/sound/isa/gus/gus_mixer.c --- a/sound/isa/gus/gus_mixer.c Sun Feb 9 21:13:28 2003 +++ b/sound/isa/gus/gus_mixer.c Sun Feb 9 21:13:28 2003 @@ -172,7 +172,8 @@ int snd_gf1_new_mixer(snd_gus_card_t * gus) { snd_card_t *card; - int idx, err, max; + unsigned int idx, max; + int err; snd_assert(gus != NULL, return -EINVAL); card = gus->card; diff -Nru a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c --- a/sound/isa/gus/gus_pcm.c Sun Feb 9 21:13:31 2003 +++ b/sound/isa/gus/gus_pcm.c Sun Feb 9 21:13:31 2003 @@ -48,7 +48,7 @@ snd_gus_card_t * gus; snd_pcm_substream_t * substream; spinlock_t lock; - int voices; + unsigned int voices; snd_gus_voice_t *pvoices[2]; unsigned int memory; unsigned short flags; @@ -186,7 +186,7 @@ gus_pcm_private_t * pcmp; snd_pcm_runtime_t * runtime; unsigned char voice_ctrl, ramp_ctrl; - int idx; + unsigned int idx; unsigned int end, step; if (!pvoice->private_data) { @@ -600,7 +600,7 @@ static snd_pcm_uframes_t snd_gf1_pcm_capture_pointer(snd_pcm_substream_t * substream) { snd_gus_card_t *gus = snd_pcm_substream_chip(substream); - int pos = gus->c_period_size - snd_dma_residue(gus->gf1.dma2); + int pos = snd_dma_pointer(gus->gf1.dma2, gus->c_period_size); pos = bytes_to_frames(substream->runtime, (gus->c_pos + pos) % gus->c_dma_size); return pos; } @@ -766,7 +766,8 @@ { snd_gus_card_t *gus = snd_kcontrol_chip(kcontrol); unsigned long flags; - int change, idx; + int change; + unsigned int idx; unsigned short val1, val2, vol; gus_pcm_private_t *pcmp; snd_gus_voice_t *pvoice; diff -Nru a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c --- a/sound/isa/gus/gus_reset.c Sun Feb 9 21:13:29 2003 +++ b/sound/isa/gus/gus_reset.c Sun Feb 9 21:13:29 2003 @@ -410,10 +410,6 @@ snd_gf1_stop_voices(gus, 0, 31); /* stop all voices */ snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* disable IRQ & DAC */ snd_gf1_timers_done(gus); -#ifdef CONFIG_SND_DEBUG - snd_gus_irq_profile_done(gus); -#endif - snd_gf1_mem_proc_done(gus); snd_gf1_mem_done(gus); #if 0 snd_gf1_lfo_done(gus); diff -Nru a/sound/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c --- a/sound/isa/gus/gus_synth.c Sun Feb 9 21:13:32 2003 +++ b/sound/isa/gus/gus_synth.c Sun Feb 9 21:13:32 2003 @@ -51,7 +51,7 @@ snd_gus_port_t * port = (snd_gus_port_t *)private_data; snd_gus_card_t * gus = port->gus; snd_gus_voice_t * voice; - int idx; + unsigned int idx; if (info->voices > 32) return -EINVAL; @@ -133,7 +133,7 @@ snd_seq_kinstr_t *instr, int what) { - int idx; + unsigned int idx; snd_gus_card_t *gus = snd_magic_cast(snd_gus_card_t, private_data, return); snd_gus_voice_t *pvoice; unsigned long flags; @@ -197,6 +197,7 @@ SNDRV_SEQ_PORT_TYPE_MIDI_GS | SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE | SNDRV_SEQ_PORT_TYPE_SYNTH, + 16, name); if (p->chset->port < 0) { result = p->chset->port; diff -Nru a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c --- a/sound/isa/gus/interwave.c Sun Feb 9 21:13:32 2003 +++ b/sound/isa/gus/interwave.c Sun Feb 9 21:13:32 2003 @@ -544,7 +544,8 @@ { snd_card_t *card = chip->card; snd_ctl_elem_id_t id1, id2; - int idx, err; + unsigned int idx; + int err; memset(&id1, 0, sizeof(id1)); memset(&id2, 0, sizeof(id2)); diff -Nru a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c --- a/sound/isa/opti9xx/opti92x-ad1848.c Sun Feb 9 21:13:29 2003 +++ b/sound/isa/opti9xx/opti92x-ad1848.c Sun Feb 9 21:13:29 2003 @@ -842,7 +842,7 @@ static unsigned char snd_opti93x_get_freq(unsigned int rate) { - int i; + unsigned int i; for (i = 0; i < RATES; i++) { if (rate == rates[i]) @@ -1100,7 +1100,7 @@ if (!(chip->image[OPTi93X_IFACE_CONF] & OPTi93X_PLAYBACK_ENABLE)) return 0; - ptr = chip->p_dma_size - snd_dma_residue(chip->dma1); + ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -1112,7 +1112,7 @@ if (!(chip->image[OPTi93X_IFACE_CONF] & OPTi93X_CAPTURE_ENABLE)) return 0; - ptr = chip->c_dma_size - snd_dma_residue(chip->dma2); + ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -1635,7 +1635,8 @@ { snd_card_t *card; snd_kcontrol_new_t knew; - int err, idx; + int err; + unsigned int idx; snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); diff -Nru a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile --- a/sound/isa/sb/Makefile Sun Feb 9 21:13:31 2003 +++ b/sound/isa/sb/Makefile Sun Feb 9 21:13:31 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := emu8000.o sb_common.o sb8_main.o sb16_main.o sb16_csp.o - snd-sb-common-objs := sb_common.o sb_mixer.o snd-sb8-dsp-objs := sb8_main.o sb8_midi.o snd-sb16-dsp-objs := sb16_main.o @@ -15,6 +13,14 @@ snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o snd-es968-objs := es968.o +# +# this function returns: +# "m" - CONFIG_SND_SEQUENCER is m +# - CONFIG_SND_SEQUENCER is undefined +# otherwise parameter #1 value +# +sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) + # Toplevel Module Dependency obj-$(CONFIG_SND_ALS100) += snd-sb16-dsp.o snd-sb-common.o obj-$(CONFIG_SND_CMI8330) += snd-sb16-dsp.o snd-sb-common.o @@ -28,8 +34,6 @@ obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o endif -ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y) - obj-$(CONFIG_SND_SBAWE) += snd-emu8000-synth.o -endif +obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-emu8000-synth.o obj-m := $(sort $(obj-m)) diff -Nru a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c --- a/sound/isa/sb/emu8000.c Sun Feb 9 21:13:30 2003 +++ b/sound/isa/sb/emu8000.c Sun Feb 9 21:13:30 2003 @@ -662,7 +662,7 @@ snd_printk(KERN_WARNING "illegal chorus mode %d for uploading\n", mode); return -EINVAL; } - if (len < sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec))) + if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec))) return -EFAULT; chorus_parm[mode] = rec; chorus_defined[mode] = 1; @@ -790,7 +790,7 @@ snd_printk(KERN_WARNING "illegal reverb mode %d for uploading\n", mode); return -EINVAL; } - if (len < sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec))) + if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec))) return -EFAULT; reverb_parm[mode] = rec; reverb_defined[mode] = 1; diff -Nru a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c --- a/sound/isa/sb/emu8000_pcm.c Sun Feb 9 21:13:36 2003 +++ b/sound/isa/sb/emu8000_pcm.c Sun Feb 9 21:13:36 2003 @@ -215,7 +215,7 @@ add_timer(&rec->timer); /* update period */ - if (rec->period_pos >= rec->period_size) { + if (rec->period_pos >= (int)rec->period_size) { rec->period_pos %= rec->period_size; spin_unlock(&rec->timer_lock); snd_pcm_period_elapsed(rec->substream); diff -Nru a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c --- a/sound/isa/sb/sb16.c Sun Feb 9 21:13:35 2003 +++ b/sound/isa/sb/sb16.c Sun Feb 9 21:13:35 2003 @@ -204,6 +204,9 @@ ISAPNP_SB16('C','T','L',0x0070,0x0001), /* Sound Blaster Vibra16CL - added by ctm@ardi.com */ ISAPNP_SB16('C','T','L',0x0080,0x0041), + /* Sound Blaster 16 'value' PnP. It says model ct4130 on the pcb, */ + /* but ct4131 on a sticker on the board.. */ + ISAPNP_SB16('C','T','L',0x0086,0x0041), /* Sound Blaster Vibra16X */ ISAPNP_SB16('C','T','L',0x00f0,0x0043), #else /* SNDRV_SBAWE defined */ diff -Nru a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c --- a/sound/isa/sb/sb16_csp.c Sun Feb 9 21:13:36 2003 +++ b/sound/isa/sb/sb16_csp.c Sun Feb 9 21:13:37 2003 @@ -107,7 +107,6 @@ static int snd_sb_csp_qsound_transfer(snd_sb_csp_t * p); static int init_proc_entry(snd_sb_csp_t * p, int device); -static void delete_proc_entry(snd_sb_csp_t * p); static void info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer); /* @@ -170,7 +169,6 @@ if (p) { if (p->running & SNDRV_SB_CSP_ST_RUNNING) snd_sb_csp_stop(p); - delete_proc_entry(p); snd_magic_kfree(p); } } @@ -1104,26 +1102,9 @@ char name[16]; snd_info_entry_t *entry; sprintf(name, "cspD%d", device); - entry = p->proc = snd_info_create_card_entry(p->chip->card, name, p->chip->card->proc_root); - if (entry) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->c.text.read_size = 256; - entry->c.text.read = info_read; - entry->private_data = p; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - p->proc = NULL; - } - } + if (! snd_card_proc_new(p->chip->card, name, &entry)) + snd_info_set_text_ops(entry, p, info_read); return 0; -} - -static void delete_proc_entry(snd_sb_csp_t * p) -{ - if (p->proc) { - snd_info_unregister(p->proc); - p->proc = NULL; - } } static void info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer) diff -Nru a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c --- a/sound/isa/sb/sb16_main.c Sun Feb 9 21:13:32 2003 +++ b/sound/isa/sb/sb16_main.c Sun Feb 9 21:13:32 2003 @@ -60,7 +60,7 @@ if (csp->running & SNDRV_SB_CSP_ST_LOADED) { /* manually loaded codec */ if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_WRITE) && - ((1 << runtime->format) == csp->acc_format)) { + ((1U << runtime->format) == csp->acc_format)) { /* Supported runtime PCM format for playback */ if (csp->ops.csp_use(csp) == 0) { /* If CSP was successfully acquired */ @@ -108,7 +108,7 @@ if (csp->running & SNDRV_SB_CSP_ST_LOADED) { /* manually loaded codec */ if ((csp->mode & SNDRV_SB_CSP_MODE_DSP_READ) && - ((1 << runtime->format) == csp->acc_format)) { + ((1U << runtime->format) == csp->acc_format)) { /* Supported runtime PCM format for capture */ if (csp->ops.csp_use(csp) == 0) { /* If CSP was successfully acquired */ @@ -451,7 +451,7 @@ size_t ptr; dma = (chip->mode & SB_MODE_PLAYBACK_8) ? chip->dma8 : chip->dma16; - ptr = chip->p_dma_size - snd_dma_residue(dma); + ptr = snd_dma_pointer(dma, chip->p_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -462,7 +462,7 @@ size_t ptr; dma = (chip->mode & SB_MODE_CAPTURE_8) ? chip->dma8 : chip->dma16; - ptr = chip->c_dma_size - snd_dma_residue(dma); + ptr = snd_dma_pointer(dma, chip->c_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -887,7 +887,14 @@ return 0; } +const snd_pcm_ops_t *snd_sb16dsp_get_pcm_ops(int direction) +{ + return direction == SNDRV_PCM_STREAM_PLAYBACK ? + &snd_sb16_playback_ops : &snd_sb16_capture_ops; +} + EXPORT_SYMBOL(snd_sb16dsp_pcm); +EXPORT_SYMBOL(snd_sb16dsp_get_pcm_ops); EXPORT_SYMBOL(snd_sb16dsp_configure); EXPORT_SYMBOL(snd_sb16dsp_interrupt); diff -Nru a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c --- a/sound/isa/sb/sb8_main.c Sun Feb 9 21:13:31 2003 +++ b/sound/isa/sb/sb8_main.c Sun Feb 9 21:13:31 2003 @@ -365,7 +365,7 @@ if (chip->mode != SB_MODE_PLAYBACK_8) return 0; - ptr = chip->p_dma_size - snd_dma_residue(chip->dma8); + ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size); return bytes_to_frames(substream->runtime, ptr); } @@ -376,7 +376,7 @@ if (chip->mode != SB_MODE_CAPTURE_8) return 0; - ptr = chip->c_dma_size - snd_dma_residue(chip->dma8); + ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size); return bytes_to_frames(substream->runtime, ptr); } diff -Nru a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c --- a/sound/isa/sb/sb_common.c Sun Feb 9 21:13:37 2003 +++ b/sound/isa/sb/sb_common.c Sun Feb 9 21:13:37 2003 @@ -297,6 +297,7 @@ EXPORT_SYMBOL(snd_sbmixer_write); EXPORT_SYMBOL(snd_sbmixer_read); EXPORT_SYMBOL(snd_sbmixer_new); +EXPORT_SYMBOL(snd_sbmixer_add_ctl); /* * INIT part diff -Nru a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c --- a/sound/isa/sb/sb_mixer.c Sun Feb 9 21:13:31 2003 +++ b/sound/isa/sb/sb_mixer.c Sun Feb 9 21:13:31 2003 @@ -60,13 +60,6 @@ * Single channel mixer element */ -#define SB_SINGLE(xname, reg, shift, mask) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .info = snd_sbmixer_info_single, \ - .get = snd_sbmixer_get_single, put: snd_sbmixer_put_single, \ - .private_value = reg | (shift << 16) | (mask << 24) } - static int snd_sbmixer_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { int mask = (kcontrol->private_value >> 24) & 0xff; @@ -119,13 +112,6 @@ * Double channel mixer element */ -#define SB_DOUBLE(xname, left_reg, right_reg, left_shift, right_shift, mask) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .info = snd_sbmixer_info_double, \ - .get = snd_sbmixer_get_double, put: snd_sbmixer_put_double, \ - .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) } - static int snd_sbmixer_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { int mask = (kcontrol->private_value >> 24) & 0xff; @@ -362,13 +348,6 @@ * SB16 input switch */ -#define SB16_INPUT_SW(xname, reg1, reg2, left_shift, right_shift) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .info = snd_sb16mixer_info_input_sw, \ - .get = snd_sb16mixer_get_input_sw, put: snd_sb16mixer_put_input_sw, \ - .private_value = reg1 | (reg2 << 8) | (left_shift << 16) | (right_shift << 24) } - static int snd_sb16mixer_info_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; @@ -428,61 +407,114 @@ return change; } -#define SB20_CONTROLS (sizeof(snd_sb20_controls)/sizeof(snd_kcontrol_new_t *)) -static snd_kcontrol_new_t snd_sb20_ctl_master_play_vol = +/* + */ +/* + */ +int snd_sbmixer_add_ctl(sb_t *chip, const char *name, int index, int type, unsigned long value) +{ + static snd_kcontrol_new_t newctls[] = { + [SB_MIX_SINGLE] = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_sbmixer_info_single, + .get = snd_sbmixer_get_single, + .put = snd_sbmixer_put_single, + }, + [SB_MIX_DOUBLE] = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_sbmixer_info_double, + .get = snd_sbmixer_get_double, + .put = snd_sbmixer_put_double, + }, + [SB_MIX_INPUT_SW] = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_sb16mixer_info_input_sw, + .get = snd_sb16mixer_get_input_sw, + .put = snd_sb16mixer_put_input_sw, + }, + [SB_MIX_CAPTURE_PRO] = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_sb8mixer_info_mux, + .get = snd_sb8mixer_get_mux, + .put = snd_sb8mixer_put_mux, + }, + [SB_MIX_CAPTURE_DT019X] = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_dt019x_input_sw_info, + .get = snd_dt019x_input_sw_get, + .put = snd_dt019x_input_sw_put, + }, + }; + snd_kcontrol_t *ctl; + int err; + + ctl = snd_ctl_new1(&newctls[type], chip); + if (! ctl) + return -ENOMEM; + strncpy(ctl->id.name, name, sizeof(ctl->id.name)-1); + ctl->id.index = index; + ctl->private_value = value; + if ((err = snd_ctl_add(chip->card, ctl)) < 0) { + snd_ctl_free_one(ctl); + return err; + } + return 0; +} + +/* + * SB 2.0 specific mixer elements + */ + +static struct sbmix_elem snd_sb20_ctl_master_play_vol = SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7); -static snd_kcontrol_new_t snd_sb20_ctl_pcm_play_vol = +static struct sbmix_elem snd_sb20_ctl_pcm_play_vol = SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3); -static snd_kcontrol_new_t snd_sb20_ctl_synth_play_vol = +static struct sbmix_elem snd_sb20_ctl_synth_play_vol = SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7); -static snd_kcontrol_new_t snd_sb20_ctl_cd_play_vol = +static struct sbmix_elem snd_sb20_ctl_cd_play_vol = SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7); -static snd_kcontrol_new_t *snd_sb20_controls[] = { +static struct sbmix_elem *snd_sb20_controls[] = { &snd_sb20_ctl_master_play_vol, &snd_sb20_ctl_pcm_play_vol, &snd_sb20_ctl_synth_play_vol, &snd_sb20_ctl_cd_play_vol }; -#define SB20_INIT_VALUES (sizeof(snd_sb20_init_values)/sizeof(unsigned char)/2) - static unsigned char snd_sb20_init_values[][2] = { { SB_DSP20_MASTER_DEV, 0 }, { SB_DSP20_FM_DEV, 0 }, }; -#define SBPRO_CONTROLS (sizeof(snd_sbpro_controls)/sizeof(snd_kcontrol_new_t *)) - -static snd_kcontrol_new_t snd_sbpro_ctl_master_play_vol = +/* + * SB Pro specific mixer elements + */ +static struct sbmix_elem snd_sbpro_ctl_master_play_vol = SB_DOUBLE("Master Playback Volume", SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7); -static snd_kcontrol_new_t snd_sbpro_ctl_pcm_play_vol = +static struct sbmix_elem snd_sbpro_ctl_pcm_play_vol = SB_DOUBLE("PCM Playback Volume", SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7); -static snd_kcontrol_new_t snd_sbpro_ctl_pcm_play_filter = +static struct sbmix_elem snd_sbpro_ctl_pcm_play_filter = SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1); -static snd_kcontrol_new_t snd_sbpro_ctl_synth_play_vol = +static struct sbmix_elem snd_sbpro_ctl_synth_play_vol = SB_DOUBLE("Synth Playback Volume", SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7); -static snd_kcontrol_new_t snd_sbpro_ctl_cd_play_vol = +static struct sbmix_elem snd_sbpro_ctl_cd_play_vol = SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7); -static snd_kcontrol_new_t snd_sbpro_ctl_line_play_vol = +static struct sbmix_elem snd_sbpro_ctl_line_play_vol = SB_DOUBLE("Line Playback Volume", SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7); -static snd_kcontrol_new_t snd_sbpro_ctl_mic_play_vol = +static struct sbmix_elem snd_sbpro_ctl_mic_play_vol = SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3); -static snd_kcontrol_new_t snd_sbpro_ctl_capture_source = +static struct sbmix_elem snd_sbpro_ctl_capture_source = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", - .info = snd_sb8mixer_info_mux, - .get = snd_sb8mixer_get_mux, - .put = snd_sb8mixer_put_mux, + .type = SB_MIX_CAPTURE_PRO }; -static snd_kcontrol_new_t snd_sbpro_ctl_capture_filter = +static struct sbmix_elem snd_sbpro_ctl_capture_filter = SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1); -static snd_kcontrol_new_t snd_sbpro_ctl_capture_low_filter = +static struct sbmix_elem snd_sbpro_ctl_capture_low_filter = SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1); -static snd_kcontrol_new_t *snd_sbpro_controls[] = { +static struct sbmix_elem *snd_sbpro_controls[] = { &snd_sbpro_ctl_master_play_vol, &snd_sbpro_ctl_pcm_play_vol, &snd_sbpro_ctl_pcm_play_filter, @@ -495,58 +527,57 @@ &snd_sbpro_ctl_capture_low_filter }; -#define SBPRO_INIT_VALUES (sizeof(snd_sbpro_init_values)/sizeof(unsigned char)/2) - static unsigned char snd_sbpro_init_values[][2] = { { SB_DSP_MASTER_DEV, 0 }, { SB_DSP_PCM_DEV, 0 }, { SB_DSP_FM_DEV, 0 }, }; -#define SB16_CONTROLS (sizeof(snd_sb16_controls)/sizeof(snd_kcontrol_new_t *)) - -static snd_kcontrol_new_t snd_sb16_ctl_master_play_vol = +/* + * SB16 specific mixer elements + */ +static struct sbmix_elem snd_sb16_ctl_master_play_vol = SB_DOUBLE("Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31); -static snd_kcontrol_new_t snd_sb16_ctl_3d_enhance_switch = +static struct sbmix_elem snd_sb16_ctl_3d_enhance_switch = SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1); -static snd_kcontrol_new_t snd_sb16_ctl_tone_bass = +static struct sbmix_elem snd_sb16_ctl_tone_bass = SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15); -static snd_kcontrol_new_t snd_sb16_ctl_tone_treble = +static struct sbmix_elem snd_sb16_ctl_tone_treble = SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15); -static snd_kcontrol_new_t snd_sb16_ctl_pcm_play_vol = +static struct sbmix_elem snd_sb16_ctl_pcm_play_vol = SB_DOUBLE("PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31); -static snd_kcontrol_new_t snd_sb16_ctl_synth_capture_route = +static struct sbmix_elem snd_sb16_ctl_synth_capture_route = SB16_INPUT_SW("Synth Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5); -static snd_kcontrol_new_t snd_sb16_ctl_synth_play_vol = +static struct sbmix_elem snd_sb16_ctl_synth_play_vol = SB_DOUBLE("Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31); -static snd_kcontrol_new_t snd_sb16_ctl_cd_capture_route = +static struct sbmix_elem snd_sb16_ctl_cd_capture_route = SB16_INPUT_SW("CD Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1); -static snd_kcontrol_new_t snd_sb16_ctl_cd_play_switch = +static struct sbmix_elem snd_sb16_ctl_cd_play_switch = SB_DOUBLE("CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1); -static snd_kcontrol_new_t snd_sb16_ctl_cd_play_vol = +static struct sbmix_elem snd_sb16_ctl_cd_play_vol = SB_DOUBLE("CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31); -static snd_kcontrol_new_t snd_sb16_ctl_line_capture_route = +static struct sbmix_elem snd_sb16_ctl_line_capture_route = SB16_INPUT_SW("Line Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3); -static snd_kcontrol_new_t snd_sb16_ctl_line_play_switch = +static struct sbmix_elem snd_sb16_ctl_line_play_switch = SB_DOUBLE("Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1); -static snd_kcontrol_new_t snd_sb16_ctl_line_play_vol = +static struct sbmix_elem snd_sb16_ctl_line_play_vol = SB_DOUBLE("Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31); -static snd_kcontrol_new_t snd_sb16_ctl_mic_capture_route = +static struct sbmix_elem snd_sb16_ctl_mic_capture_route = SB16_INPUT_SW("Mic Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0); -static snd_kcontrol_new_t snd_sb16_ctl_mic_play_switch = +static struct sbmix_elem snd_sb16_ctl_mic_play_switch = SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1); -static snd_kcontrol_new_t snd_sb16_ctl_mic_play_vol = +static struct sbmix_elem snd_sb16_ctl_mic_play_vol = SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31); -static snd_kcontrol_new_t snd_sb16_ctl_pc_speaker_vol = +static struct sbmix_elem snd_sb16_ctl_pc_speaker_vol = SB_SINGLE("PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3); -static snd_kcontrol_new_t snd_sb16_ctl_capture_vol = +static struct sbmix_elem snd_sb16_ctl_capture_vol = SB_DOUBLE("Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3); -static snd_kcontrol_new_t snd_sb16_ctl_play_vol = +static struct sbmix_elem snd_sb16_ctl_play_vol = SB_DOUBLE("Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3); -static snd_kcontrol_new_t snd_sb16_ctl_auto_mic_gain = +static struct sbmix_elem snd_sb16_ctl_auto_mic_gain = SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1); -static snd_kcontrol_new_t *snd_sb16_controls[] = { +static struct sbmix_elem *snd_sb16_controls[] = { &snd_sb16_ctl_master_play_vol, &snd_sb16_ctl_3d_enhance_switch, &snd_sb16_ctl_tone_bass, @@ -569,8 +600,6 @@ &snd_sb16_ctl_auto_mic_gain }; -#define SB16_INIT_VALUES (sizeof(snd_sb16_init_values)/sizeof(unsigned char)/2) - static unsigned char snd_sb16_init_values[][2] = { { SB_DSP4_MASTER_DEV + 0, 0 }, { SB_DSP4_MASTER_DEV + 1, 0 }, @@ -584,37 +613,34 @@ { SB_DSP4_SPEAKER_DEV, 0 }, }; -#define DT019X_CONTROLS (sizeof(snd_dt019x_controls)/sizeof(snd_kcontrol_new_t *)) - - -static snd_kcontrol_new_t snd_dt019x_ctl_master_play_vol = +/* + * DT019x specific mixer elements + */ +static struct sbmix_elem snd_dt019x_ctl_master_play_vol = SB_DOUBLE("Master Playback Volume", SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4,0, 15); -static snd_kcontrol_new_t snd_dt019x_ctl_pcm_play_vol = +static struct sbmix_elem snd_dt019x_ctl_pcm_play_vol = SB_DOUBLE("PCM Playback Volume", SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4,0, 15); -static snd_kcontrol_new_t snd_dt019x_ctl_synth_play_vol = +static struct sbmix_elem snd_dt019x_ctl_synth_play_vol = SB_DOUBLE("Synth Playback Volume", SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4,0, 15); -static snd_kcontrol_new_t snd_dt019x_ctl_cd_play_vol = +static struct sbmix_elem snd_dt019x_ctl_cd_play_vol = SB_DOUBLE("CD Playback Volume", SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4,0, 15); -static snd_kcontrol_new_t snd_dt019x_ctl_mic_play_vol = +static struct sbmix_elem snd_dt019x_ctl_mic_play_vol = SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7); -static snd_kcontrol_new_t snd_dt019x_ctl_pc_speaker_vol = +static struct sbmix_elem snd_dt019x_ctl_pc_speaker_vol = SB_SINGLE("PC Speaker Volume", SB_DT019X_SPKR_DEV, 0, 7); -static snd_kcontrol_new_t snd_dt019x_ctl_line_play_vol = +static struct sbmix_elem snd_dt019x_ctl_line_play_vol = SB_DOUBLE("Line Playback Volume", SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4,0, 15); -static snd_kcontrol_new_t snd_dt019x_ctl_pcm_play_switch = +static struct sbmix_elem snd_dt019x_ctl_pcm_play_switch = SB_DOUBLE("PCM Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2,1, 1); -static snd_kcontrol_new_t snd_dt019x_ctl_synth_play_switch = +static struct sbmix_elem snd_dt019x_ctl_synth_play_switch = SB_DOUBLE("Synth Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4,3, 1); -static snd_kcontrol_new_t snd_dt019x_ctl_capture_source = +static struct sbmix_elem snd_dt019x_ctl_capture_source = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", - .info = snd_dt019x_input_sw_info, - .get = snd_dt019x_input_sw_get, - .put = snd_dt019x_input_sw_put, + .type = SB_MIX_CAPTURE_DT019X }; -static snd_kcontrol_new_t *snd_dt019x_controls[] = { +static struct sbmix_elem *snd_dt019x_controls[] = { &snd_dt019x_ctl_master_play_vol, &snd_dt019x_ctl_pcm_play_vol, &snd_dt019x_ctl_synth_play_vol, @@ -630,8 +656,6 @@ &snd_dt019x_ctl_capture_source }; -#define DT019X_INIT_VALUES (sizeof(snd_dt019x_init_values)/sizeof(unsigned char)/2) - static unsigned char snd_dt019x_init_values[][2] = { { SB_DT019X_MASTER_DEV, 0 }, { SB_DT019X_PCM_DEV, 0 }, @@ -644,35 +668,36 @@ { SB_DT019X_CAPTURE_SW, 0x06 }, }; +/* + * ALS4000 specific mixer elements + */ /* FIXME: SB_ALS4000_MONO_IO_CTRL needs output select ctrl ! */ -static snd_kcontrol_new_t snd_als4000_ctl_mono_output_switch = +static struct sbmix_elem snd_als4000_ctl_mono_output_switch = SB_SINGLE("Mono Output Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1); /* FIXME: mono input switch also available on DT019X ? */ -static snd_kcontrol_new_t snd_als4000_ctl_mono_input_switch = +static struct sbmix_elem snd_als4000_ctl_mono_input_switch = SB_SINGLE("Mono Input Switch", SB_DT019X_OUTPUT_SW2, 0, 1); -static snd_kcontrol_new_t snd_als4000_ctl_mic_20db_boost = +static struct sbmix_elem snd_als4000_ctl_mic_20db_boost = SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03); -static snd_kcontrol_new_t snd_als4000_ctl_mixer_out_to_in = +static struct sbmix_elem snd_als4000_ctl_mixer_out_to_in = SB_SINGLE("Mixer Out To In", SB_ALS4000_MIC_IN_GAIN, 7, 0x01); /* FIXME: 3D needs much more sophisticated controls, many more features ! */ -static snd_kcontrol_new_t snd_als4000_ctl_3d_output_switch = +static struct sbmix_elem snd_als4000_ctl_3d_output_switch = SB_SINGLE("3D Output Switch", SB_ALS4000_3D_SND_FX, 6, 0x01); -static snd_kcontrol_new_t snd_als4000_ctl_3d_output_ratio = +static struct sbmix_elem snd_als4000_ctl_3d_output_ratio = SB_SINGLE("3D Output Ratio", SB_ALS4000_3D_SND_FX, 0, 0x07); -static snd_kcontrol_new_t snd_als4000_ctl_3d_poweroff_switch = +static struct sbmix_elem snd_als4000_ctl_3d_poweroff_switch = SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01); -static snd_kcontrol_new_t snd_als4000_ctl_3d_delay = +static struct sbmix_elem snd_als4000_ctl_3d_delay = SB_SINGLE("3D Delay", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f); #if NOT_AVAILABLE -static snd_kcontrol_new_t snd_als4000_ctl_fmdac = +static struct sbmix_elem snd_als4000_ctl_fmdac = SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01); -static snd_kcontrol_new_t snd_als4000_ctl_qsound = +static struct sbmix_elem snd_als4000_ctl_qsound = SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f); #endif -#define ALS4000_CONTROLS (sizeof(snd_als4000_controls)/sizeof(snd_kcontrol_new_t *)) - -static snd_kcontrol_new_t *snd_als4000_controls[] = { +static struct sbmix_elem *snd_als4000_controls[] = { &snd_sb16_ctl_master_play_vol, &snd_dt019x_ctl_pcm_play_switch, &snd_sb16_ctl_pcm_play_vol, @@ -706,8 +731,6 @@ #endif }; -#define ALS4000_INIT_VALUES (sizeof(snd_als4000_init_values)/sizeof(unsigned char)/2) - static unsigned char snd_als4000_init_values[][2] = { { SB_DSP4_MASTER_DEV + 0, 0 }, { SB_DSP4_MASTER_DEV + 1, 0 }, @@ -723,8 +746,11 @@ { SB_ALS4000_MIC_IN_GAIN, 0 }, }; + +/* + */ static int snd_sbmixer_init(sb_t *chip, - snd_kcontrol_new_t **controls, + struct sbmix_elem **controls, int controls_count, unsigned char map[][2], int map_count, @@ -747,7 +773,7 @@ } for (idx = 0; idx < controls_count; idx++) { - if ((err = snd_ctl_add(card, snd_ctl_new1(controls[idx], chip))) < 0) + if ((err = snd_sbmixer_add_ctl_elem(chip, controls[idx])) < 0) return err; } snd_component_add(card, name); @@ -770,37 +796,47 @@ case SB_HW_20: case SB_HW_201: if ((err = snd_sbmixer_init(chip, - snd_sb20_controls, SB20_CONTROLS, - snd_sb20_init_values, SB20_INIT_VALUES, + snd_sb20_controls, + ARRAY_SIZE(snd_sb20_controls), + snd_sb20_init_values, + ARRAY_SIZE(snd_sb20_init_values), "CTL1335")) < 0) return err; break; case SB_HW_PRO: if ((err = snd_sbmixer_init(chip, - snd_sbpro_controls, SBPRO_CONTROLS, - snd_sbpro_init_values, SBPRO_INIT_VALUES, + snd_sbpro_controls, + ARRAY_SIZE(snd_sbpro_controls), + snd_sbpro_init_values, + ARRAY_SIZE(snd_sbpro_init_values), "CTL1345")) < 0) return err; break; case SB_HW_16: case SB_HW_ALS100: if ((err = snd_sbmixer_init(chip, - snd_sb16_controls, SB16_CONTROLS, - snd_sb16_init_values, SB16_INIT_VALUES, + snd_sb16_controls, + ARRAY_SIZE(snd_sb16_controls), + snd_sb16_init_values, + ARRAY_SIZE(snd_sb16_init_values), "CTL1745")) < 0) return err; break; case SB_HW_ALS4000: if ((err = snd_sbmixer_init(chip, - snd_als4000_controls, ALS4000_CONTROLS, - snd_als4000_init_values, ALS4000_INIT_VALUES, + snd_als4000_controls, + ARRAY_SIZE(snd_als4000_controls), + snd_als4000_init_values, + ARRAY_SIZE(snd_als4000_init_values), "ALS4000")) < 0) return err; break; case SB_HW_DT019X: if ((err = snd_sbmixer_init(chip, - snd_dt019x_controls, DT019X_CONTROLS, - snd_dt019x_init_values, DT019X_INIT_VALUES, + snd_dt019x_controls, + ARRAY_SIZE(snd_dt019x_controls), + snd_dt019x_init_values, + ARRAY_SIZE(snd_dt019x_init_values), "DT019X")) < 0) break; default: diff -Nru a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c --- a/sound/isa/sgalaxy.c Sun Feb 9 21:13:37 2003 +++ b/sound/isa/sgalaxy.c Sun Feb 9 21:13:37 2003 @@ -30,6 +30,7 @@ #include #include #include +#include #define SNDRV_LEGACY_FIND_FREE_IRQ #define SNDRV_LEGACY_FIND_FREE_DMA #define SNDRV_GET_ID @@ -176,9 +177,7 @@ return snd_sgalaxy_setup_wss(wssport[dev], irq, dma); } -#define SGALAXY_CONTROLS 2 - -static snd_kcontrol_new_t snd_sgalaxy_controls[2] = { +static struct ad1848_mix_elem snd_sgalaxy_controls[] = { AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7, 7, 1, 1), AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0) }; @@ -187,7 +186,8 @@ { snd_card_t *card = chip->card; snd_ctl_elem_id_t id1, id2; - int idx, err; + unsigned int idx; + int err; memset(&id1, 0, sizeof(id1)); memset(&id2, 0, sizeof(id2)); @@ -211,8 +211,8 @@ if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) return err; /* build AUX2 input */ - for (idx = 0; idx < SGALAXY_CONTROLS; idx++) { - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_sgalaxy_controls[idx], chip))) < 0) + for (idx = 0; idx < ARRAY_SIZE(snd_sgalaxy_controls); idx++) { + if ((err = snd_ad1848_add_ctl_elem(chip, &snd_sgalaxy_controls[idx])) < 0) return err; } return 0; diff -Nru a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c --- a/sound/isa/wavefront/wavefront_fx.c Sun Feb 9 21:13:33 2003 +++ b/sound/isa/wavefront/wavefront_fx.c Sun Feb 9 21:13:33 2003 @@ -144,11 +144,8 @@ snd_wavefront_fx_open (snd_hwdep_t *hw, struct file *file) { - MOD_INC_USE_COUNT; - if (!try_module_get(hw->card->module)) { - MOD_DEC_USE_COUNT; + if (!try_module_get(hw->card->module)) return -EFAULT; - } file->private_data = hw; return 0; } @@ -158,7 +155,6 @@ { module_put(hw->card->module); - MOD_DEC_USE_COUNT; return 0; } @@ -199,7 +195,7 @@ } else if (r.data[2] == 1) { pd = (unsigned short *) &r.data[3]; } else { - if (r.data[2] > sizeof (page_data)) { + if (r.data[2] > (long)sizeof (page_data)) { snd_printk ("cannot write " "> 255 bytes to FX\n"); return -EIO; diff -Nru a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c --- a/sound/isa/wavefront/wavefront_synth.c Sun Feb 9 21:13:31 2003 +++ b/sound/isa/wavefront/wavefront_synth.c Sun Feb 9 21:13:31 2003 @@ -877,7 +877,7 @@ u32 length; u16 *data_end = 0; unsigned int i; - const int max_blksize = 4096/2; + const unsigned int max_blksize = 4096/2; unsigned int written; unsigned int blocksize; int dma_ack; @@ -944,7 +944,7 @@ if (header->size) { dev->freemem = wavefront_freemem (dev); - if (dev->freemem < header->size) { + if (dev->freemem < (int)header->size) { snd_printk ("insufficient memory to " "load %d byte sample.\n", header->size); @@ -1603,11 +1603,8 @@ snd_wavefront_synth_open (snd_hwdep_t *hw, struct file *file) { - MOD_INC_USE_COUNT; - if (!try_module_get(hw->card->module)) { - MOD_DEC_USE_COUNT; + if (!try_module_get(hw->card->module)) return -EFAULT; - } file->private_data = hw; return 0; } @@ -1617,7 +1614,6 @@ { module_put(hw->card->module); - MOD_DEC_USE_COUNT; return 0; } diff -Nru a/sound/oss/Kconfig b/sound/oss/Kconfig --- a/sound/oss/Kconfig Sun Feb 9 21:13:35 2003 +++ b/sound/oss/Kconfig Sun Feb 9 21:13:35 2003 @@ -17,7 +17,7 @@ don't need this driver as most TV cards handle sound with a short cable from the TV card to your sound card's line-in. - This driver is available as a module called btaudio.o ( = code + This driver is available as a module called btaudio ( = code which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read . @@ -528,7 +528,7 @@ help OSS is the Open Sound System suite of sound card drivers. They make sound programming easier since they provide a common API. Say Y or - M here (the module will be called sound.o) if you haven't found a + M here (the module will be called sound) if you haven't found a driver for your sound card above, then pick your driver from the list below. @@ -552,7 +552,7 @@ until the shutdown. This option is only useful if you said Y to "OSS sound modules", above. If you said M to "OSS sound modules" then you can get the persistent DMA buffer functionality by passing - the command-line argument "dmabuf=1" to the sound.o module. + the command-line argument "dmabuf=1" to the sound module. Say Y unless you have 16MB or more RAM or a PCI sound card. @@ -600,7 +600,7 @@ miropcm20 driver (say M or Y here and go back to "Multimedia devices" -> "Radio Adapters"). - This driver is also available as a module and will be called aci.o. + This driver is also available as a module and will be called aci. config SOUND_CS4232 tristate "Crystal CS4232 based (PnP) cards" @@ -861,7 +861,7 @@ command line. You can say M here to compile this driver as a module; the module is - called sb.o. + called sb. config SOUND_AWE32_SYNTH tristate "AWE32 synth" diff -Nru a/sound/oss/Makefile b/sound/oss/Makefile --- a/sound/oss/Makefile Sun Feb 9 21:13:30 2003 +++ b/sound/oss/Makefile Sun Feb 9 21:13:30 2003 @@ -3,13 +3,6 @@ # 18 Apr 1998, Michael Elizabeth Chastain, # Rewritten to use lists instead of if-statements. -# All of the (potential) objects that export symbols. -# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. - -export-objs := ad1848.o audio_syms.o midi_syms.o mpu401.o ac97_codec.o \ - msnd.o opl3.o sb_common.o sequencer_syms.o ac97.o aci.o \ - sound_syms.o uart401.o - # Each configuration option enables a list of files. obj-$(CONFIG_SOUND_OSS) += sound.o diff -Nru a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c --- a/sound/oss/ac97_codec.c Sun Feb 9 21:13:29 2003 +++ b/sound/oss/ac97_codec.c Sun Feb 9 21:13:29 2003 @@ -446,7 +446,7 @@ } /* read or write the recmask, the ac97 can really have left and right recording - inputs independantly set, but OSS doesn't seem to want us to express that to + inputs independently set, but OSS doesn't seem to want us to express that to the user. the caller guarantees that we have a supported bit set, and they must be holding the card's spinlock */ static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask) diff -Nru a/sound/oss/dmasound/Makefile b/sound/oss/dmasound/Makefile --- a/sound/oss/dmasound/Makefile Sun Feb 9 21:13:29 2003 +++ b/sound/oss/dmasound/Makefile Sun Feb 9 21:13:29 2003 @@ -2,8 +2,6 @@ # Makefile for the DMA sound driver # -export-objs := dmasound_core.o - obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o obj-$(CONFIG_DMASOUND_AWACS) += dmasound_core.o dmasound_awacs.o obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o diff -Nru a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c --- a/sound/oss/i810_audio.c Sun Feb 9 21:13:34 2003 +++ b/sound/oss/i810_audio.c Sun Feb 9 21:13:34 2003 @@ -177,7 +177,7 @@ struct i810_channel { /* these sg guys should probably be allocated - seperately as nocache. Must be 8 byte aligned */ + separately as nocache. Must be 8 byte aligned */ struct sg_item sg[SG_LEN]; /* 32*8 */ u32 offset; /* 4 */ u32 port; /* 4 */ @@ -186,7 +186,7 @@ }; /* - * we have 3 seperate dma engines. pcm in, pcm out, and mic. + * we have 3 separate dma engines. pcm in, pcm out, and mic. * each dma engine has controlling registers. These goofy * names are from the datasheet, but make it easy to write * code while leafing through it. @@ -900,7 +900,7 @@ #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT) #define DMABUF_MINORDER 1 -/* allocate DMA buffer, playback and recording buffer should be allocated seperately */ +/* allocate DMA buffer, playback and recording buffer should be allocated separately */ static int alloc_dmabuf(struct i810_state *state) { struct dmabuf *dmabuf = &state->dmabuf; diff -Nru a/sound/oss/maestro.c b/sound/oss/maestro.c --- a/sound/oss/maestro.c Sun Feb 9 21:13:35 2003 +++ b/sound/oss/maestro.c Sun Feb 9 21:13:35 2003 @@ -668,7 +668,7 @@ if (mixer == SOUND_MIXER_IGAIN) { right = (right * 100) / mh->scale; left = (left * 100) / mh->scale; - else { + } else { right = 100 - ((right * 100) / mh->scale); left = 100 - ((left * 100) / mh->scale); } @@ -793,7 +793,7 @@ /* read or write the recmask the ac97 can really have left and right recording - inputs independantly set, but OSS doesn't seem to + inputs independently set, but OSS doesn't seem to want us to express that to the user. the caller guarantees that we have a supported bit set, and they must be holding the card's spinlock */ diff -Nru a/sound/oss/trident.c b/sound/oss/trident.c --- a/sound/oss/trident.c Sun Feb 9 21:13:34 2003 +++ b/sound/oss/trident.c Sun Feb 9 21:13:34 2003 @@ -1227,7 +1227,7 @@ } /* allocate the main DMA buffer, playback and recording buffer should be */ -/* allocated seperately */ +/* allocated separately */ static int alloc_main_dmabuf(struct trident_state *state) { struct dmabuf *dmabuf = &state->dmabuf; diff -Nru a/sound/pci/Kconfig b/sound/pci/Kconfig --- a/sound/pci/Kconfig Sun Feb 9 21:13:30 2003 +++ b/sound/pci/Kconfig Sun Feb 9 21:13:30 2003 @@ -51,8 +51,8 @@ tristate "RME Digi32, 32/8, 32 PRO" depends on SND help - Say 'Y' or 'M' to include support for RME Digi32, Digi32/8 and - Digi32 PRO audio devices. + Say 'Y' or 'M' to include support for RME Digi32, Digi32 PRO and + Digi32/8 (Sek'd Prodif32, Prodif96 and Prodif Gold) audio devices. config SND_RME96 tristate "RME Digi96, 96/8, 96/8 PRO" @@ -116,10 +116,10 @@ Sound Blaster PCI 64 or 128 soundcards. config SND_ES1938 - tristate "ESS ES1938/1946 (Solo-1)" + tristate "ESS ES1938/1946/1969 (Solo-1)" depends on SND && SOUND_GAMEPORT help - Say 'Y' or 'M' to include support for ESS Solo-1 (ES1938, ES1946) + Say 'Y' or 'M' to include support for ESS Solo-1 (ES1938, ES1946, ES1969) soundcard. config SND_ES1968 diff -Nru a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile --- a/sound/pci/ac97/Makefile Sun Feb 9 21:13:33 2003 +++ b/sound/pci/ac97/Makefile Sun Feb 9 21:13:33 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := ac97_codec.o ak4531_codec.o - snd-ac97-codec-objs := ac97_codec.o ac97_patch.o snd-ak4531-codec-objs := ak4531_codec.o diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c --- a/sound/pci/ac97/ac97_codec.c Sun Feb 9 21:13:31 2003 +++ b/sound/pci/ac97/ac97_codec.c Sun Feb 9 21:13:31 2003 @@ -51,7 +51,6 @@ */ static void snd_ac97_proc_init(snd_card_t * card, ac97_t * ac97); -static void snd_ac97_proc_done(ac97_t * ac97); typedef struct { unsigned int id; @@ -68,6 +67,7 @@ { 0x434d4900, 0xffffff00, "C-Media Electronics", NULL }, { 0x43525900, 0xffffff00, "Cirrus Logic", NULL }, { 0x43585400, 0xffffff00, "Conexant", NULL }, +{ 0x44543000, 0xffffff00, "Diamond Technology", NULL }, { 0x454d4300, 0xffffff00, "eMicro", NULL }, { 0x45838300, 0xffffff00, "ESS Technology", NULL }, { 0x48525300, 0xffffff00, "Intersil", NULL }, @@ -121,6 +121,7 @@ { 0x43525960, 0xfffffff8, "CS4291", NULL }, { 0x43585421, 0xffffffff, "HSD11246", NULL }, // SmartMC II { 0x43585428, 0xfffffff8, "Cx20468", patch_conexant }, // SmartAMC fixme: the mask might be different +{ 0x44543031, 0xfffffff0, "DT0398", NULL }, { 0x454d4328, 0xffffffff, "28028", NULL }, // same as TR28028? { 0x45838308, 0xffffffff, "ESS1988", NULL }, { 0x48525300, 0xffffff00, "HMP9701", NULL }, @@ -142,7 +143,7 @@ { 0x57454301, 0xffffffff, "W83971D", NULL }, { 0x574d4c00, 0xffffffff, "WM9701A", patch_wolfson00 }, { 0x574d4c03, 0xffffffff, "WM9703/9707", patch_wolfson03 }, -{ 0x574d4c04, 0xffffffff, "WM9704 (quad)", patch_wolfson04 }, +{ 0x574d4c04, 0xffffffff, "WM9704/quad", patch_wolfson04 }, { 0x574d4c05, 0xffffffff, "WM9705", NULL }, // patch? { 0x594d4800, 0xffffffff, "YMF743", NULL }, { 0x594d4802, 0xffffffff, "YMF752", NULL }, @@ -240,6 +241,18 @@ return 1; } +/** + * snd_ac97_write - write a value on the given register + * @ac97: the ac97 instance + * @reg: the register to change + * @value: the value to set + * + * Writes a value on the given register. This will invoke the write + * callback directly after the register check. + * This function doesn't change the register cache unlike + * #snd_ca97_write_cache(), so use this only when you don't want to + * reflect the change to the suspend/resume state. + */ void snd_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short value) { if (!snd_ac97_valid_reg(ac97, reg)) @@ -247,6 +260,17 @@ ac97->write(ac97, reg, value); } +/** + * snd_ac97_read - read a value from the given register + * + * @ac97: the ac97 instance + * @reg: the register to read + * + * Reads a value from the given register. This will invoke the read + * callback directly after the register check. + * + * Returns the read value. + */ unsigned short snd_ac97_read(ac97_t *ac97, unsigned short reg) { if (!snd_ac97_valid_reg(ac97, reg)) @@ -254,13 +278,24 @@ return ac97->read(ac97, reg); } +/** + * snd_ac97_write_cache - write a value on the given register and update the cache + * @ac97: the ac97 instance + * @reg: the register to change + * @value: the value to set + * + * Writes a value on the given register and updates the register + * cache. The cached values are used for the cached-read and the + * suspend/resume. + */ void snd_ac97_write_cache(ac97_t *ac97, unsigned short reg, unsigned short value) { if (!snd_ac97_valid_reg(ac97, reg)) return; spin_lock(&ac97->reg_lock); - ac97->write(ac97, reg, ac97->regs[reg] = value); + ac97->regs[reg] = value; spin_unlock(&ac97->reg_lock); + ac97->write(ac97, reg, value); set_bit(reg, ac97->reg_accessed); } @@ -269,16 +304,28 @@ #if 0 if (!snd_ac97_valid_reg(ac97, reg)) return; - spin_lock(&ac97->reg_lock); + //spin_lock(&ac97->reg_lock); ac97->write(ac97, reg, value); ac97->regs[reg] = ac97->read(ac97, reg); if (value != ac97->regs[reg]) snd_printk("AC97 reg=%02x val=%04x real=%04x\n", reg, value, ac97->regs[reg]); - spin_unlock(&ac97->reg_lock); + //spin_unlock(&ac97->reg_lock); #endif snd_ac97_write_cache(ac97, reg, value); } +/** + * snd_ac97_update - update the value on the given register + * @ac97: the ac97 instance + * @reg: the register to change + * @value: the value to set + * + * Compares the value with the register cache and updates the value + * only when the value is changed. + * + * Retruns 1 if the value is changed, 0 if no change, or a negative + * code on failure. + */ int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value) { int change; @@ -288,40 +335,48 @@ spin_lock(&ac97->reg_lock); change = ac97->regs[reg] != value; if (change) { - ac97->write(ac97, reg, value); ac97->regs[reg] = value; - } - spin_unlock(&ac97->reg_lock); + spin_unlock(&ac97->reg_lock); + ac97->write(ac97, reg, value); + } else + spin_unlock(&ac97->reg_lock); return change; } -int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value) +/** + * snd_ac97_update_bits - update the bits on the given register + * @ac97: the ac97 instance + * @reg: the register to change + * @mask: the bit-mask to change + * @value: the value to set + * + * Updates the masked-bits on the given register onle when the value + * is changed. + * + * Returns 1 if the bits are changed, 0 if no change, or a negative + * code on failure. + */ +int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value) { int change; unsigned short old, new; if (!snd_ac97_valid_reg(ac97, reg)) return -EINVAL; + spin_lock(&ac97->reg_lock); old = ac97->regs[reg]; new = (old & ~mask) | value; change = old != new; if (change) { - ac97->write(ac97, reg, new); ac97->regs[reg] = new; - } - return change; -} - -int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value) -{ - int change; - spin_lock(&ac97->reg_lock); - change = snd_ac97_update_bits_nolock(ac97, reg, mask, value); - spin_unlock(&ac97->reg_lock); + spin_unlock(&ac97->reg_lock); + ac97->write(ac97, reg, new); + } else + spin_unlock(&ac97->reg_lock); return change; } -int snd_ac97_ad18xx_update_pcm_bits(ac97_t *ac97, int codec, unsigned short mask, unsigned short value) +static int snd_ac97_ad18xx_update_pcm_bits(ac97_t *ac97, int codec, unsigned short mask, unsigned short value) { int change; unsigned short old, new; @@ -332,15 +387,16 @@ new = (old & ~mask) | value; change = old != new; if (change) { + ac97->spec.ad18xx.pcmreg[codec] = new; + spin_unlock(&ac97->reg_lock); /* select single codec */ ac97->write(ac97, AC97_AD_SERIAL_CFG, ac97->spec.ad18xx.unchained[codec] | ac97->spec.ad18xx.chained[codec]); /* update PCM bits */ ac97->write(ac97, AC97_PCM, new); /* select all codecs */ ac97->write(ac97, AC97_AD_SERIAL_CFG, 0x7000); - ac97->spec.ad18xx.pcmreg[codec] = new; - } - spin_unlock(&ac97->reg_lock); + } else + spin_unlock(&ac97->reg_lock); up(&ac97->spec.ad18xx.mutex); return change; } @@ -671,6 +727,11 @@ AC97_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1), }; +static const snd_kcontrol_new_t snd_ac97_sigmatel_surround[2] = { +AC97_SINGLE("Sigmatel Surround Playback Switch", AC97_HEADPHONE, 15, 1, 1), +AC97_DOUBLE("Sigmatel Surround Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1) +}; + static const snd_kcontrol_new_t snd_ac97_sigmatel_controls[] = { AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0), AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 0, 1, 0) @@ -733,7 +794,7 @@ ac97_t *ac97 = snd_kcontrol_chip(kcontrol); unsigned int new = 0; unsigned short val = 0; - int change = 0; + int change; spin_lock(&ac97->reg_lock); new = val = ucontrol->value.iec958.status[0] & (IEC958_AES0_PROFESSIONAL|IEC958_AES0_NONAUDIO); @@ -764,7 +825,9 @@ } } - + change = ac97->spdif_status != new; + ac97->spdif_status = new; + spin_unlock(&ac97->reg_lock); if (ac97->flags & AC97_CS_SPDIF) { int x = (val >> 12) & 0x03; @@ -773,24 +836,51 @@ case 2: x = 0; break; // 48.0 default: x = 0; break; // illegal. } - change = snd_ac97_update_bits_nolock(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12))); + change |= snd_ac97_update_bits(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12))); } else if (ac97->flags & AC97_CX_SPDIF) { int v; - v = ucontrol->value.iec958.status[0] & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT) ? 0 : AC97_CXR_COPYRGT; - v |= ucontrol->value.iec958.status[0] & IEC958_AES0_NONAUDIO ? AC97_CXR_SPDIF_AC3 : AC97_CXR_SPDIF_PCM; - change = snd_ac97_update_bits_nolock(ac97, AC97_CXR_AUDIO_MISC, - AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT, - v); + v = new & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT) ? 0 : AC97_CXR_COPYRGT; + v |= new & IEC958_AES0_NONAUDIO ? AC97_CXR_SPDIF_AC3 : AC97_CXR_SPDIF_PCM; + change |= snd_ac97_update_bits(ac97, AC97_CXR_AUDIO_MISC, + AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT, + v); } else { - change = snd_ac97_update_bits_nolock(ac97, AC97_SPDIF, 0x3fff, val); + change |= snd_ac97_update_bits(ac97, AC97_SPDIF, 0x3fff, val); } - change |= ac97->spdif_status != new; - ac97->spdif_status = new; - spin_unlock(&ac97->reg_lock); return change; } +static int snd_ac97_put_spsa(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +{ + ac97_t *ac97 = snd_kcontrol_chip(kcontrol); + int reg = kcontrol->private_value & 0xff; + int shift = (kcontrol->private_value >> 8) & 0xff; + int mask = (kcontrol->private_value >> 16) & 0xff; + // int invert = (kcontrol->private_value >> 24) & 0xff; + unsigned short value, old, new; + + value = (ucontrol->value.integer.value[0] & mask); + + mask <<= shift; + value <<= shift; + spin_lock(&ac97->reg_lock); + old = ac97->regs[reg]; + new = (old & ~mask) | value; + spin_unlock(&ac97->reg_lock); + + if (old != new) { + int change; + unsigned short extst = ac97->regs[AC97_EXTENDED_STATUS]; + snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); /* turn off */ + change = snd_ac97_update_bits(ac97, reg, mask, value); + if (extst & AC97_EA_SPDIF) + snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ + return change; + } + return 0; +} + static const snd_kcontrol_new_t snd_ac97_controls_spdif[5] = { { .access = SNDRV_CTL_ELEM_ACCESS_READ, @@ -815,7 +905,15 @@ }, AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),AC97_EXTENDED_STATUS, 2, 1, 0), - AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA",AC97_EXTENDED_STATUS, 4, 3, 0) + // AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA",AC97_EXTENDED_STATUS, 4, 3, 0) + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA", + .info = snd_ac97_info_single, + .get = snd_ac97_get_single, + .put = snd_ac97_put_spsa, + .private_value = AC97_EXTENDED_STATUS | (4 << 8) | (3 << 16) | (0 << 24), + }, }; static const snd_kcontrol_new_t snd_ac97_cirrus_controls_spdif[2] = { @@ -930,17 +1028,29 @@ AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0), AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH, 2, 1, 0), AC97_SINGLE("Exchange Center/LFE", AC97_ALC650_MULTICH, 3, 1, 0), + /* 4: Analog Input To Surround */ + /* 5: Analog Input To Center/LFE */ + /* 6: Indepedent Master Volume Right */ + /* 7: Indepedent Master Volume Left */ + /* 8: reserved */ AC97_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0), AC97_SINGLE("Mic As Center/LFE", AC97_ALC650_MULTICH, 10, 1, 0), - AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0), - AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0), - AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), #if 0 /* always set in patch_alc650 */ AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0), AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0), + AC97_SINGLE("Surround DAC Switch", AC97_ALC650_SURR_DAC_VOL, 15, 1, 1), + AC97_DOUBLE("Surround DAC Volume", AC97_ALC650_SURR_DAC_VOL, 8, 0, 31, 1), + AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL, 15, 1, 1), + AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL, 8, 0, 31, 1), #endif }; +static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = { + AC97_SINGLE("IEC958 Capture Switch", AC97_ALC650_MULTICH, 11, 1, 0), + AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0), + AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), +}; + /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */ /* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */ @@ -1093,7 +1203,6 @@ static int snd_ac97_free(ac97_t *ac97) { if (ac97) { - snd_ac97_proc_done(ac97); if (ac97->private_free) ac97->private_free(ac97); snd_magic_kfree(ac97); @@ -1236,7 +1345,9 @@ static int snd_ac97_mixer_build(snd_card_t * card, ac97_t * ac97) { snd_kcontrol_t *kctl; - int err, idx; + const snd_kcontrol_new_t *knew; + int err; + unsigned int idx; unsigned char max; /* build master controls */ @@ -1291,10 +1402,11 @@ } /* build headphone controls */ - if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE)) { - if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_headphone[0], ac97))) < 0) + if (snd_ac97_try_volume_mix(ac97, AC97_HEADPHONE) || ac97->id == AC97_ID_STAC9708) { + knew = ac97->id == AC97_ID_STAC9708 ? snd_ac97_sigmatel_surround : snd_ac97_controls_headphone; + if ((err = snd_ctl_add(card, snd_ac97_cnew(knew, ac97))) < 0) return err; - if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(&snd_ac97_controls_headphone[1], ac97))) < 0) + if ((err = snd_ctl_add(card, kctl = snd_ac97_cnew(knew + 1, ac97))) < 0) return err; snd_ac97_change_volume_params1(ac97, AC97_HEADPHONE, &max); kctl->private_value &= ~(0xff << 16); @@ -1590,6 +1702,11 @@ for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_alc650); idx++) if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_alc650[idx], ac97))) < 0) return err; + if (ac97->ext_id & AC97_EI_SPDIF) { + for (idx = 0; idx < ARRAY_SIZE(snd_ac97_spdif_controls_alc650); idx++) + if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_spdif_controls_alc650[idx], ac97))) < 0) + return err; + } break; case AC97_ID_VT1616: if (snd_ac97_try_bit(ac97, 0x5a, 9)) @@ -1676,9 +1793,68 @@ pid->patch(ac97); return; } - sprintf(name + strlen(name), " (%x)", id & 0xff); + sprintf(name + strlen(name), " id %x", id & 0xff); } + +/* wait for a while until registers are accessible after RESET + * return 0 if ok, negative not ready + */ +static int ac97_reset_wait(ac97_t *ac97, int timeout, int with_modem) +{ + signed long end_time; + end_time = jiffies + timeout; + do { + unsigned short ext_mid; + + /* use preliminary reads to settle the communication */ + snd_ac97_read(ac97, AC97_RESET); + snd_ac97_read(ac97, AC97_VENDOR_ID1); + snd_ac97_read(ac97, AC97_VENDOR_ID2); + /* modem? */ + if (with_modem) { + ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID); + if (ext_mid != 0xffff && (ext_mid & 1) != 0) + return 0; + } + /* because the PCM or MASTER volume registers can be modified, + * the REC_GAIN register is used for tests + */ + /* test if we can write to the record gain volume register */ + snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05); + if (snd_ac97_read(ac97, AC97_REC_GAIN) == 0x8a05) + return 0; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/100); + } while (time_after_eq(end_time, jiffies)); + return -ENODEV; +} + +/** + * snd_ac97_mixer - create an AC97 codec component + * @card: the card instance + * @_ac97: the template of ac97, including index, callbacks and + * the private data. + * @rac97: the pointer to store the new ac97 instance. + * + * Creates an AC97 codec component. An ac97_t instance is newly + * allocated and initialized from the template (_ac97). The codec + * is then initialized by the standard procedure. + * + * The template must include the valid callbacks (at least read and + * write), the codec number (num) and address (addr), and the private + * data (private_data). The other callbacks, wait and reset, are not + * mandantory. + * + * The clock is set to 48000. If another clock is needed, reset + * ac97->clock manually afterwards. + * + * The ac97 instance is registered as a low-level device, so you don't + * have to release it manually. + * + * Returns zero if sucessful, or a negative error code on failure. + */ + int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97) { int err; @@ -1709,32 +1885,12 @@ ac97->wait(ac97); else { udelay(50); - - /* it's necessary to wait awhile until registers are accessible after RESET */ - /* because the PCM or MASTER volume registers can be modified, */ - /* the REC_GAIN register is used for tests */ - end_time = jiffies + HZ; - do { - unsigned short ext_mid; - - /* use preliminary reads to settle the communication */ - snd_ac97_read(ac97, AC97_RESET); - snd_ac97_read(ac97, AC97_VENDOR_ID1); - snd_ac97_read(ac97, AC97_VENDOR_ID2); - /* modem? */ - ext_mid = snd_ac97_read(ac97, AC97_EXTENDED_MID); - if (ext_mid != 0xffff && (ext_mid & 1) != 0) - goto __access_ok; - /* test if we can write to the record gain volume register */ - snd_ac97_write_cache(ac97, AC97_REC_GAIN, 0x8a05); - if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) - goto __access_ok; - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/100); - } while (time_after_eq(end_time, jiffies)); - snd_printk("AC'97 %d:%d does not respond - RESET [REC_GAIN = 0x%x]\n", ac97->num, ac97->addr, err); - snd_ac97_free(ac97); - return -ENXIO; + if (ac97_reset_wait(ac97, HZ/2, 0) < 0 && + ac97_reset_wait(ac97, HZ/2, 1) < 0) { + snd_printk("AC'97 %d:%d does not respond - RESET [REC_GAIN = 0x%x]\n", ac97->num, ac97->addr, err); + snd_ac97_free(ac97); + return -ENXIO; + } } __access_ok: ac97->id = snd_ac97_read(ac97, AC97_VENDOR_ID1) << 16; @@ -1859,7 +2015,7 @@ } /* - + * proc interface */ static void snd_ac97_proc_read_main(ac97_t *ac97, snd_info_buffer_t * buffer, int subidx) @@ -2082,46 +2238,14 @@ sprintf(name, "ac97#%d-%d", ac97->addr, ac97->num); else sprintf(name, "ac97#%d", ac97->addr); - if ((entry = snd_info_create_card_entry(card, name, card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = ac97; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 512; - entry->c.text.read = snd_ac97_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - ac97->proc_entry = entry; + if (! snd_card_proc_new(card, name, &entry)) + snd_info_set_text_ops(entry, ac97, snd_ac97_proc_read); if (ac97->num) sprintf(name, "ac97#%d-%dregs", ac97->addr, ac97->num); else sprintf(name, "ac97#%dregs", ac97->addr); - if ((entry = snd_info_create_card_entry(card, name, card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = ac97; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 1024; - entry->c.text.read = snd_ac97_proc_regs_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - ac97->proc_regs_entry = entry; -} - -static void snd_ac97_proc_done(ac97_t * ac97) -{ - if (ac97->proc_regs_entry) { - snd_info_unregister(ac97->proc_regs_entry); - ac97->proc_regs_entry = NULL; - } - if (ac97->proc_entry) { - snd_info_unregister(ac97->proc_entry); - ac97->proc_entry = NULL; - } + if (! snd_card_proc_new(card, name, &entry)) + snd_info_set_text_ops(entry, ac97, snd_ac97_proc_regs_read); } /* @@ -2158,15 +2282,32 @@ spin_lock(&ac97->reg_lock); old = ac97->regs[reg] & ~AC97_SC_SPSR_MASK; + spin_unlock(&ac97->reg_lock); if (old != bits) { - snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); - snd_ac97_update_bits_nolock(ac97, reg, AC97_SC_SPSR_MASK, bits); + snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); + snd_ac97_update_bits(ac97, reg, AC97_SC_SPSR_MASK, bits); } - snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); - spin_unlock(&ac97->reg_lock); + snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); return 0; } +/** + * snd_ac97_set_rate - change the rate of the given input/output. + * @ac97: the ac97 instance + * @reg: the register to change + * @rate: the sample rate to set + * + * Changes the rate of the given input/output on the codec. + * If the codec doesn't support VAR, the rate must be 48000 (except + * for SPDIF). + * + * The valid registers are AC97_PMC_MIC_ADC_RATE, + * AC97_PCM_FRONT_DAC_RATE, AC97_PCM_LR_ADC_RATE and AC97_SPDIF. + * The SPDIF register is a pseudo-register to change the rate of SPDIF + * (only if supported). + * + * Returns zero if successful, or a negative error code on failure. + */ int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned short rate) { unsigned short mask; @@ -2206,8 +2347,11 @@ #ifdef CONFIG_PM -/* - * general suspend procedure +/** + * snd_ac97_suspend - General suspend function for AC97 codec + * @ac97: the ac97 instance + * + * Suspends the codec, power down the chip. */ void snd_ac97_suspend(ac97_t *ac97) { @@ -2224,8 +2368,12 @@ snd_ac97_write(ac97, AC97_POWERDOWN, power); } -/* - * general resume procedure +/** + * snd_ac97_resume - General resume function for AC97 codec + * @ac97: the ac97 instance + * + * Do the standard resume procedure, power up and restoring the + * old register values. */ void snd_ac97_resume(ac97_t *ac97) { diff -Nru a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c --- a/sound/pci/ac97/ac97_patch.c Sun Feb 9 21:13:36 2003 +++ b/sound/pci/ac97/ac97_patch.c Sun Feb 9 21:13:36 2003 @@ -353,8 +353,23 @@ int patch_alc650(ac97_t * ac97) { - /* enable spdif in */ - snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK, - snd_ac97_read(ac97, AC97_ALC650_CLOCK) | 0x03); + unsigned short val; + + /* check spdif */ + val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS); + if (val & AC97_EA_SPCV) { + /* enable spdif in */ + snd_ac97_write_cache(ac97, AC97_ALC650_CLOCK, + snd_ac97_read(ac97, AC97_ALC650_CLOCK) | 0x03); + } else + ac97->ext_id &= ~AC97_EI_SPDIF; /* disable extended-id */ + + val = snd_ac97_read(ac97, AC97_ALC650_MULTICH); + val &= ~0xc000; /* slot: 3,4,7,8,6,9 */ + snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, val | 0x03); + + /* full DAC volume */ + snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808); + snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808); return 0; } diff -Nru a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c --- a/sound/pci/ac97/ak4531_codec.c Sun Feb 9 21:13:29 2003 +++ b/sound/pci/ac97/ak4531_codec.c Sun Feb 9 21:13:29 2003 @@ -33,7 +33,6 @@ #define chip_t ak4531_t static void snd_ak4531_proc_init(snd_card_t * card, ak4531_t * ak4531); -static void snd_ak4531_proc_done(ak4531_t * ak4531); /* * @@ -314,7 +313,6 @@ static int snd_ak4531_free(ak4531_t *ak4531) { if (ak4531) { - snd_ak4531_proc_done(ak4531); if (ak4531->private_free) ak4531->private_free(ak4531); snd_magic_kfree(ak4531); @@ -359,7 +357,8 @@ int snd_ak4531_mixer(snd_card_t * card, ak4531_t * _ak4531, ak4531_t ** rak4531) { - int idx, err; + unsigned int idx; + int err; ak4531_t * ak4531; static snd_device_ops_t ops = { .dev_free = snd_ak4531_dev_free, @@ -425,26 +424,8 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(card, "ak4531", card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = ak4531; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 256; - entry->c.text.read = snd_ak4531_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - ak4531->proc_entry = entry; -} - -static void snd_ak4531_proc_done(ak4531_t * ak4531) -{ - if (ak4531->proc_entry) { - snd_info_unregister(ak4531->proc_entry); - ak4531->proc_entry = NULL; - } + if (! snd_card_proc_new(card, "ak4531", &entry)) + snd_info_set_text_ops(entry, ak4531, snd_ak4531_proc_read); } EXPORT_SYMBOL(snd_ak4531_mixer); diff -Nru a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c --- a/sound/pci/ali5451/ali5451.c Sun Feb 9 21:13:36 2003 +++ b/sound/pci/ali5451/ali5451.c Sun Feb 9 21:13:36 2003 @@ -529,7 +529,8 @@ udelay(5000); } - snd_printk(KERN_WARNING "ali5451: reset time out\n"); + /* non-fatal if you have a non PM capable codec */ + /* snd_printk(KERN_WARNING "ali5451: reset time out\n"); */ return 0; } @@ -1850,7 +1851,8 @@ static int __devinit snd_ali_mixer(ali_t * codec) { ac97_t ac97; - int err, idx; + unsigned int idx; + int err; memset(&ac97, 0, sizeof(ac97)); ac97.write = snd_ali_codec_write; @@ -2088,12 +2090,12 @@ /* enable PCI device */ if ((err = pci_enable_device(pci)) < 0) return err; - /* check, if we can restrict PCI DMA transfers to 30 bits */ - if (!pci_dma_supported(pci, 0x3fffffff)) { - snd_printk("architecture does not support 30bit PCI busmaster DMA\n"); + /* check, if we can restrict PCI DMA transfers to 31 bits */ + if (!pci_dma_supported(pci, 0x7fffffff)) { + snd_printk("architecture does not support 31bit PCI busmaster DMA\n"); return -ENXIO; } - pci_set_dma_mask(pci, 0x3fffffff); + pci_set_dma_mask(pci, 0x7fffffff); if ((codec = snd_magic_kcalloc(ali_t, 0, GFP_KERNEL)) == NULL) return -ENOMEM; diff -Nru a/sound/pci/cmipci.c b/sound/pci/cmipci.c --- a/sound/pci/cmipci.c Sun Feb 9 21:13:29 2003 +++ b/sound/pci/cmipci.c Sun Feb 9 21:13:29 2003 @@ -20,9 +20,7 @@ /* Does not work. Warning may block system in capture mode */ /* #define USE_VAR48KRATE */ -/* Define this if you want soft ac3 encoding - it's still buggy.. */ -/* #define DO_SOFT_AC3 */ -/* #define USE_AES_IEC958 */ +/* Define this if you want soft ac3 encoding */ #define DO_SOFT_AC3 #define USE_AES_IEC958 @@ -59,6 +57,9 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ static long mpu_port[SNDRV_CARDS] = {0x330, [1 ... (SNDRV_CARDS-1)]=-1}; static long fm_port[SNDRV_CARDS] = {0x388, [1 ... (SNDRV_CARDS-1)]=-1}; +#ifdef DO_SOFT_AC3 +static int soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1}; +#endif MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM_DESC(index, "Index value for C-Media PCI soundcard."); @@ -75,6 +76,11 @@ MODULE_PARM(fm_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l"); MODULE_PARM_DESC(fm_port, "FM port."); MODULE_PARM_SYNTAX(fm_port, SNDRV_ENABLED ",allows:{{-1},{0x388},{0x3c8},{0x3e0},{0x3e8}},dialog:list"); +#ifdef DO_SOFT_AC3 +MODULE_PARM(soft_ac3, "1-" __MODULE_STRING(SNDRV_CARDS) "l"); +MODULE_PARM_DESC(soft_ac3, "Sofware-conversion of raw SPDIF packets (model 033 only)."); +MODULE_PARM_SYNTAX(soft_ac3, SNDRV_ENABLED "," SNDRV_BOOLEAN_TRUE_DESC); +#endif #ifndef PCI_DEVICE_ID_CMEDIA_CM8738 #define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111 @@ -366,8 +372,10 @@ #define CM_OPEN_DAC 0x10 #define CM_OPEN_ADC 0x20 #define CM_OPEN_SPDIF 0x40 +#define CM_OPEN_MCHAN 0x80 #define CM_OPEN_PLAYBACK (CM_CH_PLAY | CM_OPEN_DAC) #define CM_OPEN_PLAYBACK2 (CM_CH_CAPT | CM_OPEN_DAC) +#define CM_OPEN_PLAYBACK_MULTI (CM_CH_PLAY | CM_OPEN_DAC | CM_OPEN_MCHAN) #define CM_OPEN_CAPTURE (CM_CH_CAPT | CM_OPEN_ADC) #define CM_OPEN_SPDIF_PLAYBACK (CM_CH_PLAY | CM_OPEN_DAC | CM_OPEN_SPDIF) #define CM_OPEN_SPDIF_CAPTURE (CM_CH_CAPT | CM_OPEN_ADC | CM_OPEN_SPDIF) @@ -419,7 +427,7 @@ // {"IEC958 Out To DAC", 1}, // no longer used {"IEC958 Loop", 0}, }; -#define CM_SAVED_MIXERS (sizeof(cm_saved_mixer)/sizeof(cm_saved_mixer[0])) +#define CM_SAVED_MIXERS ARRAY_SIZE(cm_saved_mixer) struct snd_stru_cmipci { snd_card_t *card; @@ -442,6 +450,7 @@ unsigned int can_ac3_sw: 1; unsigned int can_ac3_hw: 1; unsigned int can_multi_ch: 1; + unsigned int do_soft_ac3: 1; unsigned int spdif_playback_avail: 1; /* spdif ready? */ unsigned int spdif_playback_enabled: 1; /* spdif switch enabled? */ @@ -472,7 +481,6 @@ snd_rawmidi_t *rmidi; spinlock_t reg_lock; - snd_info_entry_t *proc_entry; }; @@ -552,13 +560,12 @@ * calculate frequency */ -static int rates[] = { 5512, 11025, 22050, 44100, 8000, 16000, 32000, 48000 }; -#define RATES (sizeof(rates) / sizeof(rates[0])) +static unsigned int rates[] = { 5512, 11025, 22050, 44100, 8000, 16000, 32000, 48000 }; static unsigned int snd_cmipci_rate_freq(unsigned int rate) { - int i; - for (i = 0; i < RATES; i++) { + unsigned int i; + for (i = 0; i < ARRAY_SIZE(rates); i++) { if (rates[i] == rate) return i; } @@ -638,6 +645,23 @@ return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); } +static int snd_cmipci_playback2_hw_params(snd_pcm_substream_t * substream, + snd_pcm_hw_params_t * hw_params) +{ + cmipci_t *cm = snd_pcm_substream_chip(substream); + if (params_channels(hw_params) > 2) { + down(&cm->open_mutex); + if (cm->opened[CM_CH_PLAY]) { + up(&cm->open_mutex); + return -EBUSY; + } + /* reserve the channel A */ + cm->opened[CM_CH_PLAY] = CM_OPEN_PLAYBACK_MULTI; + up(&cm->open_mutex); + } + return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); +} + static void snd_cmipci_ch_reset(cmipci_t *cm, int ch) { int reset = CM_RST_CH0 << (cm->channel[ch].ch); @@ -741,6 +765,11 @@ rec->period_size = runtime->period_size << rec->shift; rec->dma_size <<= rec->ac3_shift; rec->period_size <<= rec->ac3_shift; + if (runtime->channels > 2) { + /* multi-channels */ + rec->dma_size = (rec->dma_size * runtime->channels) / 2; + rec->period_size = (rec->period_size * runtime->channels) / 2; + } spin_lock_irqsave(&cm->reg_lock, flags); @@ -750,7 +779,7 @@ /* program sample counts */ reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2; snd_cmipci_write_w(cm, reg, rec->dma_size - 1); - snd_cmipci_write_w(cm, reg + 2, rec->period_size); /* FIXME: or period_size-1 ?? */ + snd_cmipci_write_w(cm, reg + 2, rec->period_size - 1); /* set adc/dac flag */ val = rec->ch ? CM_CHADC1 : CM_CHADC0; @@ -862,6 +891,8 @@ ptr = bytes_to_frames(substream->runtime, ptr); #endif ptr >>= rec->ac3_shift; + if (substream->runtime->channels > 2) + ptr = (ptr * 2) / substream->runtime->channels; return ptr; } @@ -1397,7 +1428,7 @@ static void save_mixer_state(cmipci_t *cm) { if (! cm->mixer_insensitive) { - int i; + unsigned int i; for (i = 0; i < CM_SAVED_MIXERS; i++) { snd_kcontrol_t *ctl = cm->mixer_res_ctl[i]; if (ctl) { @@ -1425,7 +1456,7 @@ static void restore_mixer_state(cmipci_t *cm) { if (cm->mixer_insensitive) { - int i; + unsigned int i; cm->mixer_insensitive = 0; /* at first clear this; otherwise the changes will be ignored */ for (i = 0; i < CM_SAVED_MIXERS; i++) { @@ -1781,9 +1812,11 @@ down(&cm->open_mutex); if (cm->opened[ch] == mode) { - snd_cmipci_ch_reset(cm, ch); - cm->channel[ch].running = 0; - cm->channel[ch].substream = NULL; + if (cm->channel[ch].substream) { + snd_cmipci_ch_reset(cm, ch); + cm->channel[ch].running = 0; + cm->channel[ch].substream = NULL; + } cm->opened[ch] = 0; if (! cm->channel[ch].is_dac) { /* enable dual DAC mode again */ @@ -1808,13 +1841,6 @@ if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0) return err; runtime->hw = snd_cmipci_playback; - if (cm->can_multi_ch) { - runtime->hw.channels_max = cm->max_channels; - if (cm->max_channels == 4) - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_4); - else - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_6); - } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); return 0; } @@ -1841,7 +1867,18 @@ if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use channel B */ return err; runtime->hw = snd_cmipci_playback2; - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); + down(&cm->open_mutex); + if (! cm->opened[CM_CH_PLAY]) { + if (cm->can_multi_ch) { + runtime->hw.channels_max = cm->max_channels; + if (cm->max_channels == 4) + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_4); + else + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_6); + } + snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); + } + up(&cm->open_mutex); return 0; } @@ -1898,6 +1935,7 @@ { cmipci_t *cm = snd_pcm_substream_chip(substream); close_device_check(cm, CM_OPEN_PLAYBACK2); + close_device_check(cm, CM_OPEN_PLAYBACK_MULTI); return 0; } @@ -1945,7 +1983,7 @@ .open = snd_cmipci_playback2_open, .close = snd_cmipci_playback2_close, .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_cmipci_hw_params, + .hw_params = snd_cmipci_playback2_hw_params, .hw_free = snd_cmipci_hw_free, .prepare = snd_cmipci_capture_prepare, /* channel B */ .trigger = snd_cmipci_capture_trigger, /* channel B */ @@ -1961,11 +1999,22 @@ .prepare = snd_cmipci_playback_spdif_prepare, /* set up rate */ .trigger = snd_cmipci_playback_trigger, .pointer = snd_cmipci_playback_pointer, +}; + #ifdef DO_SOFT_AC3 +static snd_pcm_ops_t snd_cmipci_playback_spdif_soft_ops = { + .open = snd_cmipci_playback_spdif_open, + .close = snd_cmipci_playback_spdif_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_cmipci_hw_params, + .hw_free = snd_cmipci_playback_hw_free, + .prepare = snd_cmipci_playback_spdif_prepare, /* set up rate */ + .trigger = snd_cmipci_playback_trigger, + .pointer = snd_cmipci_playback_pointer, .copy = snd_cmipci_ac3_copy, .silence = snd_cmipci_ac3_silence, -#endif }; +#endif static snd_pcm_ops_t snd_cmipci_capture_spdif_ops = { .open = snd_cmipci_capture_spdif_open, @@ -2041,7 +2090,14 @@ if (err < 0) return err; +#ifdef DO_SOFT_AC3 + if (cm->can_ac3_hw) + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback_spdif_ops); + else + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback_spdif_soft_ops); +#else snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback_spdif_ops); +#endif snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cmipci_capture_spdif_ops); pcm->private_data = cm; @@ -2637,7 +2693,8 @@ snd_card_t *card; snd_kcontrol_new_t *sw; snd_kcontrol_t *kctl; - int idx, err; + unsigned int idx; + int err; snd_assert(cm != NULL && cm->card != NULL, return -EINVAL); @@ -2746,26 +2803,8 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(cm->card, "cmipci", cm->card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = cm; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 256; - entry->c.text.read = snd_cmipci_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - cm->proc_entry = entry; -} - -static void snd_cmipci_proc_done(cmipci_t *cm) -{ - if (cm->proc_entry) { - snd_info_unregister(cm->proc_entry); - cm->proc_entry = NULL; - } + if (! snd_card_proc_new(cm->card, "cmipci", &entry)) + snd_info_set_text_ops(entry, cm, snd_cmipci_proc_read); } @@ -2795,7 +2834,10 @@ if (! detect) { cm->chip_version = 33; cm->max_channels = 2; - cm->can_ac3_sw = 1; + if (cm->do_soft_ac3) + cm->can_ac3_sw = 1; + else + cm->can_ac3_hw = 1; cm->has_dual_dac = 1; } else { cm->chip_version = 37; @@ -2832,8 +2874,6 @@ static int snd_cmipci_free(cmipci_t *cm) { - snd_cmipci_proc_done(cm); - if (cm->irq >= 0) { snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN); snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT); @@ -2864,11 +2904,8 @@ return snd_cmipci_free(cm); } -static int __devinit snd_cmipci_create(snd_card_t *card, - struct pci_dev *pci, - unsigned long iomidi, - unsigned long iosynth, - cmipci_t **rcmipci) +static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci, + int dev, cmipci_t **rcmipci) { cmipci_t *cm; int err; @@ -2876,8 +2913,10 @@ .dev_free = snd_cmipci_dev_free, }; unsigned int val = 0; + unsigned long iomidi = mpu_port[dev]; + unsigned long iosynth = fm_port[dev]; int pcm_index, pcm_spdif_index; - + *rcmipci = NULL; if ((err = pci_enable_device(pci)) < 0) @@ -2918,6 +2957,9 @@ cm->chip_version = 0; cm->max_channels = 2; +#ifdef DO_SOFT_AC3 + cm->do_soft_ac3 = soft_ac3[dev]; +#endif query_chip(cm); @@ -2949,20 +2991,10 @@ /* Assume TX and compatible chip set (Autodetection required for VX chip sets) */ switch (pci->device) { - struct list_head *pos; - int txvx; case PCI_DEVICE_ID_CMEDIA_CM8738: case PCI_DEVICE_ID_CMEDIA_CM8738B: - txvx = 1; - list_for_each(pos, &(pci->global_list)) { - struct pci_dev * cur = list_entry(pos, struct pci_dev, global_list); - if (cur->vendor != 0x8086) /* PCI_VENDOR_ID_INTEL */ - continue; - if (cur->device != 0x7030) /* PCI_DEVICE_ID_INTEL_82437VX */ - continue; - txvx = 0; - } - if (txvx) + /* PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX */ + if (! pci_find_device(0x8086, 0x7030, NULL)) snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_TXVX); break; default: @@ -3054,7 +3086,7 @@ return err; } #ifdef USE_VAR48KRATE - for (val = 0; val < RATES; val++) + for (val = 0; val < ARRAY_SIZE(rates); val++) snd_cmipci_set_pll(cm, rates[val], val); /* @@ -3109,10 +3141,7 @@ break; } - if ((err = snd_cmipci_create(card, pci, - mpu_port[dev], - fm_port[dev], - &cm)) < 0) { + if ((err = snd_cmipci_create(card, pci, dev, &cm)) < 0) { snd_card_free(card); return err; } diff -Nru a/sound/pci/cs4281.c b/sound/pci/cs4281.c --- a/sound/pci/cs4281.c Sun Feb 9 21:13:36 2003 +++ b/sound/pci/cs4281.c Sun Feb 9 21:13:36 2003 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -35,9 +36,6 @@ #define SNDRV_GET_ID #include -#ifndef LINUX_2_2 -#include -#endif MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Cirrus Logic CS4281"); @@ -501,13 +499,9 @@ unsigned int spurious_dhtc_irq; unsigned int spurious_dtc_irq; - void *proc_entry_BA0; - void *proc_entry_BA1; - spinlock_t reg_lock; unsigned int midcr; unsigned int uartm; - snd_info_entry_t *proc_entry; struct snd_cs4281_gameport *gameport; @@ -1253,55 +1247,19 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(chip->card, "cs4281", chip->card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = chip; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 256; - entry->c.text.read = snd_cs4281_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - chip->proc_entry = entry; - if ((entry = snd_info_create_card_entry(chip->card, "cs4281_BA0", chip->card->proc_root)) != NULL) { + if (! snd_card_proc_new(chip->card, "cs4281", &entry)) + snd_info_set_text_ops(entry, chip, snd_cs4281_proc_read); + if (! snd_card_proc_new(chip->card, "cs4281_BA0", &entry)) { entry->content = SNDRV_INFO_CONTENT_DATA; entry->private_data = chip; entry->c.ops = &snd_cs4281_proc_ops_BA0; entry->size = CS4281_BA0_SIZE; - if (snd_info_register(entry) < 0) { - snd_info_unregister(entry); - entry = NULL; - } } - chip->proc_entry_BA0 = entry; - if ((entry = snd_info_create_card_entry(chip->card, "cs4281_BA1", chip->card->proc_root)) != NULL) { + if (! snd_card_proc_new(chip->card, "cs4281_BA1", &entry)) { entry->content = SNDRV_INFO_CONTENT_DATA; entry->private_data = chip; entry->c.ops = &snd_cs4281_proc_ops_BA1; entry->size = CS4281_BA1_SIZE; - if (snd_info_register(entry) < 0) { - snd_info_unregister(entry); - entry = NULL; - } - } - chip->proc_entry_BA1 = entry; -} - -static void snd_cs4281_proc_done(cs4281_t * chip) -{ - if (chip->proc_entry_BA1) { - snd_info_unregister(chip->proc_entry_BA1); - chip->proc_entry_BA1 = NULL; - } - if (chip->proc_entry_BA0) { - snd_info_unregister(chip->proc_entry_BA0); - chip->proc_entry_BA0 = NULL; - } - if (chip->proc_entry) { - snd_info_unregister(chip->proc_entry); - chip->proc_entry = NULL; } } @@ -1309,7 +1267,7 @@ * joystick support */ -#ifndef LINUX_2_2 +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) typedef struct snd_cs4281_gameport { struct gameport info; @@ -1399,7 +1357,9 @@ gameport_register_port(&gp->info); } -#endif /* !LINUX_2_2 */ +#else +#define snd_cs4281_gameport(chip) /*NOP*/ +#endif /* CONFIG_GAMEPORT || CONFIG_GAMEPORT_MODULE */ /* @@ -1408,13 +1368,12 @@ static int snd_cs4281_free(cs4281_t *chip) { -#ifndef LINUX_2_2 +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) if (chip->gameport) { gameport_unregister_port(&chip->gameport->info); kfree(chip->gameport); } #endif - snd_cs4281_proc_done(chip); if (chip->irq >= 0) synchronize_irq(chip->irq); @@ -2041,9 +2000,7 @@ snd_card_free(card); return err; } -#ifndef LINUX_2_2 snd_cs4281_gameport(chip); -#endif strcpy(card->driver, "CS4281"); strcpy(card->shortname, "Cirrus Logic CS4281"); sprintf(card->longname, "%s at 0x%lx, irq %d", @@ -2097,11 +2054,10 @@ { snd_card_t *card = chip->card; u32 ulCLK; - int i; + unsigned int i; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D3hot) - goto __skip; + return; snd_pcm_suspend_all(chip->pcm); @@ -2134,19 +2090,16 @@ snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - __skip: - snd_power_unlock(card); } static void cs4281_resume(cs4281_t *chip) { snd_card_t *card = chip->card; - int i; + unsigned int i; u32 ulCLK; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D0) - goto __skip; + return; pci_enable_device(chip->pci); @@ -2171,8 +2124,6 @@ snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK); snd_power_change_state(card, SNDRV_CTL_POWER_D0); - __skip: - snd_power_unlock(card); } #ifndef PCI_OLD_SUSPEND diff -Nru a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c --- a/sound/pci/cs46xx/cs46xx_lib.c Sun Feb 9 21:13:28 2003 +++ b/sound/pci/cs46xx/cs46xx_lib.c Sun Feb 9 21:13:28 2003 @@ -26,7 +26,7 @@ * at Cirrus for have helping me out with the DSP, however we * still dont have sufficient documentation and technical * references to be able to implement all fancy feutures - * supported by the cs46xx DPS's. + * supported by the cs46xx DSP's. * Benny * * This program is free software; you can redistribute it and/or modify @@ -52,14 +52,14 @@ #include #include #include +#include #include #include #include +#include +#include #include -#ifndef LINUX_2_2 -#include -#endif #include @@ -273,9 +273,6 @@ unsigned short val) { cs46xx_t *chip = snd_magic_cast(cs46xx_t, ac97->private_data, return); -#ifndef CONFIG_SND_CS46XX_NEW_DSP - int val2 = 0; -#endif int codec_index = -1; /* UGGLY: nr_ac97_codecs == 0 primery codec detection is in progress */ @@ -287,59 +284,9 @@ else snd_assert(0,return); -#ifndef CONFIG_SND_CS46XX_NEW_DSP - if (reg == AC97_CD) - val2 = snd_cs46xx_codec_read(chip, AC97_CD, codec_index); -#endif - + chip->active_ctrl(chip, 1); snd_cs46xx_codec_write(chip, reg, val, codec_index); - -#ifndef CONFIG_SND_CS46XX_NEW_DSP - /* Benny: I've not found *one* soundcard where - this code below could do any sense, and - with the HW mixering it's anyway broken, with - more then 1 PCM stream the amplifier will not - be turned off by unmuting CD channel. So just - lets skip it. - */ - - /* - * Adjust power if the mixer is selected/deselected according - * to the CD. - * - * IF the CD is a valid input source (mixer or direct) AND - * the CD is not muted THEN power is needed - * - * We do two things. When record select changes the input to - * add/remove the CD we adjust the power count if the CD is - * unmuted. - * - * When the CD mute changes we adjust the power level if the - * CD was a valid input. - * - * We also check for CD volume != 0, as the CD mute isn't - * normally tweaked from userspace. - */ - - /* CD mute change ? */ - - /* Benny: this hack dont seems to make any sense to me, at least on the Game Theater XP, - Turning of the amplifier just make the PCM sound very distorcionated. - is this really needed ???????????????? - */ - if (reg == AC97_CD) { - /* Mute bit change ? */ - if ((val2^val)&0x8000 || ((val2 == 0x1f1f || val == 0x1f1f) && val2 != val)) { - /* Mute on */ - if(val&0x8000 || val == 0x1f1f) - chip->amplifier_ctrl(chip, -1); - else /* Mute off power on */ - chip->amplifier_ctrl(chip, 1); - } - } - chip->active_ctrl(chip, -1); -#endif } @@ -732,10 +679,12 @@ snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_sframes_t diff; cs46xx_pcm_t * cpcm; - int buffer_size = runtime->period_size * CS46XX_FRAGS * 4; + int buffer_size; cpcm = snd_magic_cast(cs46xx_pcm_t, substream->runtime->private_data, return -ENXIO); + buffer_size = runtime->period_size * CS46XX_FRAGS << cpcm->shift; + diff = runtime->control->appl_ptr - cpcm->appl_ptr; if (diff) { if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) @@ -749,7 +698,7 @@ size_t hw_to_end = buffer_size - cpcm->hw_data; size_t sw_to_end = cpcm->sw_bufsize - cpcm->sw_data; size_t bytes = buffer_size - cpcm->hw_ready; - if (cpcm->sw_ready < bytes) + if (cpcm->sw_ready < (int)bytes) bytes = cpcm->sw_ready; if (hw_to_end < bytes) bytes = hw_to_end; @@ -759,7 +708,7 @@ runtime->dma_area + cpcm->sw_data, bytes); cpcm->hw_data += bytes; - if (cpcm->hw_data == buffer_size) + if ((int)cpcm->hw_data == buffer_size) cpcm->hw_data = 0; cpcm->sw_data += bytes; if (cpcm->sw_data == cpcm->sw_bufsize) @@ -776,7 +725,7 @@ cs46xx_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_sframes_t diff = runtime->control->appl_ptr - chip->capt.appl_ptr; - int buffer_size = runtime->period_size * CS46XX_FRAGS * 4; + int buffer_size = runtime->period_size * CS46XX_FRAGS << chip->capt.shift; if (diff) { if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2)) diff += runtime->boundary; @@ -785,11 +734,11 @@ chip->capt.sw_ready -= frames << chip->capt.shift; chip->capt.appl_ptr = runtime->control->appl_ptr + frames; while (chip->capt.hw_ready > 0 && - chip->capt.sw_ready < chip->capt.sw_bufsize) { + chip->capt.sw_ready < (int)chip->capt.sw_bufsize) { size_t hw_to_end = buffer_size - chip->capt.hw_data; size_t sw_to_end = chip->capt.sw_bufsize - chip->capt.sw_data; size_t bytes = chip->capt.sw_bufsize - chip->capt.sw_ready; - if (chip->capt.hw_ready < bytes) + if (chip->capt.hw_ready < (int)bytes) bytes = chip->capt.hw_ready; if (hw_to_end < bytes) bytes = hw_to_end; @@ -799,7 +748,7 @@ chip->capt.hw_area + chip->capt.hw_data, bytes); chip->capt.hw_data += bytes; - if (chip->capt.hw_data == buffer_size) + if ((int)chip->capt.hw_data == buffer_size) chip->capt.hw_data = 0; chip->capt.sw_data += bytes; if (chip->capt.sw_data == chip->capt.sw_bufsize) @@ -832,7 +781,7 @@ size_t ptr; cs46xx_pcm_t *cpcm = snd_magic_cast(cs46xx_pcm_t, substream->runtime->private_data, return -ENXIO); ssize_t bytes; - int buffer_size = substream->runtime->period_size * CS46XX_FRAGS * 4; + int buffer_size = substream->runtime->period_size * CS46XX_FRAGS << cpcm->shift; #ifdef CONFIG_SND_CS46XX_NEW_DSP snd_assert (cpcm->pcm_channel,return -ENXIO); @@ -867,7 +816,7 @@ cs46xx_t *chip = snd_pcm_substream_chip(substream); size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_addr; ssize_t bytes = ptr - chip->capt.hw_io; - int buffer_size = substream->runtime->period_size * CS46XX_FRAGS * 4; + int buffer_size = substream->runtime->period_size * CS46XX_FRAGS << chip->capt.shift; if (bytes < 0) bytes += buffer_size; @@ -1044,7 +993,7 @@ cpcm->pcm_channel->sample_rate = sample_rate; } else /* if sample rate is changed */ - if (cpcm->pcm_channel->sample_rate != sample_rate) { + if ((int)cpcm->pcm_channel->sample_rate != sample_rate) { int unlinked = cpcm->pcm_channel->unlinked; cs46xx_dsp_destroy_pcm_channel (chip,cpcm->pcm_channel); @@ -1073,7 +1022,7 @@ int err; cs46xx_t *chip = snd_pcm_substream_chip(substream); int sample_rate = params_rate(hw_params); - int period_size = params_period_size(hw_params); + int period_size = params_period_bytes(hw_params); cpcm = snd_magic_cast(cs46xx_pcm_t, runtime->private_data, return -ENXIO); #ifdef CONFIG_SND_CS46XX_NEW_DSP @@ -1092,12 +1041,15 @@ return -ENXIO; } - if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size * 4)) { + + if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) { up (&chip->spos_mutex); return -EINVAL; } - snd_printdd ("period_size (%d), periods (%d)\n", - period_size, params_periods(hw_params)); + + snd_printdd ("period_size (%d), periods (%d) buffer_size(%d)\n", + period_size, params_periods(hw_params), + params_buffer_bytes(hw_params)); #endif if (params_periods(hw_params) == CS46XX_FRAGS) { @@ -1257,12 +1209,10 @@ cs46xx_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; int err; - int period_size = params_period_size(hw_params); + int period_size = params_period_bytes(hw_params); #ifdef CONFIG_SND_CS46XX_NEW_DSP - snd_printdd ("capture period size (%d)\n",period_size); - - cs46xx_dsp_pcm_ostream_set_period (chip,period_size * 4); + cs46xx_dsp_pcm_ostream_set_period (chip,period_size); #endif if (runtime->periods == CS46XX_FRAGS) { if (runtime->dma_area != chip->capt.hw_area) @@ -1447,7 +1397,7 @@ .fifo_size = 0, }; -static unsigned int period_sizes[] = { 8, 16, 32, 64, 128, 256, 512 }; +static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 }; #define PERIOD_SIZES sizeof(period_sizes) / sizeof(period_sizes[0]) @@ -1490,8 +1440,11 @@ cpcm->pcm_channel = NULL; cpcm->pcm_channel_id = pcm_channel_id; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, + + snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_sizes); + up (&chip->spos_mutex); #else chip->playback_pcm = cpcm; /* HACK */ @@ -1500,7 +1453,6 @@ if (chip->accept_valid) substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; chip->active_ctrl(chip, 1); - chip->amplifier_ctrl(chip, 1); return 0; } @@ -1564,10 +1516,10 @@ substream->runtime->hw.info |= SNDRV_PCM_INFO_MMAP_VALID; chip->active_ctrl(chip, 1); - chip->amplifier_ctrl(chip, 1); #ifdef CONFIG_SND_CS46XX_NEW_DSP - snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_sizes); #endif return 0; @@ -1598,7 +1550,6 @@ cpcm->substream = NULL; snd_free_pci_pages(chip->pci, cpcm->hw_size, cpcm->hw_area, cpcm->hw_addr); chip->active_ctrl(chip, -1); - chip->amplifier_ctrl(chip, -1); return 0; } @@ -1610,7 +1561,6 @@ chip->capt.substream = NULL; snd_free_pci_pages(chip->pci, chip->capt.hw_size, chip->capt.hw_area, chip->capt.hw_addr); chip->active_ctrl(chip, -1); - chip->amplifier_ctrl(chip, -1); return 0; } @@ -2098,7 +2048,7 @@ /* checking diff from the EGPIO direction register should be enough */ - return (val1 != snd_cs46xx_peekBA0(chip, BA0_EGPIODR)); + return (val1 != (int)snd_cs46xx_peekBA0(chip, BA0_EGPIODR)); } @@ -2141,7 +2091,7 @@ (1 << 13) | (1 << 12); - change = ins->spdif_csuv_default != val; + change = (unsigned int)ins->spdif_csuv_default != val; ins->spdif_csuv_default = val; if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) ) @@ -2459,7 +2409,7 @@ ac97_t ac97; snd_ctl_elem_id_t id; int err; - int idx; + unsigned int idx; /* detect primary codec */ chip->nr_ac97_codecs = 0; @@ -2537,17 +2487,10 @@ _end: - /* dosoundcard specific mixer setup */ - if (chip->mixer_init) { - snd_printdd ("calling chip->mixer_init(chip);\n"); - chip->mixer_init(chip); - } - #endif /* CONFIG_SND_CS46XX_NEW_DSP */ /* add cs4630 mixer controls */ - for (idx = 0; idx < sizeof(snd_cs46xx_controls) / - sizeof(snd_cs46xx_controls[0]); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) { snd_kcontrol_t *kctl; kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip); if ((err = snd_ctl_add(card, kctl)) < 0) @@ -2560,6 +2503,17 @@ strcpy(id.name, "External Amplifier Power Down"); chip->eapd_switch = snd_ctl_find_id(chip->card, &id); + /* turn on amplifier */ + chip->amplifier_ctrl(chip, 1); + +#ifdef CONFIG_SND_CS46XX_NEW_DSP + /* do soundcard specific mixer setup */ + if (chip->mixer_init) { + snd_printdd ("calling chip->mixer_init(chip);\n"); + chip->mixer_init(chip); + } +#endif + return 0; } @@ -2740,7 +2694,7 @@ * gameport interface */ -#ifndef LINUX_2_2 +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) typedef struct snd_cs46xx_gameport { struct gameport info; @@ -2824,13 +2778,13 @@ gameport_register_port(&gp->info); } -#else /* LINUX_2_2 */ +#else void __devinit snd_cs46xx_gameport(cs46xx_t *chip) { } -#endif /* !LINUX_2_2 */ +#endif /* CONFIG_GAMEPORT */ /* * proc interface @@ -2843,7 +2797,7 @@ snd_cs46xx_region_t *region = (snd_cs46xx_region_t *)entry->private_data; size = count; - if (file->f_pos + size > region->size) + if (file->f_pos + (size_t)size > region->size) size = region->size - file->f_pos; if (size > 0) { char *tmp; @@ -2876,19 +2830,13 @@ for (idx = 0; idx < 5; idx++) { snd_cs46xx_region_t *region = &chip->region.idx[idx]; - entry = snd_info_create_card_entry(card, region->name, card->proc_root); - if (entry) { + if (! snd_card_proc_new(card, region->name, &entry)) { entry->content = SNDRV_INFO_CONTENT_DATA; entry->private_data = chip; entry->c.ops = &snd_cs46xx_proc_io_ops; entry->size = region->size; entry->mode = S_IFREG | S_IRUSR; - if (snd_info_register(entry) < 0) { - snd_info_unregister(entry); - entry = NULL; - } } - region->proc_entry = entry; } #ifdef CONFIG_SND_CS46XX_NEW_DSP cs46xx_dsp_proc_init(card, chip); @@ -2898,15 +2846,6 @@ static int snd_cs46xx_proc_done(cs46xx_t *chip) { - int idx; - - for (idx = 0; idx < 5; idx++) { - snd_cs46xx_region_t *region = &chip->region.idx[idx]; - if (region->proc_entry) { - snd_info_unregister((snd_info_entry_t *) region->proc_entry); - region->proc_entry = NULL; - } - } #ifdef CONFIG_SND_CS46XX_NEW_DSP cs46xx_dsp_proc_done(chip); #endif @@ -2972,7 +2911,7 @@ if (chip->active_ctrl) chip->active_ctrl(chip, 1); -#ifndef LINUX_2_2 +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) if (chip->gameport) { gameport_unregister_port(&chip->gameport->info); kfree(chip->gameport); @@ -3553,9 +3492,6 @@ { snd_printdd ("initializing Voyetra mixer\n"); - /* turnon Amplifier and leave it on */ - chip->amplifier_ctrl(chip, 1); - /* Enable SPDIF out */ snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0); snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0); @@ -3564,7 +3500,8 @@ static void hercules_mixer_init (cs46xx_t *chip) { #ifdef CONFIG_SND_CS46XX_NEW_DSP - int idx,err; + unsigned int idx; + int err; snd_card_t *card = chip->card; #endif @@ -3574,11 +3511,7 @@ snd_printdd ("initializing Hercules mixer\n"); #ifdef CONFIG_SND_CS46XX_NEW_DSP - /* turnon Amplifier and leave it on */ - chip->amplifier_ctrl(chip, 1); - - for (idx = 0 ; idx < sizeof(snd_hercules_controls) / - sizeof(snd_hercules_controls[0]) ; idx++) { + for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) { snd_kcontrol_t *kctl; kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip); @@ -3692,21 +3625,88 @@ }; static struct cs_card_type __devinitdata cards[] = { - {0x1489, 0x7001, "Genius Soundmaker 128 value", NULL, amp_none, NULL, NULL}, - {0x5053, 0x3357, "Voyetra", NULL, amp_voyetra, NULL, voyetra_mixer_init}, - {0x1071, 0x6003, "Mitac MI6020/21", NULL, amp_voyetra, NULL, NULL}, - {0x14AF, 0x0050, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init}, - {0x1681, 0x0050, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init}, - {0x1681, 0x0051, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init}, - {0x1681, 0x0052, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init}, - {0x1681, 0x0053, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init}, - {0x1681, 0x0054, "Hercules Game Theatre XP", NULL, amp_hercules, NULL, hercules_mixer_init}, + { + .vendor = 0x1489, + .id = 0x7001, + .name = "Genius Soundmaker 128 value", + /* nothing special */ + }, + { + .vendor = 0x5053, + .id = 0x3357, + .name = "Voyetra", + .amp = amp_voyetra, + .mixer_init = voyetra_mixer_init + }, + { + .vendor = 0x1071, + .id = 0x6003, + .name = "Mitac MI6020/21", + .amp = amp_voyetra + }, + { + .vendor = 0x14AF, + .id = 0x0050, + .name = "Hercules Game Theatre XP", + .amp = amp_hercules, + .mixer_init = hercules_mixer_init + }, + { + .vendor = 0x1681, + .id = 0x0050, + .name = "Hercules Game Theatre XP", + .amp = amp_hercules, + .mixer_init = hercules_mixer_init + }, + { + .vendor = 0x1681, + .id = 0x0051, + .name = "Hercules Game Theatre XP", + .amp = amp_hercules, + .mixer_init = hercules_mixer_init + }, + { + .vendor = 0x1681, + .id = 0x0052, + .name = "Hercules Game Theatre XP", + .amp = amp_hercules, + .mixer_init = hercules_mixer_init + }, + { + .vendor = 0x1681, + .id = 0x0053, + .name = "Hercules Game Theatre XP", + .amp = amp_hercules, + .mixer_init = hercules_mixer_init + }, + { + .vendor = 0x1681, + .id = 0x0054, + .name = "Hercules Game Theatre XP", + .amp = amp_hercules, + .mixer_init = hercules_mixer_init + }, /* Not sure if the 570 needs the clkrun hack */ - {PCI_VENDOR_ID_IBM, 0x0132, "Thinkpad 570", clkrun_init, NULL, clkrun_hack, NULL}, - {PCI_VENDOR_ID_IBM, 0x0153, "Thinkpad 600X/A20/T20", clkrun_init, NULL, clkrun_hack, NULL}, - {PCI_VENDOR_ID_IBM, 0x1010, "Thinkpad 600E (unsupported)", NULL, NULL, NULL, NULL}, - {0, 0, "Card without SSID set", NULL, NULL, NULL, NULL }, - {0, 0, NULL, NULL, NULL, NULL, NULL} + { + .vendor = PCI_VENDOR_ID_IBM, + .id = 0x0132, + .name = "Thinkpad 570", + .init = clkrun_init, + .active = clkrun_hack + }, + { + .vendor = PCI_VENDOR_ID_IBM, + .id = 0x0153, + .name = "Thinkpad 600X/A20/T20", + .init = clkrun_init, + .active = clkrun_hack + }, + { + .vendor = PCI_VENDOR_ID_IBM, + .id = 0x1010, + .name = "Thinkpad 600E (unsupported)" + }, + {} /* terminator */ }; @@ -3716,18 +3716,23 @@ #ifdef CONFIG_PM void snd_cs46xx_suspend(cs46xx_t *chip) { + int amp_saved; + snd_card_t *card = chip->card; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D3hot) - goto __skip; + return; snd_pcm_suspend_all(chip->pcm); // chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL); // chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE); + amp_saved = chip->amplifier; + /* turn off amp */ + chip->amplifier_ctrl(chip, -chip->amplifier); snd_cs46xx_hw_stop(chip); + /* disable CLKRUN */ + chip->active_ctrl(chip, -chip->amplifier); + chip->amplifier = amp_saved; /* restore the status */ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - __skip: - snd_power_unlock(card); } void snd_cs46xx_resume(cs46xx_t *chip) @@ -3735,9 +3740,8 @@ snd_card_t *card = chip->card; int amp_saved; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D0) - goto __skip; + return; pci_enable_device(chip->pci); amp_saved = chip->amplifier; @@ -3760,14 +3764,11 @@ snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); if (amp_saved) - chip->amplifier_ctrl(chip, 1); /* try to turn on */ - if (! amp_saved) { - chip->amplifier = 1; - chip->active_ctrl(chip, -1); - } + chip->amplifier_ctrl(chip, 1); /* turn amp on */ + else + chip->active_ctrl(chip, -1); /* disable CLKRUN */ + chip->amplifier = amp_saved; snd_power_change_state(card, SNDRV_CTL_POWER_D0); - __skip: - snd_power_unlock(card); } static int snd_cs46xx_set_power_state(snd_card_t *card, unsigned int power_state) @@ -3828,8 +3829,8 @@ chip->irq = -1; chip->ba0_addr = pci_resource_start(pci, 0); chip->ba1_addr = pci_resource_start(pci, 1); - if (chip->ba0_addr == 0 || chip->ba0_addr == ~0 || - chip->ba1_addr == 0 || chip->ba1_addr == ~0) { + if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 || + chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) { snd_cs46xx_free(chip); snd_printk("wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr); return -ENOMEM; @@ -3867,11 +3868,11 @@ for (cp = &cards[0]; cp->name; cp++) { if (cp->vendor == ss_vendor && cp->id == ss_card) { snd_printd ("hack for %s enabled\n", cp->name); - if (cp->init) - cp->init(chip); chip->amplifier_ctrl = cp->amp; chip->active_ctrl = cp->active; chip->mixer_init = cp->mixer_init; + if (cp->init) + cp->init(chip); break; } } @@ -3892,27 +3893,27 @@ if (chip->active_ctrl == NULL) chip->active_ctrl = amp_none; - chip->active_ctrl(chip, 1); + chip->active_ctrl(chip, 1); /* enable CLKRUN */ pci_set_master(pci); for (idx = 0; idx < 5; idx++) { region = &chip->region.idx[idx]; if ((region->resource = request_mem_region(region->base, region->size, region->name)) == NULL) { - snd_cs46xx_free(chip); snd_printk("unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1); + snd_cs46xx_free(chip); return -EBUSY; } region->remap_addr = (unsigned long) ioremap_nocache(region->base, region->size); if (region->remap_addr == 0) { - snd_cs46xx_free(chip); snd_printk("%s ioremap problem\n", region->name); + snd_cs46xx_free(chip); return -ENOMEM; } } if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS46XX", (void *) chip)) { - snd_cs46xx_free(chip); snd_printk("unable to grab IRQ %d\n", pci->irq); + snd_cs46xx_free(chip); return -EBUSY; } chip->irq = pci->irq; @@ -3943,7 +3944,7 @@ return err; } - chip->active_ctrl(chip, -1); + chip->active_ctrl(chip, -1); /* disable CLKRUN */ *rchip = chip; return 0; diff -Nru a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c --- a/sound/pci/cs46xx/dsp_spos.c Sun Feb 9 21:13:35 2003 +++ b/sound/pci/cs46xx/dsp_spos.c Sun Feb 9 21:13:35 2003 @@ -54,7 +54,7 @@ static int shadow_and_reallocate_code (cs46xx_t * chip,u32 * data,u32 size, u32 overlay_begin_address) { - int i = 0,j, nreallocated = 0; + unsigned int i = 0, j, nreallocated = 0; u32 hival,loval,address; u32 mop_operands,mop_type,wide_op; dsp_spos_instance_t * ins = chip->dsp_spos_instance; @@ -569,7 +569,7 @@ { cs46xx_t *chip = snd_magic_cast(cs46xx_t, entry->private_data, return); /*dsp_spos_instance_t * ins = chip->dsp_spos_instance; */ - int i,col = 0; + unsigned int i,col = 0; unsigned long dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET; symbol_entry_t * symbol; @@ -585,7 +585,7 @@ } if (col == 0) { - snd_iprintf(buffer, "%04X ",i / sizeof(u32)); + snd_iprintf(buffer, "%04X ", i / (unsigned int)sizeof(u32)); } snd_iprintf(buffer,"%08X ",readl(dst + i)); diff -Nru a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c Sun Feb 9 21:13:36 2003 +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c Sun Feb 9 21:13:36 2003 @@ -162,7 +162,7 @@ static void _dsp_clear_sample_buffer (cs46xx_t *chip, u32 sample_buffer_addr, int dword_count) { - u32 dst = chip->region.idx[2].remap_addr + sample_buffer_addr; + unsigned long dst = chip->region.idx[2].remap_addr + sample_buffer_addr; int i; for (i = 0; i < dword_count ; ++i ) { diff -Nru a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile --- a/sound/pci/emu10k1/Makefile Sun Feb 9 21:13:31 2003 +++ b/sound/pci/emu10k1/Makefile Sun Feb 9 21:13:31 2003 @@ -3,15 +3,19 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := emu10k1_main.o - snd-emu10k1-objs := emu10k1.o emu10k1_main.o \ irq.o memory.o voice.o emumpu401.o emupcm.o io.o \ emuproc.o emumixer.o emufx.o snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o +# +# this function returns: +# "m" - CONFIG_SND_SEQUENCER is m +# - CONFIG_SND_SEQUENCER is undefined +# otherwise parameter #1 value +# +sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) + # Toplevel Module Dependency obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1.o -ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y) - obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1-synth.o -endif +obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-emu10k1-synth.o diff -Nru a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c --- a/sound/pci/emu10k1/emu10k1.c Sun Feb 9 21:13:28 2003 +++ b/sound/pci/emu10k1/emu10k1.c Sun Feb 9 21:13:28 2003 @@ -80,6 +80,7 @@ static struct pci_device_id snd_emu10k1_ids[] __devinitdata = { { 0x1102, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* EMU10K1 */ + { 0x1102, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Dell OEM version (EMU10K1) */ { 0x1102, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy */ { 0, } }; @@ -181,7 +182,7 @@ strcpy(card->driver, "EMU10K1"); strcpy(card->shortname, "Sound Blaster Live!"); } - sprintf(card->longname, "%s at 0x%lx, irq %i", card->shortname, emu->port, emu->irq); + sprintf(card->longname, "%s (rev.%d) at 0x%lx, irq %i", card->shortname, emu->revision, emu->port, emu->irq); if ((err = snd_card_register(card)) < 0) { snd_card_free(card); diff -Nru a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c --- a/sound/pci/emu10k1/emu10k1_main.c Sun Feb 9 21:13:36 2003 +++ b/sound/pci/emu10k1/emu10k1_main.c Sun Feb 9 21:13:36 2003 @@ -161,6 +161,26 @@ SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT); + + if (emu->audigy && emu->revision == 4) { /* audigy2 */ + /* Hacks for Alice3 to work independent of haP16V driver */ + u32 tmp; + + //Setup SRCMulti_I2S SamplingRate + tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); + tmp &= 0xfffff1ff; + tmp |= (0x2<<9); + snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp); + + /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */ + outl(0x600000, emu->port + 0x20); + outl(0x14, emu->port + 0x24); + + /* Setup SRCMulti Input Audio Enable */ + outl(0x6E0000, emu->port + 0x20); + outl(0xFF00FF00, emu->port + 0x24); + } + /* * Clear page with silence & setup all pointers to this page */ @@ -185,9 +205,15 @@ * Lock Sound Memory = 0 * Auto Mute = 1 */ - if (emu->audigy) - outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); - else if (emu->model == 0x20 || + if (emu->audigy) { + if (emu->revision == 4) /* audigy2 */ + outl(HCFG_AUDIOENABLE | + HCFG_AC3ENABLE_CDSPDIF | + HCFG_AC3ENABLE_GPSPDIF | + HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); + else + outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); + } else if (emu->model == 0x20 || emu->model == 0xc400 || (emu->model == 0x21 && emu->revision < 6)) outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG); @@ -221,9 +247,17 @@ outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG); /* Enable analog/digital outs on audigy */ - if (emu->audigy) + if (emu->audigy) { outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); - + + if (emu->revision == 4) { /* audigy2 */ + /* Unmute Analog now. Set GPO6 to 1 for Apollo. + * This has to be done after init ALice3 I2SOut beyond 48KHz. + * So, sequence is important. */ + outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG); + } + } + #if 0 { unsigned int tmp; @@ -494,7 +528,6 @@ static int snd_emu10k1_free(emu10k1_t *emu) { - snd_emu10k1_proc_done(emu); if (emu->res_port != NULL) { /* avoid access to already used hardware */ snd_emu10k1_fx8010_tram_setup(emu, 0); snd_emu10k1_done(emu); diff -Nru a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c --- a/sound/pci/emu10k1/emufx.c Sun Feb 9 21:13:32 2003 +++ b/sound/pci/emu10k1/emufx.c Sun Feb 9 21:13:32 2003 @@ -329,7 +329,7 @@ emu10k1_t *emu = snd_kcontrol_chip(kcontrol); snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value; unsigned long flags; - int i; + unsigned int i; spin_lock_irqsave(&emu->reg_lock, flags); for (i = 0; i < ctl->vcount; i++) @@ -344,7 +344,8 @@ snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value; unsigned long flags; unsigned int nval, val; - int i, j, change = 0; + unsigned int i, j; + int change = 0; spin_lock_irqsave(&emu->reg_lock, flags); for (i = 0; i < ctl->vcount; i++) { @@ -572,7 +573,7 @@ { emu10k1_t *emu = snd_pcm_substream_chip(substream); snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; - int i; + unsigned int i; for (i = 0; i < pcm->channels; i++) snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, 0); @@ -585,7 +586,7 @@ emu10k1_t *emu = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number]; - int i; + unsigned int i; // printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2); pcm->sw_data = pcm->sw_io = pcm->sw_ready = 0; @@ -914,7 +915,7 @@ static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { - int i; + unsigned int i; snd_ctl_elem_id_t *_id, id; emu10k1_fx8010_control_gpr_t *_gctl, gctl; @@ -958,7 +959,7 @@ static void snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { - int i, j; + unsigned int i, j; emu10k1_fx8010_control_gpr_t *_gctl, gctl; snd_emu10k1_fx8010_ctl_t *ctl, nctl; snd_kcontrol_new_t knew; @@ -1020,7 +1021,7 @@ static void snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { - int i; + unsigned int i; snd_ctl_elem_id_t *_id, id; snd_emu10k1_fx8010_ctl_t *ctl; @@ -1036,7 +1037,7 @@ static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode) { - int i = 0, j; + unsigned int i = 0, j; unsigned int total = 0; emu10k1_fx8010_control_gpr_t *_gctl, gctl; snd_emu10k1_fx8010_ctl_t *ctl; @@ -1123,7 +1124,8 @@ static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm) { - int err = 0, i; + unsigned int i; + int err = 0; snd_emu10k1_fx8010_pcm_t *pcm; if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT) @@ -1167,7 +1169,8 @@ static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm) { - int err = 0, i; + unsigned int i; + int err = 0; snd_emu10k1_fx8010_pcm_t *pcm; if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT) diff -Nru a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c --- a/sound/pci/emu10k1/emupcm.c Sun Feb 9 21:13:28 2003 +++ b/sound/pci/emu10k1/emupcm.c Sun Feb 9 21:13:28 2003 @@ -359,13 +359,13 @@ if ((err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params))) < 0) return err; - if ((err = snd_pcm_sgbuf_alloc(substream, params_buffer_bytes(hw_params))) < 0) + if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) return err; if (err > 0) { /* change */ snd_util_memblk_t *memblk; if (epcm->memblk != NULL) snd_emu10k1_free_pages(emu, epcm->memblk); - memblk = snd_emu10k1_alloc_pages(emu, (struct snd_sg_buf *)substream->dma_private); + memblk = snd_emu10k1_alloc_pages(emu, substream); if ((epcm->memblk = memblk) == NULL || ((emu10k1_memblk_t *)memblk)->mapped_page < 0) { epcm->start_addr = 0; return -ENOMEM; @@ -401,7 +401,7 @@ epcm->memblk = NULL; epcm->start_addr = 0; } - snd_pcm_sgbuf_free(substream); + snd_pcm_lib_free_pages(substream); return 0; } @@ -784,10 +784,6 @@ runtime->private_data = epcm; runtime->private_free = snd_emu10k1_pcm_free_substream; runtime->hw = snd_emu10k1_playback; - if ((err = snd_pcm_sgbuf_init(substream, emu->pci, 32)) < 0) { - snd_magic_kfree(epcm); - return err; - } if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) { snd_magic_kfree(epcm); return err; @@ -814,7 +810,6 @@ emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[substream->number]; mix->epcm = NULL; - snd_pcm_sgbuf_delete(substream); snd_emu10k1_pcm_mixer_notify(emu->card, mix, 0); return 0; } @@ -953,8 +948,6 @@ .prepare = snd_emu10k1_playback_prepare, .trigger = snd_emu10k1_playback_trigger, .pointer = snd_emu10k1_playback_pointer, - .copy = snd_pcm_sgbuf_ops_copy_playback, - .silence = snd_pcm_sgbuf_ops_silence, .page = snd_pcm_sgbuf_ops_page, }; @@ -999,9 +992,12 @@ strcpy(pcm->name, "EMU10K1"); emu->pcm = pcm; + for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next) + if ((err = snd_pcm_lib_preallocate_sg_pages(emu->pci, substream)) < 0) + return err; + for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next) snd_pcm_lib_preallocate_pci_pages(emu->pci, substream, 64*1024, 64*1024); - return err; if (rpcm) *rpcm = pcm; diff -Nru a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c --- a/sound/pci/emu10k1/emuproc.c Sun Feb 9 21:13:30 2003 +++ b/sound/pci/emu10k1/emuproc.c Sun Feb 9 21:13:30 2003 @@ -239,111 +239,43 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(emu->card, "emu10k1", emu->card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = emu; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 4096; - entry->c.text.read = snd_emu10k1_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - emu->proc_entry = entry; - entry = NULL; - if ((entry = snd_info_create_card_entry(emu->card, "fx8010_gpr", emu->card->proc_root)) != NULL) { + if (! snd_card_proc_new(emu->card, "emu10k1", &entry)) + snd_info_set_text_ops(entry, emu, snd_emu10k1_proc_read); + + if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) { entry->content = SNDRV_INFO_CONTENT_DATA; entry->private_data = emu; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; + entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; entry->size = TOTAL_SIZE_GPR; entry->c.ops = &snd_emu10k1_proc_ops_fx8010; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } } - emu->proc_entry_fx8010_gpr = entry; - entry = NULL; - if (!emu->audigy && (entry = snd_info_create_card_entry(emu->card, "fx8010_tram_data", emu->card->proc_root)) != NULL) { + if (!emu->audigy && ! snd_card_proc_new(emu->card, "fx8010_tram_data", &entry)) { entry->content = SNDRV_INFO_CONTENT_DATA; entry->private_data = emu; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; + entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; entry->size = TOTAL_SIZE_TANKMEM_DATA; entry->c.ops = &snd_emu10k1_proc_ops_fx8010; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } } - emu->proc_entry_fx8010_tram_data = entry; - entry = NULL; - if (!emu->audigy && (entry = snd_info_create_card_entry(emu->card, "fx8010_tram_addr", emu->card->proc_root)) != NULL) { + if (!emu->audigy && ! snd_card_proc_new(emu->card, "fx8010_tram_addr", &entry)) { entry->content = SNDRV_INFO_CONTENT_DATA; entry->private_data = emu; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; + entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; entry->size = TOTAL_SIZE_TANKMEM_ADDR; entry->c.ops = &snd_emu10k1_proc_ops_fx8010; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } } - emu->proc_entry_fx8010_tram_addr = entry; - entry = NULL; - if ((entry = snd_info_create_card_entry(emu->card, "fx8010_code", emu->card->proc_root)) != NULL) { + if (! snd_card_proc_new(emu->card, "fx8010_code", &entry)) { entry->content = SNDRV_INFO_CONTENT_DATA; entry->private_data = emu; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; + entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; entry->size = TOTAL_SIZE_CODE; entry->c.ops = &snd_emu10k1_proc_ops_fx8010; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } } - emu->proc_entry_fx8010_code = entry; - entry = NULL; - if ((entry = snd_info_create_card_entry(emu->card, "fx8010_acode", emu->card->proc_root)) != NULL) { + if (! snd_card_proc_new(emu->card, "fx8010_acode", &entry)) { entry->content = SNDRV_INFO_CONTENT_TEXT; entry->private_data = emu; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; + entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/; entry->c.text.read_size = 64*1024; entry->c.text.read = snd_emu10k1_proc_acode_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - emu->proc_entry_fx8010_iblocks = entry; - return 0; -} - -int snd_emu10k1_proc_done(emu10k1_t * emu) -{ - if (emu->proc_entry) { - snd_info_unregister(emu->proc_entry); - emu->proc_entry = NULL; - } - if (emu->proc_entry_fx8010_gpr) { - snd_info_unregister(emu->proc_entry_fx8010_gpr); - emu->proc_entry_fx8010_gpr = NULL; - } - if (emu->proc_entry_fx8010_tram_data) { - snd_info_unregister(emu->proc_entry_fx8010_tram_data); - emu->proc_entry_fx8010_tram_data = NULL; - } - if (emu->proc_entry_fx8010_tram_addr) { - snd_info_unregister(emu->proc_entry_fx8010_tram_addr); - emu->proc_entry_fx8010_tram_addr = NULL; - } - if (emu->proc_entry_fx8010_code) { - snd_info_unregister(emu->proc_entry_fx8010_code); - emu->proc_entry_fx8010_code = NULL; - } - if (emu->proc_entry_fx8010_iblocks) { - snd_info_unregister(emu->proc_entry_fx8010_iblocks); - emu->proc_entry_fx8010_iblocks = NULL; } return 0; } diff -Nru a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c --- a/sound/pci/emu10k1/memory.c Sun Feb 9 21:13:35 2003 +++ b/sound/pci/emu10k1/memory.c Sun Feb 9 21:13:35 2003 @@ -25,6 +25,7 @@ #include #include #include +#include /* page arguments of these two macros are Emu page (4096 bytes), not like * aligned pages in others @@ -288,8 +289,9 @@ * page allocation for DMA */ snd_util_memblk_t * -snd_emu10k1_alloc_pages(emu10k1_t *emu, struct snd_sg_buf *sgbuf) +snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream) { + struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, _snd_pcm_substream_sgbuf(substream), return NULL); snd_util_memhdr_t *hdr; emu10k1_memblk_t *blk; int page, err, idx; @@ -306,7 +308,7 @@ return NULL; } /* fill buffer addresses but pointers are not stored so that - * snd_free_pci_pages() is not called in in synth_free() + * snd_free_pci_page() is not called in in synth_free() */ idx = 0; for (page = blk->first_page; page <= blk->last_page; page++, idx++) { @@ -430,11 +432,11 @@ get_single_page_range(emu->memhdr, blk, &first_page, &last_page); /* allocate kernel pages */ for (page = first_page; page <= last_page; page++) { - ptr = snd_malloc_pci_pages(emu->pci, PAGE_SIZE, &addr); + ptr = snd_malloc_pci_page(emu->pci, &addr); if (ptr == NULL) goto __fail; if (! is_valid_page(addr)) { - snd_free_pci_pages(emu->pci, PAGE_SIZE, ptr, addr); + snd_free_pci_page(emu->pci, ptr, addr); goto __fail; } emu->page_addr_table[page] = addr; @@ -446,7 +448,7 @@ /* release allocated pages */ last_page = page - 1; for (page = first_page; page <= last_page; page++) { - snd_free_pci_pages(emu->pci, PAGE_SIZE, emu->page_ptr_table[page], emu->page_addr_table[page]); + snd_free_pci_page(emu->pci, emu->page_ptr_table[page], emu->page_addr_table[page]); emu->page_addr_table[page] = 0; emu->page_ptr_table[page] = NULL; } @@ -464,7 +466,7 @@ get_single_page_range(emu->memhdr, blk, &first_page, &last_page); for (page = first_page; page <= last_page; page++) { if (emu->page_ptr_table[page]) - snd_free_pci_pages(emu->pci, PAGE_SIZE, emu->page_ptr_table[page], emu->page_addr_table[page]); + snd_free_pci_page(emu->pci, emu->page_ptr_table[page], emu->page_addr_table[page]); emu->page_addr_table[page] = 0; emu->page_ptr_table[page] = NULL; } diff -Nru a/sound/pci/ens1370.c b/sound/pci/ens1370.c --- a/sound/pci/ens1370.c Sun Feb 9 21:13:35 2003 +++ b/sound/pci/ens1370.c Sun Feb 9 21:13:35 2003 @@ -150,6 +150,9 @@ #define ES_REG_STATUS 0x04 /* R/O: Interrupt/Chip select status register */ #define ES_INTR (1<<31) /* Interrupt is pending */ #define ES_1371_ST_AC97_RST (1<<29) /* CT5880 AC'97 Reset bit */ +#define ES_1373_REAR_BIT27 (1<<27) /* rear bits: 000 - front, 010 - mirror, 101 - separate */ +#define ES_1373_REAR_BIT26 (1<<26) +#define ES_1373_REAR_BIT24 (1<<24) #define ES_1373_GPIO_INT_EN(o)(((o)&0x0f)<<20)/* GPIO [3:0] pins - interrupt enable */ #define ES_1373_SPDIF_EN (1<<18) /* SPDIF enable */ #define ES_1373_SPDIF_TEST (1<<17) /* SPDIF test */ @@ -398,15 +401,15 @@ unsigned int spdif_default; unsigned int spdif_stream; - snd_info_entry_t *proc_entry; - #ifdef CHIP1370 unsigned char *bugbuf; dma_addr_t bugbuf_addr; #endif +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) struct gameport gameport; struct semaphore joy_sem; // gameport configuration semaphore +#endif }; static void snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -1197,7 +1200,11 @@ if (err < 0) return err; +#ifdef CHIP1370 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops); +#else + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops); +#endif snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ensoniq_capture_ops); pcm->private_data = ensoniq; @@ -1239,8 +1246,11 @@ if (err < 0) return err; +#ifdef CHIP1370 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback1_ops); - +#else + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops); +#endif pcm->private_data = ensoniq; pcm->private_free = snd_ensoniq_pcm_free2; pcm->info_flags = 0; @@ -1262,9 +1272,10 @@ * Mixer section */ +/* + * ENS1371 mixer (including SPDIF interface) + */ #ifdef CHIP1371 - - static int snd_ens1373_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; @@ -1421,6 +1432,53 @@ static snd_kcontrol_new_t snd_es1371_mixer_spdif __devinitdata = ES1371_SPDIF("IEC958 Playback Switch"); +static int snd_es1373_rear_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int snd_es1373_rear_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +{ + ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); + int val = 0; + + spin_lock_irq(&ensoniq->reg_lock); + if ((ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) == ES_1373_REAR_BIT26) + val = 1; + ucontrol->value.integer.value[0] = val; + spin_unlock_irq(&ensoniq->reg_lock); + return 0; +} + +static int snd_es1373_rear_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) +{ + ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); + unsigned int nval1; + int change; + + nval1 = ucontrol->value.integer.value[0] ? ES_1373_REAR_BIT26 : (ES_1373_REAR_BIT27|ES_1373_REAR_BIT24); + spin_lock_irq(&ensoniq->reg_lock); + change = (ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) != nval1; + ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24); + ensoniq->cssr |= nval1; + outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); + spin_unlock_irq(&ensoniq->reg_lock); + return change; +} + +static snd_kcontrol_new_t snd_ens1373_rear __devinitdata = +{ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "AC97 2ch->4ch Copy Switch", + .info = snd_es1373_rear_info, + .get = snd_es1373_rear_get, + .put = snd_es1373_rear_put, +}; + static void snd_ensoniq_mixer_free_ac97(ac97_t *ac97) { ensoniq_t *ensoniq = snd_magic_cast(ensoniq_t, ac97->private_data, return); @@ -1431,7 +1489,7 @@ unsigned short vid; /* vendor ID */ unsigned short did; /* device ID */ unsigned char rev; /* revision */ -} __devinitdata es1371_spdif_present[] = { +} es1371_spdif_present[] __devinitdata = { { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C }, { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D }, { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E }, @@ -1483,11 +1541,19 @@ snd_ctl_add(card, kctl); break; } + if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SDAC) { + /* mirror rear to front speakers */ + ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT24); + ensoniq->cssr |= ES_1373_REAR_BIT26; + snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_rear, ensoniq)); + } return 0; } #endif /* CHIP1371 */ +/* generic control callbacks for ens1370 and for joystick */ +#if defined(CHIP1370) || defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) #define ENSONIQ_CONTROL(xname, mask) \ { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_ensoniq_control_info, \ .get = snd_ensoniq_control_get, .put = snd_ensoniq_control_put, \ @@ -1515,7 +1581,6 @@ } #ifdef CHIP1370 - static int snd_ensoniq_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) { ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol); @@ -1533,14 +1598,21 @@ spin_unlock_irqrestore(&ensoniq->reg_lock, flags); return change; } +#endif /* CHIP1370 */ +#endif /* CHIP1370 || GAMEPORT */ -#define ES1370_CONTROLS 2 +/* + * ENS1370 mixer + */ +#ifdef CHIP1370 static snd_kcontrol_new_t snd_es1370_controls[2] __devinitdata = { ENSONIQ_CONTROL("PCM 0 Output also on Line-In Jack", ES_1370_XCTL0), ENSONIQ_CONTROL("Mic +5V bias", ES_1370_XCTL1) }; +#define ES1370_CONTROLS ARRAY_SIZE(snd_es1370_controls) + static void snd_ensoniq_mixer_free_ak4531(ak4531_t *ak4531) { ensoniq_t *ensoniq = snd_magic_cast(ensoniq_t, ak4531->private_data, return); @@ -1551,7 +1623,8 @@ { snd_card_t *card = ensoniq->card; ak4531_t ak4531; - int err, idx; + unsigned int idx; + int err; /* try reset AK4531 */ outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x02), ES_REG(ensoniq, 1370_CODEC)); @@ -1576,6 +1649,7 @@ * General Switches... */ +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) /* MQ: gameport driver connectivity */ #define ENSONIQ_JOY_CONTROL(xname, mask) \ { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = xname, .info = snd_ensoniq_control_info, \ @@ -1584,7 +1658,7 @@ static int snd_ensoniq_joy_enable(ensoniq_t *ensoniq) { - static int last_jiffies = 0; + static unsigned long last_jiffies = 0; unsigned long flags; if (!request_region(ensoniq->gameport.io, 8, "ens137x: gameport")) { @@ -1693,6 +1767,7 @@ ES1371_JOYSTICK_ADDR("Joystick Address"); #endif /* CHIP1371 */ +#endif /* CONFIG_GAMEPORT */ /* @@ -1721,26 +1796,8 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(ensoniq->card, "audiopci", ensoniq->card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = ensoniq; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 256; - entry->c.text.read = snd_ensoniq_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - ensoniq->proc_entry = entry; -} - -static void snd_ensoniq_proc_done(ensoniq_t * ensoniq) -{ - if (ensoniq->proc_entry) { - snd_info_unregister(ensoniq->proc_entry); - ensoniq->proc_entry = NULL; - } + if (! snd_card_proc_new(ensoniq->card, "audiopci", &entry)) + snd_info_set_text_ops(entry, ensoniq, snd_ensoniq_proc_read); } /* @@ -1749,9 +1806,10 @@ static int snd_ensoniq_free(ensoniq_t *ensoniq) { +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) if (ensoniq->ctrl & ES_JYSTK_EN) snd_ensoniq_joy_disable(ensoniq); - snd_ensoniq_proc_done(ensoniq); +#endif if (ensoniq->irq < 0) goto __hw_end; #ifdef CHIP1370 @@ -1831,7 +1889,6 @@ if (ensoniq == NULL) return -ENOMEM; spin_lock_init(&ensoniq->reg_lock); - init_MUTEX(&ensoniq->joy_sem); ensoniq->card = card; ensoniq->pci = pci; ensoniq->irq = -1; @@ -1946,11 +2003,14 @@ outb(ensoniq->uartc = 0x00, ES_REG(ensoniq, UART_CONTROL)); outb(0x00, ES_REG(ensoniq, UART_RES)); outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) + init_MUTEX(&ensoniq->joy_sem); #ifdef CHIP1371 snd_ctl_add(card, snd_ctl_new1(&snd_es1371_joystick_addr, ensoniq)); #endif snd_ctl_add(card, snd_ctl_new1(&snd_ensoniq_control_joystick, ensoniq)); ensoniq->gameport.io = 0x200; // FIXME: is ES1371 configured like this above ? +#endif synchronize_irq(ensoniq->irq); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) { diff -Nru a/sound/pci/es1938.c b/sound/pci/es1938.c --- a/sound/pci/es1938.c Sun Feb 9 21:13:34 2003 +++ b/sound/pci/es1938.c Sun Feb 9 21:13:34 2003 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -59,9 +60,6 @@ #include #define SNDRV_GET_ID #include -#ifndef LINUX_2_2 -#include -#endif #include @@ -204,8 +202,6 @@ typedef struct _snd_es1938 es1938_t; struct _snd_es1938 { - unsigned long dma1size; - unsigned long dma2size; int irq; unsigned long io_port; @@ -248,7 +244,7 @@ spinlock_t mixer_lock; snd_info_entry_t *proc_entry; -#ifndef LINUX_2_2 +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) struct gameport gameport; #endif }; @@ -842,6 +838,25 @@ return 0; } +/* + * buffer management + */ +static int snd_es1938_pcm_hw_params(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t * hw_params) + +{ + int err; + + if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) + return err; + return 0; +} + +static int snd_es1938_pcm_hw_free(snd_pcm_substream_t *substream) +{ + return snd_pcm_lib_free_pages(substream); +} + /* ---------------------------------------------------------------------- * Audio1 Capture (ADC) * ----------------------------------------------------------------------*/ @@ -892,8 +907,6 @@ if (chip->playback2_substream) return -EAGAIN; - if ((runtime->dma_area = snd_malloc_pci_pages_fallback(chip->pci, chip->dma2size, &runtime->dma_addr, &runtime->dma_bytes)) == NULL) - return -ENOMEM; chip->capture_substream = substream; runtime->hw = snd_es1938_capture; snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, @@ -909,15 +922,11 @@ switch (substream->number) { case 0: - if ((runtime->dma_area = snd_malloc_pci_pages_fallback(chip->pci, chip->dma1size, &runtime->dma_addr, &runtime->dma_bytes)) == NULL) - return -ENOMEM; chip->playback1_substream = substream; break; case 1: if (chip->capture_substream) return -EAGAIN; - if ((runtime->dma_area = snd_malloc_pci_pages_fallback(chip->pci, chip->dma1size, &runtime->dma_addr, &runtime->dma_bytes)) == NULL) - return -ENOMEM; chip->playback2_substream = substream; break; default: @@ -965,6 +974,8 @@ .open = snd_es1938_playback_open, .close = snd_es1938_playback_close, .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_es1938_pcm_hw_params, + .hw_free = snd_es1938_pcm_hw_free, .prepare = snd_es1938_playback_prepare, .trigger = snd_es1938_playback_trigger, .pointer = snd_es1938_playback_pointer, @@ -974,6 +985,8 @@ .open = snd_es1938_capture_open, .close = snd_es1938_capture_close, .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_es1938_pcm_hw_params, + .hw_free = snd_es1938_pcm_hw_free, .prepare = snd_es1938_capture_prepare, .trigger = snd_es1938_capture_trigger, .pointer = snd_es1938_capture_pointer, @@ -1328,7 +1341,9 @@ static int snd_es1938_free(es1938_t *chip) { -#ifndef LINUX_2_2 + /*if (chip->rmidi) + snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);*/ +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) if (chip->gameport.io) gameport_unregister_port(&chip->gameport); #endif @@ -1366,8 +1381,6 @@ static int __devinit snd_es1938_create(snd_card_t * card, struct pci_dev * pci, - unsigned long dma1size, - unsigned long dma2size, es1938_t ** rchip) { es1938_t *chip; @@ -1395,8 +1408,6 @@ spin_lock_init(&chip->mixer_lock); chip->card = card; chip->pci = pci; - chip->dma1size = dma1size; - chip->dma2size = dma2size; chip->io_port = pci_resource_start(pci, 0); if ((chip->res_io_port = request_region(chip->io_port, 8, "ESS Solo-1")) == NULL) { snd_es1938_free(chip); @@ -1531,9 +1542,7 @@ /* MPU401 */ if (status & 0x80) { - /* ack */ - snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); - printk("midi interrupt..\n"); + // snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); /* ack? */ if (chip->rmidi) snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); } @@ -1545,7 +1554,8 @@ { snd_card_t *card; es1938_t *chip; - int err, idx; + unsigned int idx; + int err; snd_assert(pcm != NULL && pcm->card != NULL, return -EINVAL); @@ -1554,8 +1564,7 @@ strcpy(card->mixername, pcm->name); - for (idx = 0; idx < sizeof(snd_es1938_controls) / - sizeof(snd_es1938_controls[0]); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) { snd_kcontrol_t *kctl; kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip); switch (idx) { @@ -1610,10 +1619,7 @@ return -ENODEV; } } - if ((err = snd_es1938_create(card, pci, - 64 * 1024, - 64 * 1024, - &chip)) < 0) { + if ((err = snd_es1938_create(card, pci, &chip)) < 0) { snd_card_free(card); return err; } @@ -1644,8 +1650,10 @@ if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, chip->mpu_port, 1, chip->irq, 0, &chip->rmidi) < 0) { printk(KERN_ERR "es1938: unable to initialize MPU-401\n"); - } -#ifndef LINUX_2_2 + } /*else + snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40);*/ + +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) chip->gameport.io = chip->game_port; gameport_register_port(&chip->gameport); #endif diff -Nru a/sound/pci/es1968.c b/sound/pci/es1968.c --- a/sound/pci/es1968.c Sun Feb 9 21:13:34 2003 +++ b/sound/pci/es1968.c Sun Feb 9 21:13:34 2003 @@ -1414,7 +1414,7 @@ * DMA memory management * *************************/ -/* Because the Maestro can only take adresses relative to the PCM base adress +/* Because the Maestro can only take addresses relative to the PCM base adress register :( */ static int calc_available_memory_size(es1968_t *chip) @@ -2420,15 +2420,12 @@ if (! chip->do_pm) return; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D3hot) - goto __skip; + return; snd_pcm_suspend_all(chip->pcm); snd_es1968_bob_stop(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - __skip: - snd_power_unlock(card); } static void es1968_resume(es1968_t *chip) @@ -2438,9 +2435,8 @@ if (! chip->do_pm) return; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D0) - goto __skip; + return; /* restore all our config */ pci_enable_device(chip->pci); @@ -2459,8 +2455,6 @@ if (atomic_read(&chip->bobclient)) snd_es1968_bob_start(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D0); - __skip: - snd_power_unlock(card); } #ifndef PCI_OLD_SUSPEND @@ -2674,7 +2668,7 @@ val = oval & ~0x04; if (ucontrol->value.integer.value[0]) val |= 0x04; - if (val != oval); { + if (val != oval) { pci_write_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, val); return 1; } @@ -2701,7 +2695,8 @@ static int dev; snd_card_t *card; es1968_t *chip; - int i, err; + unsigned int i; + int err; if (dev >= SNDRV_CARDS) return -ENODEV; diff -Nru a/sound/pci/fm801.c b/sound/pci/fm801.c --- a/sound/pci/fm801.c Sun Feb 9 21:13:35 2003 +++ b/sound/pci/fm801.c Sun Feb 9 21:13:35 2003 @@ -130,7 +130,7 @@ struct resource *res_port; unsigned int multichannel: 1, /* multichannel support */ secondary: 1; /* secondary codec */ - unsigned char secondary_addr; /* addres of the secondary codec */ + unsigned char secondary_addr; /* address of the secondary codec */ unsigned short ply_ctrl; /* playback control */ unsigned short cap_ctrl; /* capture control */ @@ -293,7 +293,7 @@ * Sample rate routines */ -static unsigned short snd_fm801_rate_bits(int rate) +static unsigned short snd_fm801_rate_bits(unsigned int rate) { unsigned int idx; @@ -312,48 +312,66 @@ int cmd) { fm801_t *chip = snd_pcm_substream_chip(substream); - int result = 0; spin_lock(&chip->reg_lock); - if (cmd == SNDRV_PCM_TRIGGER_START) { + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: chip->ply_ctrl &= ~(FM801_BUF1_LAST | FM801_BUF2_LAST | FM801_PAUSE); chip->ply_ctrl |= FM801_START | FM801_IMMED_STOP; - outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL)); - } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { - chip->ply_ctrl &= ~FM801_START; - outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL)); - } else { - result = -EINVAL; + break; + case SNDRV_PCM_TRIGGER_STOP: + chip->ply_ctrl &= ~(FM801_START | FM801_PAUSE); + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + chip->ply_ctrl |= FM801_PAUSE; + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + chip->ply_ctrl &= ~FM801_PAUSE; + break; + default: + spin_unlock(&chip->reg_lock); + snd_BUG(); + return -EINVAL; } + outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL)); spin_unlock(&chip->reg_lock); - return result; + return 0; } static int snd_fm801_capture_trigger(snd_pcm_substream_t * substream, int cmd) { fm801_t *chip = snd_pcm_substream_chip(substream); - int result = 0; spin_lock(&chip->reg_lock); - if (cmd == SNDRV_PCM_TRIGGER_START) { + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: chip->cap_ctrl &= ~(FM801_BUF1_LAST | FM801_BUF2_LAST | FM801_PAUSE); chip->cap_ctrl |= FM801_START | FM801_IMMED_STOP; - outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL)); - } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { - chip->cap_ctrl &= ~FM801_START; - outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL)); - } else { - result = -EINVAL; + break; + case SNDRV_PCM_TRIGGER_STOP: + chip->cap_ctrl &= ~(FM801_START | FM801_PAUSE); + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + chip->cap_ctrl |= FM801_PAUSE; + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + chip->cap_ctrl &= ~FM801_PAUSE; + break; + default: + spin_unlock(&chip->reg_lock); + snd_BUG(); + return -EINVAL; } + outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL)); spin_unlock(&chip->reg_lock); - return result; + return 0; } static int snd_fm801_hw_params(snd_pcm_substream_t * substream, @@ -470,8 +488,11 @@ unsigned int tmp; status = inw(FM801_REG(chip, IRQ_STATUS)); - if ((status & (FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU|FM801_IRQ_VOLUME)) == 0) + status &= FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU|FM801_IRQ_VOLUME; + if (! status) return; + /* ack first */ + outw(status, FM801_REG(chip, IRQ_STATUS)); if (chip->pcm && (status & FM801_IRQ_PLAYBACK) && chip->playback_substream) { spin_lock(&chip->reg_lock); chip->ply_buf++; @@ -483,7 +504,6 @@ (chip->ply_buf & 1) ? FM801_REG(chip, PLY_BUF1) : FM801_REG(chip, PLY_BUF2)); - outw(FM801_IRQ_PLAYBACK, FM801_REG(chip, IRQ_STATUS)); spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(chip->playback_substream); } @@ -498,24 +518,20 @@ (chip->cap_buf & 1) ? FM801_REG(chip, CAP_BUF1) : FM801_REG(chip, CAP_BUF2)); - outw(FM801_IRQ_CAPTURE, FM801_REG(chip, IRQ_STATUS)); spin_unlock(&chip->reg_lock); snd_pcm_period_elapsed(chip->capture_substream); } - if ((status & FM801_IRQ_MPU) && chip->rmidi != NULL) { + if (chip->rmidi && (status & FM801_IRQ_MPU)) snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); - outw(FM801_IRQ_MPU, FM801_REG(chip, IRQ_STATUS)); - } - if (status & FM801_IRQ_VOLUME) { - /* TODO */ - outw(FM801_IRQ_VOLUME, FM801_REG(chip, IRQ_STATUS)); - } + if (status & FM801_IRQ_VOLUME) + ;/* TODO */ } static snd_pcm_hardware_t snd_fm801_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, @@ -535,6 +551,7 @@ { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000, @@ -822,6 +839,7 @@ FM801_SINGLE("IEC958 Capture Switch", FM801_I2S_MODE, 8, 1, 0), FM801_SINGLE("IEC958 Raw Data Playback Switch", FM801_I2S_MODE, 9, 1, 0), FM801_SINGLE("IEC958 Raw Data Capture Switch", FM801_I2S_MODE, 10, 1, 0), +FM801_SINGLE("IEC958 Playback Switch", FM801_GEN_CTRL, 2, 1, 0), }; static void snd_fm801_mixer_free_ac97(ac97_t *ac97) @@ -837,7 +855,8 @@ static int __devinit snd_fm801_mixer(fm801_t *chip) { ac97_t ac97; - int err, i; + unsigned int i; + int err; memset(&ac97, 0, sizeof(ac97)); ac97.write = snd_fm801_codec_write; diff -Nru a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile --- a/sound/pci/ice1712/Makefile Sun Feb 9 21:13:31 2003 +++ b/sound/pci/ice1712/Makefile Sun Feb 9 21:13:31 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := ice1712.o - snd-ice1712-objs := ice1712.o ak4524.o delta.o hoontech.o ews.o amp.o # Toplevel Module Dependency diff -Nru a/sound/pci/ice1712/ak4524.c b/sound/pci/ice1712/ak4524.c --- a/sound/pci/ice1712/ak4524.c Sun Feb 9 21:13:32 2003 +++ b/sound/pci/ice1712/ak4524.c Sun Feb 9 21:13:32 2003 @@ -112,7 +112,7 @@ void snd_ice1712_ak4524_reset(ice1712_t *ice, int state) { - int chip; + unsigned int chip; unsigned char reg; ak4524_t *ak = &ice->ak4524; @@ -341,7 +341,8 @@ int __devinit snd_ice1712_ak4524_build_controls(ice1712_t *ice) { - int err, idx; + unsigned int idx; + int err; ak4524_t *ak = &ice->ak4524; for (idx = 0; idx < ak->num_dacs; ++idx) { diff -Nru a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c --- a/sound/pci/ice1712/amp.c Sun Feb 9 21:13:32 2003 +++ b/sound/pci/ice1712/amp.c Sun Feb 9 21:13:32 2003 @@ -42,6 +42,13 @@ return 0; } +static int __devinit snd_vt1724_amp_add_controls(ice1712_t *ice) +{ + /* we use pins 39 and 41 of the VT1616 for left and right read outputs */ + snd_ac97_write_cache(ice->ac97, 0x5a, snd_ac97_read(ice->ac97, 0x5a) & ~0x8000); + return 0; +} + /* entry point */ struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { @@ -49,6 +56,7 @@ VT1724_SUBDEVICE_AUDIO2000, "AMP Ltd AUDIO2000", snd_vt1724_amp_init, + snd_vt1724_amp_add_controls, }, { } /* terminator */ }; diff -Nru a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c --- a/sound/pci/ice1712/ews.c Sun Feb 9 21:13:29 2003 +++ b/sound/pci/ice1712/ews.c Sun Feb 9 21:13:29 2003 @@ -851,7 +851,8 @@ static int __devinit snd_ice1712_ews_add_controls(ice1712_t *ice) { - int err, idx; + unsigned int idx; + int err; snd_kcontrol_t *kctl; /* all terratec cards have spdif */ @@ -873,7 +874,7 @@ /* card specific controls */ switch (ice->eeprom.subvendor) { case ICE1712_SUBDEVICE_EWX2496: - for (idx = 0; idx < sizeof(snd_ice1712_ewx2496_controls)/sizeof(snd_ice1712_ewx2496_controls[0]); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ewx2496_controls); idx++) { err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ewx2496_controls[idx], ice)); if (err < 0) return err; @@ -892,14 +893,14 @@ return err; break; case ICE1712_SUBDEVICE_EWS88D: - for (idx = 0; idx < sizeof(snd_ice1712_ews88d_controls)/sizeof(snd_ice1712_ews88d_controls[0]); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_ews88d_controls); idx++) { err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88d_controls[idx], ice)); if (err < 0) return err; } break; case ICE1712_SUBDEVICE_DMX6FIRE: - for (idx = 0; idx < sizeof(snd_ice1712_6fire_controls)/sizeof(snd_ice1712_6fire_controls[0]); idx++) { + for (idx = 0; idx < ARRAY_SIZE(snd_ice1712_6fire_controls); idx++) { err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_controls[idx], ice)); if (err < 0) return err; diff -Nru a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c --- a/sound/pci/ice1712/ice1712.c Sun Feb 9 21:13:30 2003 +++ b/sound/pci/ice1712/ice1712.c Sun Feb 9 21:13:30 2003 @@ -107,9 +107,13 @@ #define PCI_DEVICE_ID_VT1724 0x1724 #endif +enum { + TYPE_ICE1712, TYPE_VT1724 +}; + static struct pci_device_id snd_ice1712_ids[] __devinitdata = { - { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ICE1712 */ - { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* VT1724 */ + { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_ICE1712 }, /* ICE1712 */ + { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_VT1724 }, /* VT1724 */ { 0, } }; @@ -1681,12 +1685,11 @@ snd_iprintf(buffer, " CCS%02x : 0x%02x\n", idx, inb(ice->port+idx)); for (idx = 0x0; idx < 0x30 ; idx++) snd_iprintf(buffer, " MT%02x : 0x%02x\n", idx, inb(ice->profi_port+idx)); - - } - else { + } else { snd_iprintf(buffer, " PSDOUT03 : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_PSDOUT03))); snd_iprintf(buffer, " CAPTURE : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE))); snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT))); + snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE))); } } @@ -1694,26 +1697,8 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(ice->card, "ice1712", ice->card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = ice; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 2048; - entry->c.text.read = snd_ice1712_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - ice->proc_entry = entry; -} - -static void snd_ice1712_proc_done(ice1712_t * ice) -{ - if (ice->proc_entry) { - snd_info_unregister(ice->proc_entry); - ice->proc_entry = NULL; - } + if (! snd_card_proc_new(ice->card, "ice1712", &entry)) + snd_info_set_text_ops(entry, ice, snd_ice1712_proc_read); } /* @@ -2689,7 +2674,6 @@ outb(0xff, ICEREG(ice, IRQMASK)); /* --- */ __hw_end: - snd_ice1712_proc_done(ice); if (ice->irq >= 0) { synchronize_irq(ice->irq); free_irq(ice->irq, (void *) ice); @@ -2721,9 +2705,10 @@ } static int __devinit snd_ice1712_create(snd_card_t * card, - struct pci_dev *pci, - int omni, - ice1712_t ** r_ice1712) + struct pci_dev *pci, + int vt1724, + int omni, + ice1712_t ** r_ice1712) { ice1712_t *ice; int err; @@ -2737,7 +2722,7 @@ if ((err = pci_enable_device(pci)) < 0) return err; /* VT1724 does not have 28bit DMA transfer limit */ - if (pci->device==PCI_DEVICE_ID_ICE_1712) { + if (! vt1724) { /* check, if we can restrict PCI DMA transfers to 28 bits */ if (!pci_dma_supported(pci, 0x0fffffff)) { snd_printk("architecture does not support 28bit PCI busmaster DMA\n"); @@ -2745,13 +2730,13 @@ } pci_set_dma_mask(pci, 0x0fffffff); } - else pci_set_dma_mask(pci, 0xffffffff); + else + pci_set_dma_mask(pci, 0xffffffff); ice = snd_magic_kcalloc(ice1712_t, 0, GFP_KERNEL); if (ice == NULL) return -ENOMEM; - if (pci->device==PCI_DEVICE_ID_VT1724) - ice->vt1724=1; + ice->vt1724 = vt1724 ? 1 : 0; ice->omni = omni ? 1 : 0; spin_lock_init(&ice->reg_lock); init_MUTEX(&ice->gpio_mutex); @@ -2893,6 +2878,7 @@ snd_card_t *card; ice1712_t *ice; int pcm_dev = 0, err; + int chip_type; struct snd_ice1712_card_info **tbl, *c; if (dev >= SNDRV_CARDS) @@ -2906,7 +2892,8 @@ if (card == NULL) return -ENOMEM; - if (pci->device==PCI_DEVICE_ID_ICE_1712) { + chip_type = pci_id->driver_data; + if (chip_type == TYPE_ICE1712) { strcpy(card->driver, "ICE1712"); strcpy(card->shortname, "ICEnsemble ICE1712"); } else { @@ -2914,7 +2901,7 @@ strcpy(card->shortname, "ICEnsemble ICE1724"); } - if ((err = snd_ice1712_create(card, pci, omni[dev], &ice)) < 0) { + if ((err = snd_ice1712_create(card, pci, chip_type, omni[dev], &ice)) < 0) { snd_card_free(card); return err; } diff -Nru a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h --- a/sound/pci/ice1712/ice1712.h Sun Feb 9 21:13:28 2003 +++ b/sound/pci/ice1712/ice1712.h Sun Feb 9 21:13:28 2003 @@ -237,8 +237,8 @@ } ice1712_eeprom_t; struct snd_ak4524 { - int num_adcs; /* AK4524 or AK4528 ADCs */ - int num_dacs; /* AK4524 or AK4528 DACs */ + unsigned int num_adcs; /* AK4524 or AK4528 ADCs */ + unsigned int num_dacs; /* AK4524 or AK4528 DACs */ unsigned char images[4][16]; unsigned char ipga_gain[4][2]; /* */ @@ -323,7 +323,7 @@ unsigned int pro_volumes[20]; int omni: 1; /* Delta Omni I/O */ - int num_total_dacs; /* total DACs */ + unsigned int num_total_dacs; /* total DACs */ unsigned char hoontech_boxbits[4]; unsigned int hoontech_config; unsigned short hoontech_boxconfig[4]; diff -Nru a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c --- a/sound/pci/intel8x0.c Sun Feb 9 21:13:33 2003 +++ b/sound/pci/intel8x0.c Sun Feb 9 21:13:33 2003 @@ -131,6 +131,9 @@ #ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a #endif +#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO +#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da +#endif enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_SIS, DEVICE_ALI }; @@ -319,7 +322,6 @@ unsigned char piv_saved; unsigned short picb_saved; #endif - snd_info_entry_t *proc_entry; } ichdev_t; typedef struct _snd_intel8x0 intel8x0_t; @@ -365,7 +367,6 @@ spinlock_t reg_lock; spinlock_t ac97_lock; - snd_info_entry_t *proc_entry; u32 bdbars_count; u32 *bdbars; @@ -388,6 +389,7 @@ { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7012 */ { 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* NFORCE */ { 0x10de, 0x006a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* NFORCE2 */ + { 0x10de, 0x00da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* NFORCE3 */ { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */ { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */ @@ -709,7 +711,7 @@ intel8x0_t *chip = snd_magic_cast(intel8x0_t, dev_id, return); ichdev_t *ichdev; unsigned int status; - int i; + unsigned int i; spin_lock(&chip->reg_lock); status = igetdword(chip, chip->int_sta_reg); @@ -1276,6 +1278,9 @@ sprintf(pcm->name, "%s - MIC ADC", chip->card->shortname); chip->pcm_mic = pcm; + + snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 0, 128*1024); + if (rpcm) *rpcm = pcm; return 0; @@ -1310,6 +1315,9 @@ sprintf(pcm->name, "%s - MIC2 ADC", chip->card->shortname); chip->pcm_mic2 = pcm; + + snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 0, 128*1024); + if (rpcm) *rpcm = pcm; return 0; @@ -1344,6 +1352,9 @@ sprintf(pcm->name, "%s - ADC2", chip->card->shortname); chip->pcm2 = pcm; + + snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 0, 128*1024); + if (rpcm) *rpcm = pcm; return 0; @@ -1378,6 +1389,9 @@ sprintf(pcm->name, "%s - IEC958", chip->card->shortname); chip->pcm_spdif = pcm; + + snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 128*1024); + if (rpcm) *rpcm = pcm; return 0; @@ -1413,6 +1427,9 @@ sprintf(pcm->name, "%s - IEC958", chip->card->shortname); chip->pcm_spdif = pcm; + + snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 128*1024); + if (rpcm) *rpcm = pcm; return 0; @@ -1447,6 +1464,9 @@ sprintf(pcm->name, "%s - AC97 IEC958", chip->card->shortname); chip->pcm_ac97spdif = pcm; + + snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 128*1024); + if (rpcm) *rpcm = pcm; return 0; @@ -1788,6 +1808,10 @@ } while (time_after_eq(end_time, jiffies)); __ok3: + if (chip->device_type == DEVICE_SIS) { + /* unmute the output on SIS7012 */ + iputword(chip, 0x4c, igetword(chip, 0x4c) | 1); + } return 0; } @@ -1827,7 +1851,8 @@ static int snd_intel8x0_chip_init(intel8x0_t *chip) { - int i, err; + unsigned int i; + int err; if (chip->device_type != DEVICE_ALI) err = snd_intel8x0_ich_chip_init(chip); @@ -1850,11 +1875,9 @@ return 0; } -static void snd_intel8x0_proc_done(intel8x0_t * chip); - static int snd_intel8x0_free(intel8x0_t *chip) { - int i; + unsigned int i; if (chip->irq < 0) goto __hw_end; @@ -1867,7 +1890,6 @@ /* --- */ synchronize_irq(chip->irq); __hw_end: - snd_intel8x0_proc_done(chip); if (chip->bdbars) snd_free_pci_pages(chip->pci, chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2, chip->bdbars, chip->bdbars_addr); if (chip->remap_addr) @@ -1896,17 +1918,15 @@ { snd_card_t *card = chip->card; - chip->in_suspend = 1; - snd_power_lock(card); - if (card->power_state == SNDRV_CTL_POWER_D3hot) - goto __skip; + if (chip->in_suspend || + card->power_state == SNDRV_CTL_POWER_D3hot) + return; + chip->in_suspend = 1; snd_pcm_suspend_all(chip->pcm); if (chip->pcm_mic) snd_pcm_suspend_all(chip->pcm_mic); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - __skip: - snd_power_unlock(card); } static void intel8x0_resume(intel8x0_t *chip) @@ -1914,9 +1934,9 @@ snd_card_t *card = chip->card; int i; - snd_power_lock(card); - if (card->power_state == SNDRV_CTL_POWER_D0) - goto __skip; + if (! chip->in_suspend || + card->power_state == SNDRV_CTL_POWER_D0) + return; pci_enable_device(chip->pci); snd_intel8x0_chip_init(chip); @@ -1926,8 +1946,6 @@ chip->in_suspend = 0; snd_power_change_state(card, SNDRV_CTL_POWER_D0); - __skip: - snd_power_unlock(card); } #ifndef PCI_OLD_SUSPEND @@ -2096,26 +2114,8 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(chip->card, "intel8x0", chip->card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = chip; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 2048; - entry->c.text.read = snd_intel8x0_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - chip->proc_entry = entry; -} - -static void snd_intel8x0_proc_done(intel8x0_t * chip) -{ - if (chip->proc_entry) { - snd_info_unregister(chip->proc_entry); - chip->proc_entry = NULL; - } + if (! snd_card_proc_new(chip->card, "intel8x0", &entry)) + snd_info_set_text_ops(entry, chip, snd_intel8x0_proc_read); } static int snd_intel8x0_dev_free(snd_device_t *device) @@ -2130,7 +2130,8 @@ intel8x0_t ** r_intel8x0) { intel8x0_t *chip; - int err, i; + int err; + unsigned int i; unsigned int int_sta_masks; ichdev_t *ichdev; static snd_device_ops_t ops = { @@ -2247,7 +2248,7 @@ chip->bdbars_count = 3; if (device_type == DEVICE_INTEL_ICH4 || device_type == DEVICE_ALI) chip->bdbars_count = 6; - chip->bdbars = (u32 *)snd_malloc_pci_pages(pci, chip->bdbars_count * sizeof(unsigned int) * ICH_MAX_FRAGS * 2, &chip->bdbars_addr); + chip->bdbars = (u32 *)snd_malloc_pci_pages(pci, chip->bdbars_count * sizeof(u32) * ICH_MAX_FRAGS * 2, &chip->bdbars_addr); if (chip->bdbars == NULL) { snd_intel8x0_free(chip); return -ENOMEM; @@ -2304,6 +2305,7 @@ { PCI_DEVICE_ID_SI_7012, "SiS SI7012" }, { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia NForce" }, { PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia NForce2" }, + { PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, "NVidia NForce3" }, { 0x746d, "AMD AMD8111" }, { 0x7445, "AMD AMD768" }, { 0x5455, "ALi M5455" }, @@ -2488,6 +2490,8 @@ // { 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 440MX */ // { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SI7012 */ { 0x10de, 0x01b2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* NFORCE */ + { 0x10de, 0x006b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* NFORCE2 */ + { 0x10de, 0x00db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* NFORCE3 */ { 0, } }; @@ -2496,6 +2500,8 @@ .id_table = snd_intel8x0_joystick_ids, .probe = snd_intel8x0_joystick_probe, }; + +static int have_joystick; #endif static int __init alsa_card_intel8x0_init(void) @@ -2509,7 +2515,13 @@ return err; } #if defined(SUPPORT_JOYSTICK) || defined(SUPPORT_MIDI) - pci_module_init(&joystick_driver); + if (pci_module_init(&joystick_driver) < 0) { + snd_printdd(KERN_INFO "no joystick found\n"); + have_joystick = 0; + } else { + snd_printdd(KERN_INFO "joystick(s) found\n"); + have_joystick = 1; + } #endif return 0; @@ -2519,7 +2531,8 @@ { pci_unregister_driver(&driver); #if defined(SUPPORT_JOYSTICK) || defined(SUPPORT_MIDI) - pci_unregister_driver(&joystick_driver); + if (have_joystick) + pci_unregister_driver(&joystick_driver); #endif } diff -Nru a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c --- a/sound/pci/korg1212/korg1212.c Sun Feb 9 21:13:28 2003 +++ b/sound/pci/korg1212/korg1212.c Sun Feb 9 21:13:28 2003 @@ -368,7 +368,6 @@ snd_pcm_substream_t *playback_substream; snd_pcm_substream_t *capture_substream; - snd_info_entry_t * proc_entry; CardState cardState; int running; @@ -1704,13 +1703,13 @@ i = kcontrol->private_value; - if (u->value.enumerated.item[0] != korg1212->sharedBufferPtr->volumeData[i]) { + if (u->value.enumerated.item[0] != (unsigned int)korg1212->sharedBufferPtr->volumeData[i]) { korg1212->sharedBufferPtr->routeData[i] = u->value.enumerated.item[0]; change = 1; } if (i >= 8) { - if (u->value.enumerated.item[1] != korg1212->sharedBufferPtr->volumeData[i+1]) { + if (u->value.enumerated.item[1] != (unsigned int)korg1212->sharedBufferPtr->volumeData[i+1]) { korg1212->sharedBufferPtr->routeData[i+1] = u->value.enumerated.item[1]; change = 1; } @@ -1898,33 +1897,15 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(korg1212->card, "korg1212", korg1212->card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = korg1212; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 256; - entry->c.text.read = snd_korg1212_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - korg1212->proc_entry = entry; -} - -static void snd_korg1212_proc_done(korg1212_t * korg1212) -{ - if (korg1212->proc_entry) { - snd_info_unregister(korg1212->proc_entry); - korg1212->proc_entry = NULL; - } + if (! snd_card_proc_new(korg1212->card, "korg1212", &entry)) + snd_info_set_text_ops(entry, korg1212, snd_korg1212_proc_read); } static int __devinit snd_korg1212_create(korg1212_t *korg1212) { struct pci_dev *pci = korg1212->pci; int err; - int i; + unsigned int i; unsigned ioport_size, iomem_size, iomem2_size; dma_addr_t phys_addr; @@ -2173,8 +2154,6 @@ if (korg1212 == NULL) { return; } - - snd_korg1212_proc_done(korg1212); snd_korg1212_TurnOffIdleMonitor(korg1212); diff -Nru a/sound/pci/maestro3.c b/sound/pci/maestro3.c --- a/sound/pci/maestro3.c Sun Feb 9 21:13:33 2003 +++ b/sound/pci/maestro3.c Sun Feb 9 21:13:33 2003 @@ -1328,7 +1328,7 @@ static void snd_m3_playback_setup(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs) { - int i; + unsigned int i; /* * some per client initializers @@ -1355,7 +1355,7 @@ /* * set an armload of static initializers */ - for (i = 0 ; i < (sizeof(pv) / sizeof(pv[0])) ; i++) + for (i = 0; i < ARRAY_SIZE(pv); i++) snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA, s->inst.data + pv[i].addr, pv[i].val); } @@ -1394,7 +1394,7 @@ static void snd_m3_capture_setup(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs) { - int i; + unsigned int i; /* * some per client initializers @@ -1413,7 +1413,7 @@ /* * set an armload of static initializers */ - for (i = 0 ; i < (sizeof(rv) / sizeof(rv[0])) ; i++) + for (i = 0; i < ARRAY_SIZE(rv); i++) snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA, s->inst.data + rv[i].addr, rv[i].val); } @@ -2121,7 +2121,7 @@ static void snd_m3_assp_init(m3_t *chip) { - int i; + unsigned int i; /* zero kernel data */ for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++) @@ -2377,9 +2377,8 @@ snd_card_t *card = chip->card; int i, index; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D3hot) - goto __skip; + return; snd_pcm_suspend_all(chip->pcm); @@ -2400,8 +2399,6 @@ snd_m3_outw(chip, 0xffff, 0x54); snd_m3_outw(chip, 0xffff, 0x56); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - __skip: - snd_power_unlock(card); } static void m3_resume(m3_t *chip) @@ -2409,9 +2406,8 @@ snd_card_t *card = chip->card; int i, index; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D0) - goto __skip; + return; /* first lets just bring everything back. .*/ snd_m3_outw(chip, 0, 0x54); @@ -2442,8 +2438,6 @@ snd_m3_amp_enable(chip, 1); snd_power_change_state(card, SNDRV_CTL_POWER_D0); - __skip: - snd_power_unlock(card); } #ifndef PCI_OLD_SUSPEND diff -Nru a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c --- a/sound/pci/nm256/nm256.c Sun Feb 9 21:13:35 2003 +++ b/sound/pci/nm256/nm256.c Sun Feb 9 21:13:35 2003 @@ -405,7 +405,7 @@ /* The actual rates supported by the card. */ -static int samplerates[8] = { +static unsigned int samplerates[8] = { 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, }; #define NUM_SAMPLERATES (sizeof(samplerates) / sizeof(samplerates[0])) @@ -419,9 +419,9 @@ * return the index of the target rate */ static int -snd_nm256_fixed_rate(int rate) +snd_nm256_fixed_rate(unsigned int rate) { - int i; + unsigned int i; for (i = 0; i < NUM_SAMPLERATES; i++) { if (rate == samplerates[i]) return i; @@ -1270,24 +1270,20 @@ { snd_card_t *card = chip->card; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D3hot) - goto __skip; + return; snd_pcm_suspend_all(chip->pcm); chip->coeffs_current = 0; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - __skip: - snd_power_unlock(card); } static void nm256_resume(nm256_t *chip) { snd_card_t *card = chip->card; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D0) - goto __skip; + return; /* Perform a full reset on the hardware */ pci_enable_device(chip->pci); @@ -1297,8 +1293,6 @@ snd_ac97_resume(chip->ac97); snd_power_change_state(card, SNDRV_CTL_POWER_D0); - __skip: - snd_power_unlock(card); } #ifndef PCI_OLD_SUSPEND @@ -1539,7 +1533,7 @@ if ((err = snd_nm256_pcm(chip, 0)) < 0) goto __error; - if ((err = snd_nm256_mixer(chip) < 0)) + if ((err = snd_nm256_mixer(chip)) < 0) goto __error; // pci_set_master(pci); /* needed? */ diff -Nru a/sound/pci/rme32.c b/sound/pci/rme32.c --- a/sound/pci/rme32.c Sun Feb 9 21:13:37 2003 +++ b/sound/pci/rme32.c Sun Feb 9 21:13:37 2003 @@ -1,7 +1,7 @@ /* * ALSA driver for RME Digi32, Digi32/8 and Digi32 PRO audio interfaces * - * Copyright (c) 2002 Martin Langer + * Copyright (c) 2002, 2003 Martin Langer * * Thanks to : Anders Torger , * Henk Hesselink @@ -220,7 +220,6 @@ snd_pcm_t *spdif_pcm; snd_pcm_t *adat_pcm; struct pci_dev *pci; - snd_info_entry_t *proc_entry; snd_kcontrol_t *spdif_ctl; } rme32_t; @@ -257,8 +256,6 @@ static void snd_rme32_proc_init(rme32_t * rme32); -static void snd_rme32_proc_done(rme32_t * rme32); - static int snd_rme32_create_switches(snd_card_t * card, rme32_t * rme32); static inline unsigned int snd_rme32_playback_ptr(rme32_t * rme32) @@ -274,6 +271,19 @@ & RME32_RCR_AUDIO_ADDR_MASK) >> rme32->capture_frlog; } +static int snd_rme32_ratecode(int rate) +{ + switch (rate) { + case 32000: return SNDRV_PCM_RATE_32000; + case 44100: return SNDRV_PCM_RATE_44100; + case 48000: return SNDRV_PCM_RATE_48000; + case 64000: return SNDRV_PCM_RATE_64000; + case 88200: return SNDRV_PCM_RATE_88200; + case 96000: return SNDRV_PCM_RATE_96000; + } + return 0; +} + static int snd_rme32_playback_silence(snd_pcm_substream_t * substream, int channel, /* not used (interleaved data) */ snd_pcm_uframes_t pos, snd_pcm_uframes_t count) @@ -561,18 +571,22 @@ { switch (mode) { case RME32_CLOCKMODE_SLAVE: + /* AutoSync */ rme32->wcreg = (rme32->wcreg & ~RME32_WCR_FREQ_0) & ~RME32_WCR_FREQ_1; break; case RME32_CLOCKMODE_MASTER_32: + /* Internal 32.0kHz */ rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) & ~RME32_WCR_FREQ_1; break; case RME32_CLOCKMODE_MASTER_44: + /* Internal 44.1kHz */ rme32->wcreg = (rme32->wcreg & ~RME32_WCR_FREQ_0) | RME32_WCR_FREQ_1; break; case RME32_CLOCKMODE_MASTER_48: + /* Internal 48.0kHz */ rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) | RME32_WCR_FREQ_1; break; @@ -661,14 +675,21 @@ snd_rme32_playback_hw_params(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * params) { + int err, rate, dummy; rme32_t *rme32 = _snd_pcm_substream_chip(substream); - int err; if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0) return err; spin_lock_irq(&rme32->lock); - if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) { + if ((rme32->rcreg & RME32_RCR_KMODE) && + (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) { + /* AutoSync */ + if ((int)params_rate(params) != rate) { + spin_unlock_irq(&rme32->lock); + return -EIO; + } + } else if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) { spin_unlock_irq(&rme32->lock); return err; } @@ -708,8 +729,9 @@ snd_pcm_hw_params_t * params) { unsigned long flags; + int err, isadat, rate; rme32_t *rme32 = _snd_pcm_substream_chip(substream); - int err, isadat; + snd_pcm_runtime_t *runtime = substream->runtime; if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0) @@ -727,9 +749,16 @@ spin_unlock_irqrestore(&rme32->lock, flags); return err; } - if (params_rate(params) != snd_rme32_capture_getrate(rme32, &isadat)) { - spin_unlock_irqrestore(&rme32->lock, flags); - return -EBUSY; + if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) { + if ((int)params_rate(params) != rate) { + spin_unlock_irqrestore(&rme32->lock, flags); + return -EIO; + } + if ((isadat && runtime->hw.channels_min == 2) || + (!isadat && runtime->hw.channels_min == 8)) { + spin_unlock_irqrestore(&rme32->lock, flags); + return -EIO; + } } /* AutoSync off for recording */ rme32->wcreg &= ~RME32_WCR_AUTOSYNC; @@ -789,7 +818,8 @@ writel(0, rme32->iobase + RME32_IO_CONFIRM_ACTION_IRQ); } rme32->wcreg &= ~RME32_WCR_START; - rme32->wcreg |= RME32_WCR_MUTE; + if (rme32->wcreg & RME32_WCR_SEL) + rme32->wcreg |= RME32_WCR_MUTE; writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER); } @@ -836,12 +866,17 @@ static int snd_rme32_playback_spdif_open(snd_pcm_substream_t * substream) { unsigned long flags; + int rate, dummy; rme32_t *rme32 = _snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_set_sync(substream); spin_lock_irqsave(&rme32->lock, flags); + if (rme32->playback_substream != NULL) { + spin_unlock_irqrestore(&rme32->lock, flags); + return -EBUSY; + } rme32->wcreg &= ~RME32_WCR_ADAT; writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER); rme32->playback_substream = substream; @@ -854,7 +889,13 @@ runtime->hw.rates |= SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000; runtime->hw.rate_max = 96000; } - + if ((rme32->rcreg & RME32_RCR_KMODE) && + (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) { + /* AutoSync */ + runtime->hw.rates = snd_rme32_ratecode(rate); + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME32_BUFFER_SIZE, RME32_BUFFER_SIZE); @@ -872,23 +913,17 @@ static int snd_rme32_capture_spdif_open(snd_pcm_substream_t * substream) { unsigned long flags; - int isadat; + int isadat, rate; rme32_t *rme32 = _snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; - rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER); - if (snd_rme32_capture_getrate(rme32, &isadat) < 0) { - /* no input */ - return -EIO; - } - if (isadat) { - /* ADAT input */ - return -EBUSY; - } snd_pcm_set_sync(substream); spin_lock_irqsave(&rme32->lock, flags); - + if (rme32->capture_substream != NULL) { + spin_unlock_irqrestore(&rme32->lock, flags); + return -EBUSY; + } rme32->capture_substream = substream; rme32->capture_ptr = 0; spin_unlock_irqrestore(&rme32->lock, flags); @@ -898,6 +933,14 @@ runtime->hw.rates |= SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000; runtime->hw.rate_max = 96000; } + if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) { + if (isadat) { + return -EIO; + } + runtime->hw.rates = snd_rme32_ratecode(rate); + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, @@ -913,12 +956,17 @@ snd_rme32_playback_adat_open(snd_pcm_substream_t *substream) { unsigned long flags; + int rate, dummy; rme32_t *rme32 = _snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_set_sync(substream); spin_lock_irqsave(&rme32->lock, flags); + if (rme32->playback_substream != NULL) { + spin_unlock_irqrestore(&rme32->lock, flags); + return -EBUSY; + } rme32->wcreg |= RME32_WCR_ADAT; writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER); rme32->playback_substream = substream; @@ -927,6 +975,13 @@ spin_unlock_irqrestore(&rme32->lock, flags); runtime->hw = snd_rme32_playback_adat_info; + if ((rme32->rcreg & RME32_RCR_KMODE) && + (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) { + /* AutoSync */ + runtime->hw.rates = snd_rme32_ratecode(rate); + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME32_BUFFER_SIZE, RME32_BUFFER_SIZE); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, @@ -938,27 +993,31 @@ snd_rme32_capture_adat_open(snd_pcm_substream_t *substream) { unsigned long flags; - int isadat; + int isadat, rate; rme32_t *rme32 = _snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; - rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER); - if (snd_rme32_capture_getrate(rme32, &isadat) < 0) { - /* no input */ - return -EIO; - } - if (!isadat) { - /* S/PDIF input */ - return -EBUSY; - } - snd_pcm_set_sync(substream); + runtime->hw = snd_rme32_capture_adat_info; + if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) { + if (!isadat) { + return -EIO; + } + runtime->hw.rates = snd_rme32_ratecode(rate); + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } + snd_pcm_set_sync(substream); + spin_lock_irqsave(&rme32->lock, flags); + if (rme32->capture_substream != NULL) { + spin_unlock_irqrestore(&rme32->lock, flags); + return -EBUSY; + } rme32->capture_substream = substream; rme32->capture_ptr = 0; spin_unlock_irqrestore(&rme32->lock, flags); - runtime->hw = snd_rme32_capture_adat_info; snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME32_BUFFER_SIZE, RME32_BUFFER_SIZE); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, @@ -1008,7 +1067,8 @@ snd_rme32_playback_stop(rme32); } writel(0, rme32->iobase + RME32_IO_RESET_POS); - rme32->wcreg &= ~RME32_WCR_MUTE; + if (rme32->wcreg & RME32_WCR_SEL) + rme32->wcreg &= ~RME32_WCR_MUTE; writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER); spin_unlock_irqrestore(&rme32->lock, flags); return 0; @@ -1240,7 +1300,6 @@ if (rme32->irq >= 0) { snd_rme32_playback_stop(rme32); snd_rme32_capture_stop(rme32); - snd_rme32_proc_done(rme32); free_irq(rme32->irq, (void *) rme32); rme32->irq = -1; } @@ -1463,10 +1522,10 @@ snd_iprintf(buffer, " sample rate: %d Hz\n", snd_rme32_playback_getrate(rme32)); } - if (rme32->wcreg & RME32_RCR_KMODE) { - snd_iprintf(buffer, " clock mode: slave\n"); + if (rme32->rcreg & RME32_RCR_KMODE) { + snd_iprintf(buffer, " sample clock source: AutoSync\n"); } else { - snd_iprintf(buffer, " clock mode: master\n"); + snd_iprintf(buffer, " sample clock source: Internal\n"); } if (rme32->wcreg & RME32_WCR_PRO) { snd_iprintf(buffer, " format: AES/EBU (professional)\n"); @@ -1484,26 +1543,8 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(rme32->card, "rme32", rme32->card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = rme32; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 256; - entry->c.text.read = snd_rme32_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - rme32->proc_entry = entry; -} - -static void snd_rme32_proc_done(rme32_t * rme32) -{ - if (rme32->proc_entry) { - snd_info_unregister(rme32->proc_entry); - rme32->proc_entry = NULL; - } + if (! snd_card_proc_new(rme32->card, "rme32", &entry)) + snd_info_set_text_ops(entry, rme32, snd_rme32_proc_read); } /* @@ -1546,6 +1587,10 @@ spin_lock_irqsave(&rme32->lock, flags); val = (rme32->wcreg & ~RME32_WCR_SEL) | val; change = val != rme32->wcreg; + if (ucontrol->value.integer.value[0]) + val &= ~RME32_WCR_MUTE; + else + val |= RME32_WCR_MUTE; writel(rme32->wcreg = val, rme32->iobase + RME32_IO_CONTROL_REGISTER); spin_unlock_irqrestore(&rme32->lock, flags); @@ -1588,7 +1633,7 @@ { rme32_t *rme32 = _snd_kcontrol_chip(kcontrol); unsigned long flags; - int items = 3; + unsigned int items = 3; spin_lock_irqsave(&rme32->lock, flags); ucontrol->value.enumerated.item[0] = snd_rme32_getinputtype(rme32); @@ -1636,7 +1681,7 @@ val = ucontrol->value.enumerated.item[0] % items; spin_lock_irqsave(&rme32->lock, flags); - change = val != snd_rme32_getinputtype(rme32); + change = val != (unsigned int)snd_rme32_getinputtype(rme32); snd_rme32_setinputtype(rme32, val); spin_unlock_irqrestore(&rme32->lock, flags); return change; @@ -1646,7 +1691,10 @@ snd_rme32_info_clockmode_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) { - static char *texts[4] = { "Slave", "Master (32.0 kHz)", "Master (44.1 kHz)", "Master (48.0 kHz)" }; + static char *texts[4] = { "AutoSync", + "Internal 32.0kHz", + "Internal 44.1kHz", + "Internal 48.0kHz" }; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -1681,7 +1729,7 @@ val = ucontrol->value.enumerated.item[0] % 3; spin_lock_irqsave(&rme32->lock, flags); - change = val != snd_rme32_getclockmode(rme32); + change = val != (unsigned int)snd_rme32_getclockmode(rme32); snd_rme32_setclockmode(rme32, val); spin_unlock_irqrestore(&rme32->lock, flags); return change; @@ -1843,7 +1891,7 @@ }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "Clock Mode", + .name = "Sample Clock Source", .info = snd_rme32_info_clockmode_control, .get = snd_rme32_get_clockmode_control, .put = snd_rme32_put_clockmode_control diff -Nru a/sound/pci/rme96.c b/sound/pci/rme96.c --- a/sound/pci/rme96.c Sun Feb 9 21:13:31 2003 +++ b/sound/pci/rme96.c Sun Feb 9 21:13:31 2003 @@ -257,7 +257,6 @@ snd_pcm_t *spdif_pcm; snd_pcm_t *adat_pcm; struct pci_dev *pci; - snd_info_entry_t *proc_entry; snd_kcontrol_t *spdif_ctl; } rme96_t; @@ -308,13 +307,13 @@ static void __devinit snd_rme96_proc_init(rme96_t *rme96); -static void -snd_rme96_proc_done(rme96_t *rme96); - static int snd_rme96_create_switches(snd_card_t *card, rme96_t *rme96); +static int +snd_rme96_getinputtype(rme96_t *rme96); + static inline unsigned int snd_rme96_playback_ptr(rme96_t *rme96) { @@ -330,6 +329,20 @@ } static int +snd_rme96_ratecode(int rate) +{ + switch (rate) { + case 32000: return SNDRV_PCM_RATE_32000; + case 44100: return SNDRV_PCM_RATE_44100; + case 48000: return SNDRV_PCM_RATE_48000; + case 64000: return SNDRV_PCM_RATE_64000; + case 88200: return SNDRV_PCM_RATE_88200; + case 96000: return SNDRV_PCM_RATE_96000; + } + return 0; +} + +static int snd_rme96_playback_silence(snd_pcm_substream_t *substream, int channel, /* not used (interleaved data) */ snd_pcm_uframes_t pos, @@ -669,10 +682,11 @@ int rate, dummy; if (!(rme96->wcreg & RME96_WCR_MASTER) && + snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) { - /* slave clock */ - return rate; + /* slave clock */ + return rate; } rate = ((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_0) & 1) + (((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_1) & 1) << 1); @@ -974,14 +988,23 @@ snd_rme96_playback_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params) { - unsigned long flags; + unsigned long flags; rme96_t *rme96 = _snd_pcm_substream_chip(substream); - int err; + int err, rate, dummy; if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0) return err; spin_lock_irqsave(&rme96->lock, flags); - if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) { + if (!(rme96->wcreg & RME96_WCR_MASTER) && + snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && + (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) + { + /* slave clock */ + if ((int)params_rate(params) != rate) { + spin_unlock_irqrestore(&rme96->lock, flags); + return -EIO; + } + } else if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) { spin_unlock_irqrestore(&rme96->lock, flags); return err; } @@ -1024,7 +1047,8 @@ { unsigned long flags; rme96_t *rme96 = _snd_pcm_substream_chip(substream); - int err, isadat; + snd_pcm_runtime_t *runtime = substream->runtime; + int err, isadat, rate; if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0) return err; @@ -1040,10 +1064,18 @@ spin_unlock_irqrestore(&rme96->lock, flags); return err; } - } else if (params_rate(params) != snd_rme96_capture_getrate(rme96, &isadat)) { - spin_unlock_irqrestore(&rme96->lock, flags); - return -EBUSY; - } + } else if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) { + if ((int)params_rate(params) != rate) { + spin_unlock_irqrestore(&rme96->lock, flags); + return -EIO; + } + if ((isadat && runtime->hw.channels_min == 2) || + (!isadat && runtime->hw.channels_min == 8)) + { + spin_unlock_irqrestore(&rme96->lock, flags); + return -EIO; + } + } snd_rme96_setframelog(rme96, params_channels(params), 0); if (rme96->playback_periodsize != 0) { if (params_period_size(params) << rme96->capture_frlog != @@ -1138,7 +1170,7 @@ if (rme96->rcreg & RME96_RCR_IRQ) { /* playback */ - snd_pcm_period_elapsed(rme96->playback_substream); + snd_pcm_period_elapsed(rme96->playback_substream); writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ); } if (rme96->rcreg & RME96_RCR_IRQ_2) { @@ -1162,12 +1194,17 @@ snd_rme96_playback_spdif_open(snd_pcm_substream_t *substream) { unsigned long flags; + int rate, dummy; rme96_t *rme96 = _snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_set_sync(substream); spin_lock_irqsave(&rme96->lock, flags); + if (rme96->playback_substream != NULL) { + spin_unlock_irqrestore(&rme96->lock, flags); + return -EBUSY; + } rme96->wcreg &= ~RME96_WCR_ADAT; writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); rme96->playback_substream = substream; @@ -1175,7 +1212,16 @@ rme96->playback_ptr = 0; spin_unlock_irqrestore(&rme96->lock, flags); - runtime->hw = snd_rme96_playback_spdif_info; + runtime->hw = snd_rme96_playback_spdif_info; + if (!(rme96->wcreg & RME96_WCR_MASTER) && + snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && + (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) + { + /* slave clock */ + runtime->hw.rates = snd_rme96_ratecode(rate); + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes); @@ -1190,28 +1236,33 @@ snd_rme96_capture_spdif_open(snd_pcm_substream_t *substream) { unsigned long flags; - int isadat; + int isadat, rate; rme96_t *rme96 = _snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; - rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); - if (snd_rme96_capture_getrate(rme96, &isadat) < 0) { - /* no input */ - return -EIO; - } - if (isadat) { - /* ADAT input */ - return -EBUSY; - } snd_pcm_set_sync(substream); - spin_lock_irqsave(&rme96->lock, flags); + runtime->hw = snd_rme96_capture_spdif_info; + if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && + (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) + { + if (isadat) { + return -EIO; + } + runtime->hw.rates = snd_rme96_ratecode(rate); + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } + + spin_lock_irqsave(&rme96->lock, flags); + if (rme96->capture_substream != NULL) { + spin_unlock_irqrestore(&rme96->lock, flags); + return -EBUSY; + } rme96->capture_substream = substream; rme96->capture_ptr = 0; spin_unlock_irqrestore(&rme96->lock, flags); - runtime->hw = snd_rme96_capture_spdif_info; - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes); @@ -1222,12 +1273,17 @@ snd_rme96_playback_adat_open(snd_pcm_substream_t *substream) { unsigned long flags; + int rate, dummy; rme96_t *rme96 = _snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_set_sync(substream); spin_lock_irqsave(&rme96->lock, flags); + if (rme96->playback_substream != NULL) { + spin_unlock_irqrestore(&rme96->lock, flags); + return -EBUSY; + } rme96->wcreg |= RME96_WCR_ADAT; writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); rme96->playback_substream = substream; @@ -1236,6 +1292,15 @@ spin_unlock_irqrestore(&rme96->lock, flags); runtime->hw = snd_rme96_playback_adat_info; + if (!(rme96->wcreg & RME96_WCR_MASTER) && + snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && + (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) + { + /* slave clock */ + runtime->hw.rates = snd_rme96_ratecode(rate); + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes); return 0; @@ -1245,27 +1310,36 @@ snd_rme96_capture_adat_open(snd_pcm_substream_t *substream) { unsigned long flags; - int isadat; + int isadat, rate; rme96_t *rme96 = _snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; - rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); - if (snd_rme96_capture_getrate(rme96, &isadat) < 0) { - /* no input */ - return -EIO; - } - if (!isadat) { - /* S/PDIF input */ - return -EBUSY; - } snd_pcm_set_sync(substream); + runtime->hw = snd_rme96_capture_adat_info; + if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG) { + /* makes no sense to use analog input. Note that analog + expension cards AEB4/8-I are RME96_INPUT_INTERNAL */ + return -EIO; + } + if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) { + if (!isadat) { + return -EIO; + } + runtime->hw.rates = snd_rme96_ratecode(rate); + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } + spin_lock_irqsave(&rme96->lock, flags); + if (rme96->capture_substream != NULL) { + spin_unlock_irqrestore(&rme96->lock, flags); + return -EBUSY; + } rme96->capture_substream = substream; rme96->capture_ptr = 0; spin_unlock_irqrestore(&rme96->lock, flags); - runtime->hw = snd_rme96_capture_adat_info; snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE); snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_period_bytes); return 0; @@ -1279,6 +1353,9 @@ int spdif = 0; spin_lock_irqsave(&rme96->lock, flags); + if (RME96_ISPLAYING(rme96)) { + snd_rme96_playback_stop(rme96); + } rme96->playback_substream = NULL; rme96->playback_periodsize = 0; spdif = (rme96->wcreg & RME96_WCR_ADAT) == 0; @@ -1298,6 +1375,9 @@ rme96_t *rme96 = _snd_pcm_substream_chip(substream); spin_lock_irqsave(&rme96->lock, flags); + if (RME96_ISRECORDING(rme96)) { + snd_rme96_capture_stop(rme96); + } rme96->capture_substream = NULL; rme96->capture_periodsize = 0; spin_unlock_irqrestore(&rme96->lock, flags); @@ -1558,7 +1638,6 @@ snd_rme96_capture_stop(rme96); rme96->areg &= ~RME96_AR_DAC_EN; writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); - snd_rme96_proc_done(rme96); free_irq(rme96->irq, (void *)rme96); rme96->irq = -1; } @@ -1785,6 +1864,10 @@ snd_iprintf(buffer, " clock mode: word clock\n"); } else if (rme96->wcreg & RME96_WCR_MASTER) { snd_iprintf(buffer, " clock mode: master\n"); + } else if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) { + snd_iprintf(buffer, " clock mode: slave (master anyway due to analog input setting)\n"); + } else if (snd_rme96_capture_getrate(rme96, &n) < 0) { + snd_iprintf(buffer, " clock mode: slave (master anyway due to no valid signal)\n"); } else { snd_iprintf(buffer, " clock mode: slave\n"); } @@ -1843,27 +1926,8 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(rme96->card, "rme96", rme96->card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = rme96; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 256; - entry->c.text.read = snd_rme96_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - rme96->proc_entry = entry; -} - -static void -snd_rme96_proc_done(rme96_t * rme96) -{ - if (rme96->proc_entry) { - snd_info_unregister(rme96->proc_entry); - rme96->proc_entry = NULL; - } + if (! snd_card_proc_new(rme96->card, "rme96", &entry)) + snd_info_set_text_ops(entry, rme96, snd_rme96_proc_read); } /* @@ -1949,7 +2013,7 @@ { rme96_t *rme96 = _snd_kcontrol_chip(kcontrol); unsigned long flags; - int items = 3; + unsigned int items = 3; spin_lock_irqsave(&rme96->lock, flags); ucontrol->value.enumerated.item[0] = snd_rme96_getinputtype(rme96); @@ -2021,7 +2085,7 @@ } spin_lock_irqsave(&rme96->lock, flags); - change = val != snd_rme96_getinputtype(rme96); + change = (int)val != snd_rme96_getinputtype(rme96); snd_rme96_setinputtype(rme96, val); spin_unlock_irqrestore(&rme96->lock, flags); return change; @@ -2062,7 +2126,7 @@ val = ucontrol->value.enumerated.item[0] % 3; spin_lock_irqsave(&rme96->lock, flags); - change = val != snd_rme96_getclockmode(rme96); + change = (int)val != snd_rme96_getclockmode(rme96); snd_rme96_setclockmode(rme96, val); spin_unlock_irqrestore(&rme96->lock, flags); return change; @@ -2103,7 +2167,8 @@ val = ucontrol->value.enumerated.item[0] % 4; spin_lock_irqsave(&rme96->lock, flags); - change = val != snd_rme96_getattenuation(rme96); + + change = (int)val != snd_rme96_getattenuation(rme96); snd_rme96_setattenuation(rme96, val); spin_unlock_irqrestore(&rme96->lock, flags); return change; @@ -2144,7 +2209,7 @@ val = ucontrol->value.enumerated.item[0] % 4; spin_lock_irqsave(&rme96->lock, flags); - change = val != snd_rme96_getmontracks(rme96); + change = (int)val != snd_rme96_getmontracks(rme96); snd_rme96_setmontracks(rme96, val); spin_unlock_irqrestore(&rme96->lock, flags); return change; diff -Nru a/sound/pci/rme9652/Makefile b/sound/pci/rme9652/Makefile --- a/sound/pci/rme9652/Makefile Sun Feb 9 21:13:33 2003 +++ b/sound/pci/rme9652/Makefile Sun Feb 9 21:13:33 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := hammerfall_mem.o - snd-hammerfall-mem-objs := hammerfall_mem.o snd-rme9652-objs := rme9652.o snd-hdsp-objs := hdsp.o diff -Nru a/sound/pci/rme9652/hammerfall_mem.c b/sound/pci/rme9652/hammerfall_mem.c --- a/sound/pci/rme9652/hammerfall_mem.c Sun Feb 9 21:13:29 2003 +++ b/sound/pci/rme9652/hammerfall_mem.c Sun Feb 9 21:13:29 2003 @@ -25,7 +25,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - $Id: hammerfall_mem.c,v 1.5 2002/11/04 09:11:42 perex Exp $ + $Id: hammerfall_mem.c,v 1.7 2003/01/06 14:21:28 perex Exp $ Tue Oct 17 2000 Jaroslav Kysela @@ -150,9 +150,10 @@ for (i = 0; i < NBUFS; i++) { rbuf = &hammerfall_buffers[i]; if (rbuf->flags == HAMMERFALL_BUF_ALLOCATED) { + if (! try_module_get(THIS_MODULE)) + return NULL; rbuf->flags |= HAMMERFALL_BUF_USED; rbuf->pci = pcidev; - MOD_INC_USE_COUNT; *dmaaddr = rbuf->addr; return rbuf->buf; } @@ -169,8 +170,8 @@ for (i = 0; i < NBUFS; i++) { rbuf = &hammerfall_buffers[i]; if (rbuf->buf == addr && rbuf->pci == pcidev) { - MOD_DEC_USE_COUNT; rbuf->flags &= ~HAMMERFALL_BUF_USED; + module_put(THIS_MODULE); return; } } @@ -178,7 +179,7 @@ printk ("Hammerfall memory allocator: unknown buffer address or PCI device ID"); } -static void __exit hammerfall_free_buffers (void) +static void hammerfall_free_buffers (void) { int i; diff -Nru a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c --- a/sound/pci/rme9652/hdsp.c Sun Feb 9 21:13:30 2003 +++ b/sound/pci/rme9652/hdsp.c Sun Feb 9 21:13:30 2003 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -368,7 +369,6 @@ snd_card_t *card; snd_pcm_t *pcm; struct pci_dev *pci; - snd_info_entry_t *proc_entry; snd_kcontrol_t *spdif_ctl; unsigned short mixer_matrix[HDSP_MATRIX_MIXER_SIZE]; }; @@ -461,7 +461,7 @@ */ for (i = 0; i < timeout; i++) - if ((hdsp_read (hdsp, HDSP_fifoStatus) & 0xff) <= count) + if ((int)(hdsp_read (hdsp, HDSP_fifoStatus) & 0xff) <= count) return 0; snd_printk ("wait for FIFO status <= %d failed after %d iterations\n", @@ -818,10 +818,18 @@ static inline int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id) { + int fifo_bytes_used; + if (id) { - return (hdsp_read(hdsp, HDSP_midiStatusOut1) & 0xff) < 128; + fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut1) & 0xff; + } else { + fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut0) & 0xff; + } + + if (fifo_bytes_used < 128) { + return 128 - fifo_bytes_used; } else { - return (hdsp_read(hdsp, HDSP_midiStatusOut0) & 0xff)< 128; + return 0; } } @@ -836,7 +844,6 @@ { unsigned long flags; int n_pending; - int clear_timer = 0; int to_write; int i; unsigned char buf[128]; @@ -848,23 +855,15 @@ if (hmidi->output) { if (!snd_rawmidi_transmit_empty (hmidi->output)) { if ((n_pending = snd_hdsp_midi_output_possible (hmidi->hdsp, hmidi->id)) > 0) { - if (n_pending > sizeof (buf)) + if (n_pending > (int)sizeof (buf)) n_pending = sizeof (buf); if ((to_write = snd_rawmidi_transmit (hmidi->output, buf, n_pending)) > 0) { for (i = 0; i < to_write; ++i) snd_hdsp_midi_write_byte (hmidi->hdsp, hmidi->id, buf[i]); - } else { - clear_timer = 1; } } - } else { - clear_timer = 1; } - - if (clear_timer && hmidi->istimer && --hmidi->istimer <= 0) { - del_timer(&hmidi->timer); - } } spin_unlock_irqrestore (&hmidi->lock, flags); @@ -882,7 +881,7 @@ if ((n_pending = snd_hdsp_midi_input_available (hmidi->hdsp, hmidi->id)) > 0) { if (hmidi->input) { - if (n_pending > sizeof (buf)) { + if (n_pending > (int)sizeof (buf)) { n_pending = sizeof (buf); } for (i = 0; i < n_pending; ++i) { @@ -972,6 +971,8 @@ } } spin_unlock_irqrestore (&hmidi->lock, flags); + if (up) + snd_hdsp_midi_output_write(hmidi); } static int snd_hdsp_midi_input_open(snd_rawmidi_substream_t * substream) @@ -1288,7 +1289,7 @@ return -EBUSY; val = ucontrol->value.integer.value[0] & 1; spin_lock_irqsave(&hdsp->lock, flags); - change = val != hdsp_spdif_out(hdsp); + change = (int)val != hdsp_spdif_out(hdsp); hdsp_set_spdif_output(hdsp, val); spin_unlock_irqrestore(&hdsp->lock, flags); return change; @@ -1403,7 +1404,7 @@ max = hdsp->ss_channels == (hdsp->type == Digiface) ? 7 : 6; val = ucontrol->value.enumerated.item[0] % max; spin_lock_irqsave(&hdsp->lock, flags); - change = val != hdsp_sync_pref(hdsp); + change = (int)val != hdsp_sync_pref(hdsp); hdsp_set_sync_pref(hdsp, val); spin_unlock_irqrestore(&hdsp->lock, flags); return change; @@ -1507,7 +1508,7 @@ return -EBUSY; val = ucontrol->value.integer.value[0] & 1; spin_lock_irqsave(&hdsp->lock, flags); - change = val != hdsp_line_out(hdsp); + change = (int)val != hdsp_line_out(hdsp); hdsp_set_line_output(hdsp, val); spin_unlock_irqrestore(&hdsp->lock, flags); return change; @@ -1576,7 +1577,8 @@ gain = ucontrol->value.integer.value[2]; spin_lock_irqsave(&hdsp->lock, flags); - if ((change = gain != hdsp_read_gain(hdsp, addr))) + change = gain != hdsp_read_gain(hdsp, addr); + if (change) hdsp_write_gain(hdsp, addr, gain); spin_unlock_irqrestore(&hdsp->lock, flags); return change; @@ -1654,7 +1656,8 @@ spin_lock_irqsave(&hdsp->lock, flags); - if ((change = gain != hdsp_read_gain(hdsp, addr))) + change = gain != hdsp_read_gain(hdsp, addr); + if (change) hdsp_write_gain(hdsp, addr, gain); spin_unlock_irqrestore(&hdsp->lock, flags); return change; @@ -1826,7 +1829,8 @@ int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp) { - int idx, err, limit; + unsigned int idx, limit; + int err; snd_kcontrol_t *kctl; for (idx = 0; idx < HDSP_CONTROLS; idx++) { @@ -2076,27 +2080,8 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(hdsp->card, "hdsp", hdsp->card->proc_root)) != - NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = hdsp; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 256; - entry->c.text.read = snd_hdsp_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - hdsp->proc_entry = entry; -} - -static void snd_hdsp_proc_done(hdsp_t *hdsp) -{ - if (hdsp->proc_entry) { - snd_info_unregister(hdsp->proc_entry); - hdsp->proc_entry = NULL; - } + if (! snd_card_proc_new(hdsp->card, "hdsp", &entry)) + snd_info_set_text_ops(entry, hdsp, snd_hdsp_proc_read); } static void snd_hdsp_free_buffers(hdsp_t *hdsp) @@ -2413,7 +2398,7 @@ that matter are the same. */ - if (params_rate(params) != hdsp_system_sample_rate(hdsp)) { + if ((int)params_rate(params) != hdsp_system_sample_rate(hdsp)) { spin_unlock_irq(&hdsp->lock); _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); return -EBUSY; @@ -2589,9 +2574,9 @@ .rate_max = 96000, .channels_min = 14, .channels_max = HDSP_MAX_CHANNELS, - .buffer_bytes_max = 1024*1024, - .period_bytes_min = 1, - .period_bytes_max = 1024*1024, + .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, + .period_bytes_min = (64 * 4) *10, + .period_bytes_max = (8192 * 4) * HDSP_MAX_CHANNELS, .periods_min = 2, .periods_max = 2, .fifo_size = 0, @@ -2614,9 +2599,9 @@ .rate_max = 96000, .channels_min = 14, .channels_max = HDSP_MAX_CHANNELS, - .buffer_bytes_max = 1024*1024, - .period_bytes_min = 1, - .period_bytes_max = 1024*1024, + .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, + .period_bytes_min = (64 * 4) * 10, + .period_bytes_max = (8192 * 4) * HDSP_MAX_CHANNELS, .periods_min = 2, .periods_max = 2, .fifo_size = 0, @@ -3078,7 +3063,6 @@ if (hdsp->irq >= 0) free_irq(hdsp->irq, (void *)hdsp); - snd_hdsp_proc_done(hdsp); snd_hdsp_free_buffers(hdsp); if (hdsp->iobase) diff -Nru a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c --- a/sound/pci/rme9652/rme9652.c Sun Feb 9 21:13:31 2003 +++ b/sound/pci/rme9652/rme9652.c Sun Feb 9 21:13:31 2003 @@ -263,7 +263,6 @@ snd_card_t *card; snd_pcm_t *pcm; struct pci_dev *pci; - snd_info_entry_t *proc_entry; snd_kcontrol_t *spdif_ctl; } rme9652_t; @@ -375,7 +374,7 @@ static snd_pcm_uframes_t rme9652_hw_pointer(rme9652_t *rme9652) { int status; - int offset, frag; + unsigned int offset, frag; snd_pcm_uframes_t period_size = rme9652->period_bytes / 4; snd_pcm_sframes_t delta; @@ -390,7 +389,7 @@ delta = rme9652->prev_hw_offset - offset; delta &= 0xffff; - if (delta <= rme9652->max_jitter * 4) + if (delta <= (snd_pcm_sframes_t)rme9652->max_jitter * 4) offset = rme9652->prev_hw_offset; else rme9652->prev_hw_offset = offset; @@ -1103,7 +1102,7 @@ return -EBUSY; val = ucontrol->value.integer.value[0] & 1; spin_lock_irqsave(&rme9652->lock, flags); - change = val != rme9652_spdif_out(rme9652); + change = (int)val != rme9652_spdif_out(rme9652); rme9652_set_spdif_output(rme9652, val); spin_unlock_irqrestore(&rme9652->lock, flags); return change; @@ -1190,7 +1189,7 @@ val = ucontrol->value.enumerated.item[0] % 3; spin_lock_irqsave(&rme9652->lock, flags); - change = val != rme9652_sync_mode(rme9652); + change = (int)val != rme9652_sync_mode(rme9652); rme9652_set_sync_mode(rme9652, val); spin_unlock_irqrestore(&rme9652->lock, flags); return change; @@ -1287,7 +1286,7 @@ max = rme9652->ss_channels == RME9652_NCHANNELS ? 4 : 3; val = ucontrol->value.enumerated.item[0] % max; spin_lock_irqsave(&rme9652->lock, flags); - change = val != rme9652_sync_pref(rme9652); + change = (int)val != rme9652_sync_pref(rme9652); rme9652_set_sync_pref(rme9652, val); spin_unlock_irqrestore(&rme9652->lock, flags); return change; @@ -1601,7 +1600,8 @@ int snd_rme9652_create_controls(snd_card_t *card, rme9652_t *rme9652) { - int idx, err; + unsigned int idx; + int err; snd_kcontrol_t *kctl; for (idx = 0; idx < RME9652_CONTROLS; idx++) { @@ -1803,27 +1803,8 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(rme9652->card, "rme9652", rme9652->card->proc_root)) != - NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = rme9652; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 256; - entry->c.text.read = snd_rme9652_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - rme9652->proc_entry = entry; -} - -static void snd_rme9652_proc_done(rme9652_t *rme9652) -{ - if (rme9652->proc_entry) { - snd_info_unregister(rme9652->proc_entry); - rme9652->proc_entry = NULL; - } + if (! snd_card_proc_new(rme9652->card, "rme9652", &entry)) + snd_info_set_text_ops(entry, rme9652, snd_rme9652_proc_read); } static void snd_rme9652_free_buffers(rme9652_t *rme9652) @@ -1855,7 +1836,6 @@ { if (rme9652->irq >= 0) rme9652_stop(rme9652); - snd_rme9652_proc_done(rme9652); snd_rme9652_free_buffers(rme9652); if (rme9652->iobase) @@ -2116,7 +2096,7 @@ that matter are the same. */ - if (params_rate(params) != + if ((int)params_rate(params) != rme9652_adat_sample_rate(rme9652)) { spin_unlock_irq(&rme9652->lock); _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); @@ -2288,9 +2268,9 @@ .rate_max = 96000, .channels_min = 10, .channels_max = 26, - .buffer_bytes_max = 1024*1024, - .period_bytes_min = 1, - .period_bytes_max = 1024*1024, + .buffer_bytes_max = RME9652_CHANNEL_BUFFER_BYTES * 26, + .period_bytes_min = (64 * 4) * 10, + .period_bytes_max = (8192 * 4) * 26, .periods_min = 2, .periods_max = 2, .fifo_size = 0, @@ -2311,9 +2291,9 @@ .rate_max = 96000, .channels_min = 10, .channels_max = 26, - .buffer_bytes_max = 1024*1024, - .period_bytes_min = 1, - .period_bytes_max = 1024*1024, + .buffer_bytes_max = RME9652_CHANNEL_BUFFER_BYTES *26, + .period_bytes_min = (64 * 4) * 10, + .period_bytes_max = (8192 * 4) * 26, .periods_min = 2, .periods_max = 2, .fifo_size = 0, diff -Nru a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c --- a/sound/pci/sonicvibes.c Sun Feb 9 21:13:34 2003 +++ b/sound/pci/sonicvibes.c Sun Feb 9 21:13:34 2003 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -37,9 +38,6 @@ #include #define SNDRV_GET_ID #include -#ifndef LINUX_2_2 -#include -#endif #include @@ -249,7 +247,6 @@ snd_hwdep_t *fmsynth; /* S3FM */ spinlock_t reg_lock; - snd_info_entry_t *proc_entry; unsigned int p_dma_size; unsigned int c_dma_size; @@ -257,7 +254,7 @@ snd_kcontrol_t *master_mute; snd_kcontrol_t *master_volume; -#ifndef LINUX_2_2 +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) struct gameport gameport; #endif }; @@ -1122,7 +1119,8 @@ { snd_card_t *card; snd_kcontrol_t *kctl; - int idx, err; + unsigned int idx; + int err; snd_assert(sonic != NULL && sonic->card != NULL, return -EINVAL); card = sonic->card; @@ -1177,26 +1175,8 @@ { snd_info_entry_t *entry; - if ((entry = snd_info_create_card_entry(sonic->card, "sonicvibes", sonic->card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = sonic; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 256; - entry->c.text.read = snd_sonicvibes_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - sonic->proc_entry = entry; -} - -static void snd_sonicvibes_proc_done(sonicvibes_t * sonic) -{ - if (sonic->proc_entry) { - snd_info_unregister(sonic->proc_entry); - sonic->proc_entry = NULL; - } + if (! snd_card_proc_new(sonic->card, "sonicvibes", &entry)) + snd_info_set_text_ops(entry, sonic, snd_sonicvibes_proc_read); } /* @@ -1208,11 +1188,10 @@ static int snd_sonicvibes_free(sonicvibes_t *sonic) { -#ifndef LINUX_2_2 +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) if (sonic->gameport.io) gameport_unregister_port(&sonic->gameport); #endif - snd_sonicvibes_proc_done(sonic); pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port); pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port); if (sonic->res_sb_port) { @@ -1440,7 +1419,8 @@ mpu401_t * mpu = snd_magic_cast(mpu401_t, rmidi->private_data, return -ENXIO); snd_card_t *card = sonic->card; snd_rawmidi_str_t *dir; - int idx, err; + unsigned int idx; + int err; mpu->private_data = sonic; mpu->open_input = snd_sonicvibes_midi_input_open; @@ -1512,7 +1492,7 @@ snd_card_free(card); return err; } -#ifndef LINUX_2_2 +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) sonic->gameport.io = sonic->game_port; gameport_register_port(&sonic->gameport); #endif diff -Nru a/sound/pci/trident/Makefile b/sound/pci/trident/Makefile --- a/sound/pci/trident/Makefile Sun Feb 9 21:13:34 2003 +++ b/sound/pci/trident/Makefile Sun Feb 9 21:13:34 2003 @@ -3,13 +3,17 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := trident_main.o - snd-trident-objs := trident.o trident_main.o trident_memory.o snd-trident-synth-objs := trident_synth.o +# +# this function returns: +# "m" - CONFIG_SND_SEQUENCER is m +# - CONFIG_SND_SEQUENCER is undefined +# otherwise parameter #1 value +# +sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) + # Toplevel Module Dependency obj-$(CONFIG_SND_TRIDENT) += snd-trident.o -ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y) - obj-$(CONFIG_SND_TRIDENT) += snd-trident-synth.o -endif +obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-trident-synth.o diff -Nru a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c --- a/sound/pci/trident/trident_main.c Sun Feb 9 21:13:33 2003 +++ b/sound/pci/trident/trident_main.c Sun Feb 9 21:13:33 2003 @@ -34,15 +34,14 @@ #include #include #include +#include #include #include #include #include #include -#ifndef LINUX_2_2 -#include -#endif +#include #include @@ -760,14 +759,14 @@ if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) return err; - if (err > 0 && trident->tlb.entries) { - if (voice->memblk) - snd_trident_free_pages(trident, voice->memblk); - spin_lock_irq(&trident->reg_lock); - voice->memblk = snd_trident_alloc_pages(trident, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); - spin_unlock_irq(&trident->reg_lock); - if (voice->memblk == NULL) - return -ENOMEM; + if (trident->tlb.entries) { + if (err > 0) { /* change */ + if (voice->memblk) + snd_trident_free_pages(trident, voice->memblk); + voice->memblk = snd_trident_alloc_pages(trident, substream); + if (voice->memblk == NULL) + return -ENOMEM; + } } return 0; } @@ -794,7 +793,7 @@ /* voice management */ - if (params_buffer_size(hw_params) / 2 != params_buffer_size(hw_params)) { + if (params_buffer_size(hw_params) / 2 != params_period_size(hw_params)) { if (evoice == NULL) { evoice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); if (evoice == NULL) @@ -853,9 +852,11 @@ snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; snd_trident_voice_t *evoice = voice ? voice->extra : NULL; - if (trident->tlb.entries && voice && voice->memblk) { - snd_trident_free_pages(trident, voice->memblk); - voice->memblk = NULL; + if (trident->tlb.entries) { + if (voice && voice->memblk) { + snd_trident_free_pages(trident, voice->memblk); + voice->memblk = NULL; + } } snd_pcm_lib_free_pages(substream); if (evoice != NULL) { @@ -992,10 +993,12 @@ outb(0x54, TRID_REG(trident, LEGACY_DMAR11)); // Set channel buffer Address - voice->LBA = runtime->dma_addr; - outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0)); + /* FIXME: LEGACY_DMAR0 correctly set? */ if (voice->memblk) voice->LBA = voice->memblk->offset; + else + voice->LBA = runtime->dma_addr; + outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0)); // set ESO ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1; @@ -1345,6 +1348,7 @@ voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, runtime->period_size); /* set Loop Back Address */ + /* FIXME: LBAO?? */ LBAO = runtime->dma_addr; if (voice->memblk) voice->LBA = voice->memblk->offset; @@ -1573,11 +1577,11 @@ cso = (unsigned int) inl(TRID_REG(trident, CH_NX_DELTA_CSO)) & 0x00ffffff; } - if (++cso > runtime->buffer_size) - cso = runtime->buffer_size; - spin_unlock(&trident->reg_lock); + if (++cso >= runtime->buffer_size) + cso = 0; + return cso; } @@ -1605,7 +1609,8 @@ result = inw(TRID_REG(trident, T4D_SBBL_SBCL)); if (runtime->channels > 1) result >>= 1; - result = runtime->buffer_size - result; + if (result > 0) + result = runtime->buffer_size - result; // printk("capture result = 0x%x, cso = 0x%x\n", result, cso); @@ -1759,15 +1764,12 @@ static void snd_trident_pcm_free_substream(snd_pcm_runtime_t *runtime) { - unsigned long flags; snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data; trident_t *trident; if (voice) { trident = voice->trident; - spin_lock_irqsave(&trident->reg_lock, flags); snd_trident_free_voice(trident, voice); - spin_unlock_irqrestore(&trident->reg_lock, flags); } } @@ -1777,13 +1779,9 @@ snd_pcm_runtime_t *runtime = substream->runtime; snd_trident_voice_t *voice; - spin_lock_irq(&trident->reg_lock); voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); - if (voice == NULL) { - spin_unlock_irq(&trident->reg_lock); + if (voice == NULL) return -EAGAIN; - } - spin_unlock_irq(&trident->reg_lock); snd_trident_pcm_mixer_build(trident, voice, substream); voice->substream = substream; runtime->private_data = voice; @@ -1830,12 +1828,9 @@ snd_trident_voice_t *voice; snd_pcm_runtime_t *runtime = substream->runtime; - spin_lock_irq(&trident->reg_lock); voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); - if (voice == NULL) { - spin_unlock_irq(&trident->reg_lock); + if (voice == NULL) return -EAGAIN; - } voice->spdif = 1; voice->substream = substream; trident->spdif_pcm_bits = trident->spdif_bits; @@ -1911,14 +1906,10 @@ snd_trident_voice_t *voice; snd_pcm_runtime_t *runtime = substream->runtime; - spin_lock_irq(&trident->reg_lock); voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); - if (voice == NULL) { - spin_unlock_irq(&trident->reg_lock); + if (voice == NULL) return -EAGAIN; - } voice->capture = 1; - spin_unlock_irq(&trident->reg_lock); voice->substream = substream; runtime->private_data = voice; runtime->private_free = snd_trident_pcm_free_substream; @@ -1959,23 +1950,11 @@ snd_trident_voice_t *voice; snd_pcm_runtime_t *runtime = substream->runtime; - spin_lock_irq(&trident->reg_lock); voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0); - if (voice == NULL) { - spin_unlock_irq(&trident->reg_lock); + if (voice == NULL) return -EAGAIN; - } - if (trident->tlb.entries) { - voice->memblk = snd_trident_alloc_pages(trident, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); - if (voice->memblk == NULL) { - snd_trident_free_voice(trident, voice); - spin_unlock_irq(&trident->reg_lock); - return -ENOMEM; - } - } - voice->substream = substream; voice->foldback_chan = substream->number; - spin_unlock_irq(&trident->reg_lock); + voice->substream = substream; runtime->private_data = voice; runtime->private_free = snd_trident_pcm_free_substream; runtime->hw = snd_trident_foldback; @@ -2021,6 +2000,18 @@ .pointer = snd_trident_playback_pointer, }; +static snd_pcm_ops_t snd_trident_nx_playback_ops = { + .open = snd_trident_playback_open, + .close = snd_trident_playback_close, + .ioctl = snd_trident_ioctl, + .hw_params = snd_trident_hw_params, + .hw_free = snd_trident_hw_free, + .prepare = snd_trident_playback_prepare, + .trigger = snd_trident_trigger, + .pointer = snd_trident_playback_pointer, + .page = snd_pcm_sgbuf_ops_page, +}; + static snd_pcm_ops_t snd_trident_capture_ops = { .open = snd_trident_capture_open, .close = snd_trident_capture_close, @@ -2032,6 +2023,18 @@ .pointer = snd_trident_capture_pointer, }; +static snd_pcm_ops_t snd_trident_nx_capture_ops = { + .open = snd_trident_capture_open, + .close = snd_trident_capture_close, + .ioctl = snd_trident_ioctl, + .hw_params = snd_trident_capture_hw_params, + .hw_free = snd_trident_hw_free, + .prepare = snd_trident_capture_prepare, + .trigger = snd_trident_trigger, + .pointer = snd_trident_capture_pointer, + .page = snd_pcm_sgbuf_ops_page, +}; + static snd_pcm_ops_t snd_trident_si7018_capture_ops = { .open = snd_trident_capture_open, .close = snd_trident_capture_close, @@ -2054,6 +2057,18 @@ .pointer = snd_trident_playback_pointer, }; +static snd_pcm_ops_t snd_trident_nx_foldback_ops = { + .open = snd_trident_foldback_open, + .close = snd_trident_foldback_close, + .ioctl = snd_trident_ioctl, + .hw_params = snd_trident_hw_params, + .hw_free = snd_trident_hw_free, + .prepare = snd_trident_foldback_prepare, + .trigger = snd_trident_trigger, + .pointer = snd_trident_playback_pointer, + .page = snd_pcm_sgbuf_ops_page, +}; + static snd_pcm_ops_t snd_trident_spdif_ops = { .open = snd_trident_spdif_open, .close = snd_trident_spdif_close, @@ -2065,6 +2080,18 @@ .pointer = snd_trident_spdif_pointer, }; +static snd_pcm_ops_t snd_trident_nx_spdif_ops = { + .open = snd_trident_spdif_open, + .close = snd_trident_spdif_close, + .ioctl = snd_trident_ioctl, + .hw_params = snd_trident_spdif_hw_params, + .hw_free = snd_trident_hw_free, + .prepare = snd_trident_spdif_prepare, + .trigger = snd_trident_trigger, + .pointer = snd_trident_spdif_pointer, + .page = snd_pcm_sgbuf_ops_page, +}; + static snd_pcm_ops_t snd_trident_spdif_7018_ops = { .open = snd_trident_spdif_open, .close = snd_trident_spdif_close, @@ -2131,18 +2158,26 @@ pcm->private_data = trident; pcm->private_free = snd_trident_pcm_free; - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + if (trident->tlb.entries) { + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_capture_ops); + } else { + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, trident->device != TRIDENT_DEVICE_ID_SI7018 ? - &snd_trident_capture_ops : - &snd_trident_si7018_capture_ops); + &snd_trident_capture_ops : + &snd_trident_si7018_capture_ops); + } pcm->info_flags = 0; pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; strcpy(pcm->name, "Trident 4DWave"); trident->pcm = pcm; - snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, pcm, 64*1024, 256*1024); + if (trident->tlb.entries) + snd_pcm_lib_preallocate_sg_pages_for_all(trident->pci, pcm); + else + snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, pcm, 64*1024, 128*1024); if (rpcm) *rpcm = pcm; @@ -2176,7 +2211,10 @@ foldback->private_data = trident; foldback->private_free = snd_trident_foldback_pcm_free; - snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_foldback_ops); + if (trident->tlb.entries) + snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_foldback_ops); + else + snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_foldback_ops); foldback->info_flags = 0; strcpy(foldback->name, "Trident 4DWave"); substream = foldback->streams[SNDRV_PCM_STREAM_CAPTURE].substream; @@ -2191,7 +2229,10 @@ } trident->foldback = foldback; - snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, foldback, 64*1024, 128*1024); + if (trident->tlb.entries) + snd_pcm_lib_preallocate_sg_pages_for_all(trident->pci, foldback); + else + snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, foldback, 64*1024, 128*1024); if (rpcm) *rpcm = foldback; @@ -2221,7 +2262,9 @@ spdif->private_data = trident; spdif->private_free = snd_trident_spdif_pcm_free; - if (trident->device != TRIDENT_DEVICE_ID_SI7018) { + if (trident->tlb.entries) { + snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_spdif_ops); + } else if (trident->device != TRIDENT_DEVICE_ID_SI7018) { snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops); } else { snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_7018_ops); @@ -2230,7 +2273,10 @@ strcpy(spdif->name, "Trident 4DWave IEC958"); trident->spdif = spdif; - snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, spdif, 64*1024, 128*1024); + if (trident->tlb.entries) + snd_pcm_lib_preallocate_sg_pages_for_all(trident->pci, spdif); + else + snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, spdif, 64*1024, 128*1024); if (rpcm) *rpcm = spdif; @@ -2888,7 +2934,7 @@ static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device) { - ac97_t _ac97, *ac97; + ac97_t _ac97; snd_card_t * card = trident->card; snd_kcontrol_t *kctl; snd_ctl_elem_value_t uctl; @@ -2902,7 +2948,7 @@ _ac97.private_data = trident; trident->ac97_detect = 1; __again: - if ((err = snd_ac97_mixer(trident->card, &_ac97, &ac97)) < 0) { + if ((err = snd_ac97_mixer(trident->card, &_ac97, &trident->ac97)) < 0) { if (trident->device == TRIDENT_DEVICE_ID_SI7018) { if ((err = snd_trident_sis_reset(trident)) < 0) return err; @@ -2987,7 +3033,7 @@ /* * gameport interface */ -#ifndef LINUX_2_2 +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) typedef struct snd_trident_gameport { struct gameport info; @@ -3076,7 +3122,22 @@ void __devinit snd_trident_gameport(trident_t *chip) { } +#endif /* CONFIG_GAMEPORT */ + +/* + * delay for 1 tick + */ +inline static void do_delay(trident_t *chip) +{ +#ifdef CONFIG_PM + if (chip->in_suspend) { + mdelay((1000 + HZ - 1) / HZ); + return; + } #endif + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); +} /* * SiS reset routine @@ -3088,7 +3149,7 @@ unsigned int i; int r; - r = 2; /* count of retries */ + r = trident->in_suspend ? 0 : 2; /* count of retries */ __si7018_retry: pci_write_config_byte(trident->pci, 0x46, 0x04); /* SOFTWARE RESET */ udelay(100); @@ -3109,15 +3170,13 @@ do { if ((inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)) & SI_AC97_PRIMARY_READY) != 0) goto __si7018_ok; - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); + do_delay(trident); } while (time_after_eq(end_time, jiffies)); snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL))); if (r-- > 0) { end_time = jiffies + HZ; do { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); + do_delay(trident); } while (time_after_eq(end_time, jiffies)); goto __si7018_retry; } @@ -3175,36 +3234,195 @@ static void __devinit snd_trident_proc_init(trident_t * trident) { snd_info_entry_t *entry; - char *s = "trident"; + const char *s = "trident"; if (trident->device == TRIDENT_DEVICE_ID_SI7018) s = "sis7018"; - if ((entry = snd_info_create_card_entry(trident->card, s, trident->card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = trident; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 256; - entry->c.text.read = snd_trident_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } + if (! snd_card_proc_new(trident->card, s, &entry)) + snd_info_set_text_ops(entry, trident, snd_trident_proc_read); +} + +static int snd_trident_dev_free(snd_device_t *device) +{ + trident_t *trident = snd_magic_cast(trident_t, device->device_data, return -ENXIO); + return snd_trident_free(trident); +} + +/*--------------------------------------------------------------------------- + snd_trident_tlb_alloc + + Description: Allocate and set up the TLB page table on 4D NX. + Each entry has 4 bytes (physical PCI address). + + Paramters: trident - pointer to target device class for 4DWave. + + Returns: 0 or negative error code + + ---------------------------------------------------------------------------*/ + +static int __devinit snd_trident_tlb_alloc(trident_t *trident) +{ + int i; + + /* TLB array must be aligned to 16kB !!! so we allocate + 32kB region and correct offset when necessary */ + + trident->tlb.buffer = snd_malloc_pci_pages(trident->pci, 2 * SNDRV_TRIDENT_MAX_PAGES * 4, &trident->tlb.buffer_dmaaddr); + if (trident->tlb.buffer == NULL) { + snd_printk(KERN_ERR "trident: unable to allocate TLB buffer\n"); + return -ENOMEM; } - trident->proc_entry = entry; + trident->tlb.entries = (unsigned int*)(((unsigned long)trident->tlb.buffer + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1)); + trident->tlb.entries_dmaaddr = (trident->tlb.buffer_dmaaddr + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1); + /* allocate shadow TLB page table (virtual addresses) */ + trident->tlb.shadow_entries = (unsigned long *)vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long)); + if (trident->tlb.shadow_entries == NULL) { + snd_printk(KERN_ERR "trident: unable to allocate shadow TLB entries\n"); + return -ENOMEM; + } + /* allocate and setup silent page and initialise TLB entries */ + trident->tlb.silent_page = snd_malloc_pci_pages(trident->pci, SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page_dmaaddr); + if (trident->tlb.silent_page == 0UL) { + snd_printk(KERN_ERR "trident: unable to allocate silent page\n"); + return -ENOMEM; + } + memset(trident->tlb.silent_page, 0, SNDRV_TRIDENT_PAGE_SIZE); + for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++) { + trident->tlb.entries[i] = cpu_to_le32(trident->tlb.silent_page_dmaaddr & ~(SNDRV_TRIDENT_PAGE_SIZE-1)); + trident->tlb.shadow_entries[i] = (unsigned long)trident->tlb.silent_page; + } + + /* use emu memory block manager code to manage tlb page allocation */ + trident->tlb.memhdr = snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE * SNDRV_TRIDENT_MAX_PAGES); + if (trident->tlb.memhdr == NULL) + return -ENOMEM; + + trident->tlb.memhdr->block_extra_size = sizeof(snd_trident_memblk_arg_t); + return 0; +} + +/* + * initialize 4D DX chip + */ + +static void snd_trident_stop_all_voices(trident_t *trident) +{ + outl(0xffffffff, TRID_REG(trident, T4D_STOP_A)); + outl(0xffffffff, TRID_REG(trident, T4D_STOP_B)); + outl(0, TRID_REG(trident, T4D_AINTEN_A)); + outl(0, TRID_REG(trident, T4D_AINTEN_B)); +} + +static int snd_trident_4d_dx_init(trident_t *trident) +{ + struct pci_dev *pci = trident->pci; + signed long end_time; + + /* reset the legacy configuration and whole audio/wavetable block */ + pci_write_config_dword(pci, 0x40, 0); /* DDMA */ + pci_write_config_byte(pci, 0x44, 0); /* ports */ + pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */ + pci_write_config_byte(pci, 0x46, 4); /* reset */ + udelay(100); + pci_write_config_byte(pci, 0x46, 0); /* release reset */ + udelay(100); + + /* warm reset of the AC'97 codec */ + outl(0x00000001, TRID_REG(trident, DX_ACR2_AC97_COM_STAT)); + udelay(100); + outl(0x00000000, TRID_REG(trident, DX_ACR2_AC97_COM_STAT)); + /* DAC on, disable SB IRQ and try to force ADC valid signal */ + trident->ac97_ctrl = 0x0000004a; + outl(trident->ac97_ctrl, TRID_REG(trident, DX_ACR2_AC97_COM_STAT)); + /* wait, until the codec is ready */ + end_time = (jiffies + (HZ * 3) / 4) + 1; + do { + if ((inl(TRID_REG(trident, DX_ACR2_AC97_COM_STAT)) & 0x0010) != 0) + goto __dx_ok; + do_delay(trident); + } while (time_after_eq(end_time, jiffies)); + snd_printk(KERN_ERR "AC'97 codec ready error\n"); + return -EIO; + + __dx_ok: + snd_trident_stop_all_voices(trident); + + return 0; } -static void snd_trident_proc_done(trident_t * trident) +/* + * initialize 4D NX chip + */ +static int snd_trident_4d_nx_init(trident_t *trident) { - if (trident->proc_entry) { - snd_info_unregister(trident->proc_entry); - trident->proc_entry = NULL; + struct pci_dev *pci = trident->pci; + signed long end_time; + + /* reset the legacy configuration and whole audio/wavetable block */ + pci_write_config_dword(pci, 0x40, 0); /* DDMA */ + pci_write_config_byte(pci, 0x44, 0); /* ports */ + pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */ + + pci_write_config_byte(pci, 0x46, 1); /* reset */ + udelay(100); + pci_write_config_byte(pci, 0x46, 0); /* release reset */ + udelay(100); + + /* warm reset of the AC'97 codec */ + outl(0x00000001, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); + udelay(100); + outl(0x00000000, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); + /* wait, until the codec is ready */ + end_time = (jiffies + (HZ * 3) / 4) + 1; + do { + if ((inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)) & 0x0008) != 0) + goto __nx_ok; + do_delay(trident); + } while (time_after_eq(end_time, jiffies)); + snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT))); + return -EIO; + + __nx_ok: + /* DAC on */ + trident->ac97_ctrl = 0x00000002; + outl(trident->ac97_ctrl, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); + /* disable SB IRQ */ + outl(NX_SB_IRQ_DISABLE, TRID_REG(trident, T4D_MISCINT)); + + snd_trident_stop_all_voices(trident); + + if (trident->tlb.entries != NULL) { + unsigned int i; + /* enable virtual addressing via TLB */ + i = trident->tlb.entries_dmaaddr; + i |= 0x00000001; + outl(i, TRID_REG(trident, NX_TLBC)); + } else { + outl(0, TRID_REG(trident, NX_TLBC)); } + /* initialize S/PDIF */ + outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); + outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); + + return 0; } -static int snd_trident_dev_free(snd_device_t *device) +/* + * initialize sis7018 chip + */ +static int snd_trident_sis_init(trident_t *trident) { - trident_t *trident = snd_magic_cast(trident_t, device->device_data, return -ENXIO); - return snd_trident_free(trident); + int err; + + if ((err = snd_trident_sis_reset(trident)) < 0) + return err; + + snd_trident_stop_all_voices(trident); + + /* initialize S/PDIF */ + outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); + + return 0; } /*--------------------------------------------------------------------------- @@ -3231,9 +3449,7 @@ trident_t ** rtrident) { trident_t *trident; - unsigned int i; - int err; - signed long end_time; + int i, err; snd_trident_voice_t *voice; snd_trident_pcm_mixer_t *tmix; static snd_device_ops_t ops = { @@ -3292,151 +3508,39 @@ trident->tlb.entries = NULL; trident->tlb.buffer = NULL; if (trident->device == TRIDENT_DEVICE_ID_NX) { - /* allocate and setup TLB page table */ - /* each entry has 4 bytes (physical PCI address) */ - /* TLB array must be aligned to 16kB !!! so we allocate - 32kB region and correct offset when necessary */ - trident->tlb.buffer = snd_malloc_pci_pages(trident->pci, 2 * SNDRV_TRIDENT_MAX_PAGES * 4, &trident->tlb.buffer_dmaaddr); - if (trident->tlb.buffer == NULL) { + if ((err = snd_trident_tlb_alloc(trident)) < 0) { snd_trident_free(trident); - snd_printk("unable to allocate TLB buffer\n"); - return -ENOMEM; - } - trident->tlb.entries = (unsigned int*)(((unsigned long)trident->tlb.buffer + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1)); - trident->tlb.entries_dmaaddr = (trident->tlb.buffer_dmaaddr + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1); - /* allocate shadow TLB page table (virtual addresses) */ - trident->tlb.shadow_entries = (unsigned long *)vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long)); - if (trident->tlb.shadow_entries == NULL) { - snd_trident_free(trident); - snd_printk("unable to allocate shadow TLB entries\n"); - return -ENOMEM; - } - /* allocate and setup silent page and initialise TLB entries */ - trident->tlb.silent_page = snd_malloc_pci_pages(trident->pci, SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page_dmaaddr); - if (trident->tlb.silent_page == 0UL) { - snd_trident_free(trident); - snd_printk("unable to allocate silent page\n"); - return -ENOMEM; - } - memset(trident->tlb.silent_page, 0, SNDRV_TRIDENT_PAGE_SIZE); - for (i = 0; i < SNDRV_TRIDENT_MAX_PAGES; i++) { - trident->tlb.entries[i] = cpu_to_le32(trident->tlb.silent_page_dmaaddr & ~(SNDRV_TRIDENT_PAGE_SIZE-1)); - trident->tlb.shadow_entries[i] = (unsigned long)trident->tlb.silent_page; - } - - /* use emu memory block manager code to manage tlb page allocation */ - trident->tlb.memhdr = snd_util_memhdr_new(SNDRV_TRIDENT_PAGE_SIZE * SNDRV_TRIDENT_MAX_PAGES); - if (trident->tlb.memhdr == NULL) { - snd_trident_free(trident); - return -ENOMEM; + return err; } - trident->tlb.memhdr->block_extra_size = sizeof(snd_trident_memblk_arg_t); } - /* reset the legacy configuration and whole audio/wavetable block */ - if (trident->device == TRIDENT_DEVICE_ID_DX || - trident->device == TRIDENT_DEVICE_ID_NX) { - pci_write_config_dword(pci, 0x40, 0); /* DDMA */ - pci_write_config_byte(pci, 0x44, 0); /* ports */ - pci_write_config_byte(pci, 0x45, 0); /* Legacy DMA */ - if (trident->device == TRIDENT_DEVICE_ID_DX) { - pci_write_config_byte(pci, 0x46, 4); /* reset */ - udelay(100); - pci_write_config_byte(pci, 0x46, 0); /* release reset */ - udelay(100); - } else /* NX */ { - pci_write_config_byte(pci, 0x46, 1); /* reset */ - udelay(100); - pci_write_config_byte(pci, 0x46, 0); /* release reset */ - udelay(100); - } - } - - /* initialize chip */ + trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF; + /* initialize chip */ switch (trident->device) { case TRIDENT_DEVICE_ID_DX: - /* warm reset of the AC'97 codec */ - outl(0x00000001, TRID_REG(trident, DX_ACR2_AC97_COM_STAT)); - udelay(100); - outl(0x00000000, TRID_REG(trident, DX_ACR2_AC97_COM_STAT)); - /* DAC on, disable SB IRQ and try to force ADC valid signal */ - trident->ac97_ctrl = 0x0000004a; - outl(trident->ac97_ctrl, TRID_REG(trident, DX_ACR2_AC97_COM_STAT)); - /* wait, until the codec is ready */ - end_time = (jiffies + (HZ * 3) / 4) + 1; - do { - if ((inl(TRID_REG(trident, DX_ACR2_AC97_COM_STAT)) & 0x0010) != 0) - goto __dx_ok; - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); - } while (end_time - (signed long)jiffies >= 0); - snd_printk("AC'97 codec ready error\n"); - snd_trident_free(trident); - return -EIO; - __dx_ok: + err = snd_trident_4d_dx_init(trident); break; case TRIDENT_DEVICE_ID_NX: - /* warm reset of the AC'97 codec */ - outl(0x00000001, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); - udelay(100); - outl(0x00000000, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); - /* wait, until the codec is ready */ - end_time = (jiffies + (HZ * 3) / 4) + 1; - do { - if ((inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT)) & 0x0008) != 0) - goto __nx_ok; - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1); - } while (end_time - (signed long)jiffies >= 0); - snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT))); - snd_trident_free(trident); - return -EIO; - __nx_ok: - /* DAC on */ - trident->ac97_ctrl = 0x00000002; - outl(trident->ac97_ctrl, TRID_REG(trident, NX_ACR0_AC97_COM_STAT)); - /* disable SB IRQ */ - outl(NX_SB_IRQ_DISABLE, TRID_REG(trident, T4D_MISCINT)); + err = snd_trident_4d_nx_init(trident); break; case TRIDENT_DEVICE_ID_SI7018: - if ((err = snd_trident_sis_reset(trident)) < 0) { - snd_trident_free(trident); - return err; - } + err = snd_trident_sis_init(trident); + break; + default: + snd_BUG(); + break; + } + if (err < 0) { + snd_trident_free(trident); + return err; } - - outl(0xffffffff, TRID_REG(trident, T4D_STOP_A)); - outl(0xffffffff, TRID_REG(trident, T4D_STOP_B)); - outl(0, TRID_REG(trident, T4D_AINTEN_A)); - outl(0, TRID_REG(trident, T4D_AINTEN_B)); if ((err = snd_trident_mixer(trident, pcm_spdif_device)) < 0) { snd_trident_free(trident); return err; } - if (trident->device == TRIDENT_DEVICE_ID_NX) { - if (trident->tlb.entries != NULL) { - /* enable virtual addressing via TLB */ - i = trident->tlb.entries_dmaaddr; - i |= 0x00000001; - outl(i, TRID_REG(trident, NX_TLBC)); - } else { - outl(0, TRID_REG(trident, NX_TLBC)); - } - /* initialize S/PDIF */ - trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF; - outl(trident->spdif_bits, TRID_REG(trident, NX_SPCSTATUS)); - outb(trident->spdif_ctrl, TRID_REG(trident, NX_SPCTRL_SPCSO + 3)); - } - - if (trident->device == TRIDENT_DEVICE_ID_SI7018) { - /* initialize S/PDIF */ - trident->spdif_bits = trident->spdif_pcm_bits = SNDRV_PCM_DEFAULT_CON_SPDIF; - outl(trident->spdif_bits, TRID_REG(trident, SI_SPDIF_CS)); - } - /* initialise synth voices */ for (i = 0; i < 64; i++) { voice = &trident->synth.voices[i]; @@ -3482,7 +3586,7 @@ int snd_trident_free(trident_t *trident) { -#ifndef LINUX_2_2 +#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) if (trident->gameport) { gameport_unregister_port(&trident->gameport->info); kfree(trident->gameport); @@ -3495,7 +3599,6 @@ else if (trident->device == TRIDENT_DEVICE_ID_SI7018) { outl(0, TRID_REG(trident, SI_SERIAL_INTF_CTRL)); } - snd_trident_proc_done(trident); if (trident->tlb.buffer) { outl(0, TRID_REG(trident, NX_TLBC)); if (trident->tlb.memhdr) @@ -3568,10 +3671,10 @@ delta = (int)stimer - (int)voice->stimer; if (delta < 0) delta = -delta; - if (delta < voice->spurious_threshold) { + if ((unsigned int)delta < voice->spurious_threshold) { /* do some statistics here */ trident->spurious_irq_count++; - if (trident->spurious_irq_max_delta < delta) + if (trident->spurious_irq_max_delta < (unsigned int)delta) trident->spurious_irq_max_delta = delta; continue; } @@ -3656,6 +3759,7 @@ pvoice->capture = 0; pvoice->spdif = 0; pvoice->memblk = NULL; + pvoice->substream = NULL; spin_unlock_irqrestore(&trident->voice_alloc, flags); return pvoice; } @@ -3734,9 +3838,9 @@ { snd_card_t *card = trident->card; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D3hot) - goto __skip; + return; + trident->in_suspend = 1; snd_pcm_suspend_all(trident->pcm); if (trident->foldback) snd_pcm_suspend_all(trident->foldback); @@ -3750,27 +3854,40 @@ break; } snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - __skip: - snd_power_unlock(card); } void snd_trident_resume(trident_t *trident) { snd_card_t *card = trident->card; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D0) - goto __skip; + return; + + pci_enable_device(trident->pci); + pci_set_dma_mask(trident->pci, 0x3fffffff); /* to be sure */ + pci_set_master(trident->pci); /* to be sure */ + switch (trident->device) { case TRIDENT_DEVICE_ID_DX: + snd_trident_4d_dx_init(trident); + break; case TRIDENT_DEVICE_ID_NX: - break; /* TODO */ + snd_trident_4d_nx_init(trident); + break; case TRIDENT_DEVICE_ID_SI7018: + snd_trident_sis_init(trident); break; } + + snd_ac97_resume(trident->ac97); + + /* restore some registers */ + outl(trident->musicvol_wavevol, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL)); + + snd_trident_enable_eso(trident); + snd_power_change_state(card, SNDRV_CTL_POWER_D0); - __skip: - snd_power_unlock(card); + trident->in_suspend = 0; } static int snd_trident_set_power_state(snd_card_t *card, unsigned int power_state) diff -Nru a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c --- a/sound/pci/trident/trident_memory.c Sun Feb 9 21:13:34 2003 +++ b/sound/pci/trident/trident_memory.c Sun Feb 9 21:13:34 2003 @@ -28,6 +28,7 @@ #include #include #include +#include /* page arguments of these two macros are Trident page (4096 bytes), not like * aligned pages in others @@ -166,9 +167,8 @@ /* * check if the given pointer is valid for pages */ -static int is_valid_page(void *pages) +static int is_valid_page(unsigned long ptr) { - unsigned long ptr = (unsigned long)virt_to_phys(pages); if (ptr & ~0x3fffffffUL) { snd_printk("max memory size is 1GB!!\n"); return 0; @@ -184,33 +184,42 @@ * page allocation for DMA */ snd_util_memblk_t * -snd_trident_alloc_pages(trident_t *trident, void *pages, dma_addr_t addr, unsigned long size) +snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream) { - unsigned long ptr; snd_util_memhdr_t *hdr; snd_util_memblk_t *blk; - int page; + int idx, page; + struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, _snd_pcm_substream_sgbuf(substream), return NULL); snd_assert(trident != NULL, return NULL); - snd_assert(size > 0 && size < SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL); + snd_assert(sgbuf->size > 0 && sgbuf->size < SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL); hdr = trident->tlb.memhdr; snd_assert(hdr != NULL, return NULL); - if (! is_valid_page(pages)) - return NULL; - down(&hdr->block_mutex); - blk = search_empty(hdr, size); + blk = search_empty(hdr, sgbuf->size); if (blk == NULL) { up(&hdr->block_mutex); return NULL; } + if (lastpg(blk) - firstpg(blk) >= sgbuf->pages) { + snd_printk(KERN_ERR "page calculation doesn't match: allocated pages = %d, trident = %d/%d\n", sgbuf->pages, firstpg(blk), lastpg(blk)); + __snd_util_mem_free(hdr, blk); + up(&hdr->block_mutex); + return NULL; + } + /* set TLB entries */ - ptr = (unsigned long)pages; - for (page = firstpg(blk); page <= lastpg(blk); page++) { + idx = 0; + for (page = firstpg(blk); page <= lastpg(blk); page++, idx++) { + dma_addr_t addr = sgbuf->table[idx].addr; + unsigned long ptr = (unsigned long)sgbuf->table[idx].buf; + if (! is_valid_page(addr)) { + __snd_util_mem_free(hdr, blk); + up(&hdr->block_mutex); + return NULL; + } set_tlb_bus(trident, page, ptr, addr); - ptr += ALIGN_PAGE_SIZE; - addr += ALIGN_PAGE_SIZE; } up(&hdr->block_mutex); return blk; @@ -301,7 +310,8 @@ void *ptr = page_to_ptr(trident, page); dma_addr_t addr = page_to_addr(trident, page); set_silent_tlb(trident, page); - snd_free_pci_pages(trident->pci, ALIGN_PAGE_SIZE, ptr, addr); + if (ptr) + snd_free_pci_pages(trident->pci, ALIGN_PAGE_SIZE, ptr, addr); } /* check new allocation range */ @@ -346,7 +356,7 @@ ptr = snd_malloc_pci_pages(hw->pci, ALIGN_PAGE_SIZE, &addr); if (ptr == NULL) goto __fail; - if (! is_valid_page(ptr)) { + if (! is_valid_page(addr)) { snd_free_pci_pages(hw->pci, ALIGN_PAGE_SIZE, ptr, addr); goto __fail; } diff -Nru a/sound/pci/trident/trident_synth.c b/sound/pci/trident/trident_synth.c --- a/sound/pci/trident/trident_synth.c Sun Feb 9 21:13:31 2003 +++ b/sound/pci/trident/trident_synth.c Sun Feb 9 21:13:31 2003 @@ -392,7 +392,7 @@ break; } else { /* attenuate right (pan left) */ for (voice->Pan = 0; voice->Pan < 63; voice->Pan++ ) - if (volume->lr >= pan_table[voice->Pan] ) + if ((unsigned int)volume->lr >= pan_table[voice->Pan] ) break; voice->Pan |= 0x40; } @@ -746,7 +746,7 @@ snd_trident_port_t *port = (snd_trident_port_t *) private_data; trident_t *trident = port->trident; snd_trident_voice_t *voice; - int idx; + unsigned int idx; unsigned long flags; if (info->voices > 32) @@ -909,6 +909,7 @@ SNDRV_SEQ_PORT_TYPE_MIDI_GS | SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE | SNDRV_SEQ_PORT_TYPE_SYNTH, + 16, name); if (p->chset->port < 0) { result = p->chset->port; diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c --- a/sound/pci/via82xx.c Sun Feb 9 21:13:30 2003 +++ b/sound/pci/via82xx.c Sun Feb 9 21:13:30 2003 @@ -23,6 +23,26 @@ * */ +/* + * Changes: + * + * Dec. 19, 2002 Takashi Iwai + * - use the DSX channels for the first pcm playback. + * (on VIA8233, 8233C and 8235 only) + * this will allow you play simultaneously up to 4 streams. + * multi-channel playback is assigned to the second device + * on these chips. + * - support the secondary capture (on VIA8233/C,8235) + * - SPDIF support + * the DSX3 channel can be used for SPDIF output. + * on VIA8233A, this channel is assigned to the second pcm + * playback. + * the card config of alsa-lib will assign the correct + * device for applications. + * - clean up the code, separate low-level initialization + * routines for each chipset. + */ + #include #include #include @@ -40,11 +60,15 @@ #define SNDRV_GET_ID #include +#if 0 +#define POINTER_DEBUG +#endif + MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("VIA VT82xx audio"); MODULE_LICENSE("GPL"); MODULE_CLASSES("{sound}"); -MODULE_DEVICES("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/B/C}}"); +MODULE_DEVICES("{{VIA,VT82C686A/B/C,pci},{VIA,VT8233A/C,8235}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -64,7 +88,7 @@ MODULE_PARM(mpu_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l"); MODULE_PARM_DESC(mpu_port, "MPU-401 port."); MODULE_PARM_SYNTAX(mpu_port, SNDRV_PORT_DESC); -MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "l"); +MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:48000"); @@ -77,6 +101,14 @@ #define PCI_DEVICE_ID_VIA_8233_5 0x3059 #endif +/* revision numbers for via686 */ +#define VIA_REV_686_A 0x10 +#define VIA_REV_686_B 0x11 +#define VIA_REV_686_C 0x12 +#define VIA_REV_686_D 0x13 +#define VIA_REV_686_E 0x14 +#define VIA_REV_686_H 0x20 + /* revision numbers for via8233 */ #define VIA_REV_PRE_8233 0x10 /* not in market */ #define VIA_REV_8233C 0x20 /* 2 rec, 4 pb, 1 multi-pb */ @@ -89,6 +121,7 @@ */ #define VIAREG(via, x) ((via)->port + VIA_REG_##x) +#define VIADEV_REG(viadev, x) ((viadev)->port + VIA_REG_##x) /* common offsets */ #define VIA_REG_OFFSET_STATUS 0x00 /* byte - channel status */ @@ -156,21 +189,51 @@ #define VIA_REG_AC97_CMD_MASK 0x7e #define VIA_REG_AC97_DATA_SHIFT 0 #define VIA_REG_AC97_DATA_MASK 0xffff + #define VIA_REG_SGD_SHADOW 0x84 /* dword */ +/* via686 */ +#define VIA_REG_SGD_STAT_PB_FLAG (1<<0) +#define VIA_REG_SGD_STAT_CP_FLAG (1<<1) +#define VIA_REG_SGD_STAT_FM_FLAG (1<<2) +#define VIA_REG_SGD_STAT_PB_EOL (1<<4) +#define VIA_REG_SGD_STAT_CP_EOL (1<<5) +#define VIA_REG_SGD_STAT_FM_EOL (1<<6) +#define VIA_REG_SGD_STAT_PB_STOP (1<<8) +#define VIA_REG_SGD_STAT_CP_STOP (1<<9) +#define VIA_REG_SGD_STAT_FM_STOP (1<<10) +#define VIA_REG_SGD_STAT_PB_ACTIVE (1<<12) +#define VIA_REG_SGD_STAT_CP_ACTIVE (1<<13) +#define VIA_REG_SGD_STAT_FM_ACTIVE (1<<14) +/* via8233 */ +#define VIA8233_REG_SGD_STAT_FLAG (1<<0) +#define VIA8233_REG_SGD_STAT_EOL (1<<1) +#define VIA8233_REG_SGD_STAT_STOP (1<<2) +#define VIA8233_REG_SGD_STAT_ACTIVE (1<<3) +#define VIA8233_REG_SGD_SDX0_SHIFT 0 +#define VIA8233_REG_SGD_SDX1_SHIFT 4 +#define VIA8233_REG_SGD_SDX2_SHIFT 8 +#define VIA8233_REG_SGD_SDX3_SHIFT 12 +#define VIA8233_REG_SGD_MCHAN_SHIFT 16 +#define VIA8233_REG_SGD_REC0_SHIFT 24 +#define VIA8233_REG_SGD_REC1_SHIFT 28 + +#define VIA_REG_GPI_STATUS 0x88 +#define VIA_REG_GPI_INTR 0x8c /* multi-channel and capture registers for via8233 */ DEFINE_VIA_REGSET(MULTPLAY, 0x40); DEFINE_VIA_REGSET(CAPTURE_8233, 0x60); /* via8233-specific registers */ -#define VIA_REG_PLAYBACK_VOLUME_L 0x02 /* byte */ -#define VIA_REG_PLAYBACK_VOLUME_R 0x03 /* byte */ -#define VIA_REG_MULTPLAY_FORMAT 0x42 /* byte - format and channels */ +#define VIA_REG_OFS_PLAYBACK_VOLUME_L 0x02 /* byte */ +#define VIA_REG_OFS_PLAYBACK_VOLUME_R 0x03 /* byte */ +#define VIA_REG_OFS_MULTPLAY_FORMAT 0x02 /* byte - format and channels */ #define VIA_REG_MULTPLAY_FMT_8BIT 0x00 #define VIA_REG_MULTPLAY_FMT_16BIT 0x80 #define VIA_REG_MULTPLAY_FMT_CH_MASK 0x70 /* # channels << 4 (valid = 1,2,4,6) */ -#define VIA_REG_CAPTURE_FIFO 0x62 /* byte - bit 6 = fifo enable */ +#define VIA_REG_OFS_CAPTURE_FIFO 0x62 /* byte - bit 6 = fifo enable */ #define VIA_REG_CAPTURE_FIFO_ENABLE 0x40 + #define VIA_REG_CAPTURE_CHANNEL 0x63 /* byte - input select */ #define VIA_REG_CAPTURE_CHANNEL_MIC 0x4 #define VIA_REG_CAPTURE_CHANNEL_LINE 0 @@ -179,6 +242,53 @@ #define VIA_TBL_BIT_FLAG 0x40000000 #define VIA_TBL_BIT_EOL 0x80000000 +/* pci space */ +#define VIA_ACLINK_STAT 0x40 +#define VIA_ACLINK_C11_READY 0x20 +#define VIA_ACLINK_C10_READY 0x10 +#define VIA_ACLINK_C01_READY 0x04 /* secondary codec ready */ +#define VIA_ACLINK_LOWPOWER 0x02 /* low-power state */ +#define VIA_ACLINK_C00_READY 0x01 /* primary codec ready */ +#define VIA_ACLINK_CTRL 0x41 +#define VIA_ACLINK_CTRL_ENABLE 0x80 /* 0: disable, 1: enable */ +#define VIA_ACLINK_CTRL_RESET 0x40 /* 0: assert, 1: de-assert */ +#define VIA_ACLINK_CTRL_SYNC 0x20 /* 0: release SYNC, 1: force SYNC hi */ +#define VIA_ACLINK_CTRL_SDO 0x10 /* 0: release SDO, 1: force SDO hi */ +#define VIA_ACLINK_CTRL_VRA 0x08 /* 0: disable VRA, 1: enable VRA */ +#define VIA_ACLINK_CTRL_PCM 0x04 /* 0: disable PCM, 1: enable PCM */ +#define VIA_ACLINK_CTRL_FM 0x02 /* via686 only */ +#define VIA_ACLINK_CTRL_SB 0x01 /* via686 only */ +#define VIA_ACLINK_CTRL_INIT (VIA_ACLINK_CTRL_ENABLE|\ + VIA_ACLINK_CTRL_RESET|\ + VIA_ACLINK_CTRL_PCM|\ + VIA_ACLINK_CTRL_VRA) +#define VIA_FUNC_ENABLE 0x42 +#define VIA_FUNC_MIDI_PNP 0x80 /* FIXME: it's 0x40 in the datasheet! */ +#define VIA_FUNC_MIDI_IRQMASK 0x40 /* FIXME: not documented! */ +#define VIA_FUNC_RX2C_WRITE 0x20 +#define VIA_FUNC_SB_FIFO_EMPTY 0x10 +#define VIA_FUNC_ENABLE_GAME 0x08 +#define VIA_FUNC_ENABLE_FM 0x04 +#define VIA_FUNC_ENABLE_MIDI 0x02 +#define VIA_FUNC_ENABLE_SB 0x01 +#define VIA_PNP_CONTROL 0x43 +#define VIA_FM_NMI_CTRL 0x48 +#define VIA8233_VOLCHG_CTRL 0x48 +#define VIA8233_SPDIF_CTRL 0x49 +#define VIA8233_SPDIF_DX3 0x08 +#define VIA8233_SPDIF_SLOT_MASK 0x03 +#define VIA8233_SPDIF_SLOT_1011 0x00 +#define VIA8233_SPDIF_SLOT_34 0x01 +#define VIA8233_SPDIF_SLOT_78 0x02 +#define VIA8233_SPDIF_SLOT_69 0x03 + +/* + */ + +typedef struct _snd_via82xx via82xx_t; +typedef struct via_dev viadev_t; +#define chip_t via82xx_t + /* * pcm stream */ @@ -190,15 +300,21 @@ #define VIA_TABLE_SIZE 255 -typedef struct { - unsigned long reg_offset; +struct via_dev { + unsigned int reg_offset; + unsigned long port; + int direction; /* playback = 0, capture = 1 */ snd_pcm_substream_t *substream; int running; unsigned int tbl_entries; /* # descriptors */ u32 *table; /* physical address + flag */ dma_addr_t table_addr; struct snd_via_sg_table *idx_table; -} viadev_t; + /* for recovery from the unexpected pointer */ + unsigned int lastpos; + unsigned int bufsize; + unsigned int bufsize2; +}; /* @@ -208,10 +324,10 @@ */ static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream, struct pci_dev *pci, - int periods, int fragsize) + unsigned int periods, unsigned int fragsize) { - int i, idx, ofs, rest; - struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL); + unsigned int i, idx, ofs, rest; + struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); if (! dev->table) { /* the start of each lists must be aligned to 8 bytes, @@ -237,8 +353,13 @@ * over page boundary. */ do { - int r; + unsigned int r; unsigned int flag; + + if (idx >= VIA_TABLE_SIZE) { + snd_printk(KERN_ERR "via82xx: too much table size!\n"); + return -EINVAL; + } dev->table[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs)); r = PAGE_SIZE - (ofs % PAGE_SIZE); if (rest < r) @@ -257,13 +378,11 @@ dev->idx_table[idx].size = r; ofs += r; idx++; - if (idx >= VIA_TABLE_SIZE) { - snd_printk(KERN_ERR "via82xx: too much table size!\n"); - return -EINVAL; - } } while (rest > 0); } dev->tbl_entries = idx; + dev->bufsize = periods * fragsize; + dev->bufsize2 = dev->bufsize / 2; return 0; } @@ -285,10 +404,16 @@ /* */ -enum { TYPE_VIA686 = 1, TYPE_VIA8233 }; +enum { TYPE_CARD_VIA686 = 1, TYPE_CARD_VIA8233 }; +enum { TYPE_VIA686, TYPE_VIA8233, TYPE_VIA8233A }; -typedef struct _snd_via82xx via82xx_t; -#define chip_t via82xx_t +#define VIA_MAX_DEVS 7 /* 4 playback, 1 multi, 2 capture */ + +struct via_rate_lock { + spinlock_t lock; + int rate; + int used; +}; struct _snd_via82xx { int irq; @@ -301,12 +426,17 @@ unsigned char old_legacy; unsigned char old_legacy_cfg; + unsigned char playback_volume[2]; /* for VIA8233/C/8235; default = 0 */ + + unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */ + struct pci_dev *pci; snd_card_t *card; - snd_pcm_t *pcm; - viadev_t playback; - viadev_t capture; + unsigned int num_devs; + unsigned int playback_devno, multi_devno, capture_devno; + viadev_t devs[VIA_MAX_DEVS]; + struct via_rate_lock rates[2]; /* playback and capture */ snd_rawmidi_t *rmidi; @@ -320,8 +450,8 @@ }; static struct pci_device_id snd_via82xx_ids[] __devinitdata = { - { 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_VIA686, }, /* 686A */ - { 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_VIA8233, }, /* VT8233 */ + { 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */ + { 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, }, /* VT8233 */ { 0, } }; @@ -351,7 +481,7 @@ if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)) return val & 0xffff; } - snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_via82xx_codec_xread(chip)); + snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_via82xx_codec_xread(chip)); return -EIO; } @@ -367,7 +497,7 @@ if ((val = snd_via82xx_codec_xread(chip)) & stat) return val & 0xffff; } - snd_printk("codec_valid: codec %i is not valid [0x%x]\n", secondary, snd_via82xx_codec_xread(chip)); + snd_printk(KERN_ERR "codec_valid: codec %i is not valid [0x%x]\n", secondary, snd_via82xx_codec_xread(chip)); return -EIO; } @@ -429,24 +559,70 @@ static void snd_via82xx_channel_reset(via82xx_t *chip, viadev_t *viadev) { - unsigned long port = chip->port + viadev->reg_offset; - - outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET, port + VIA_REG_OFFSET_CONTROL); + outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET, + VIADEV_REG(viadev, OFFSET_CONTROL)); udelay(50); /* disable interrupts */ - outb(0x00, port + VIA_REG_OFFSET_CONTROL); + outb(0x00, VIADEV_REG(viadev, OFFSET_CONTROL)); /* clear interrupts */ - outb(0x03, port + VIA_REG_OFFSET_STATUS); - outb(0x00, port + VIA_REG_OFFSET_TYPE); /* for via686 */ - outl(0, port + VIA_REG_OFFSET_CURR_PTR); + outb(0x03, VIADEV_REG(viadev, OFFSET_STATUS)); + outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */ + // outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR)); + viadev->lastpos = 0; +} + + +/* + * Interrupt handler + */ + +static void snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + via82xx_t *chip = snd_magic_cast(via82xx_t, dev_id, return); + unsigned int status; + unsigned int i; + + spin_lock(&chip->reg_lock); + status = inl(VIAREG(chip, SGD_SHADOW)); + if (! (status & chip->intr_mask)) { + spin_unlock(&chip->reg_lock); + if (chip->rmidi) + /* check mpu401 interrupt */ + snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); + return; + } + + /* check status for each stream */ + for (i = 0; i < chip->num_devs; i++) { + viadev_t *viadev = &chip->devs[i]; + unsigned char status = inb(VIADEV_REG(viadev, OFFSET_STATUS)); + status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG); + if (! status) + continue; + outb(status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */ + if (viadev->substream && viadev->running) { + spin_unlock(&chip->reg_lock); + snd_pcm_period_elapsed(viadev->substream); + spin_lock(&chip->reg_lock); + } + } + spin_unlock(&chip->reg_lock); } -static int snd_via82xx_trigger(via82xx_t *chip, viadev_t *viadev, int cmd) +/* + * PCM callbacks + */ + +/* + * trigger callback + */ +static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd) { + via82xx_t *chip = snd_pcm_substream_chip(substream); + viadev_t *viadev = (viadev_t *)substream->runtime->private_data; unsigned char val; - unsigned long port = chip->port + viadev->reg_offset; - - if (chip->chip_type == TYPE_VIA8233) + + if (chip->chip_type != TYPE_VIA686) val = VIA_REG_CTRL_INT; else val = 0; @@ -469,124 +645,121 @@ default: return -EINVAL; } - outb(val, port + VIA_REG_OFFSET_CONTROL); + outb(val, VIADEV_REG(viadev, OFFSET_CONTROL)); if (cmd == SNDRV_PCM_TRIGGER_STOP) snd_via82xx_channel_reset(chip, viadev); return 0; } -static int snd_via82xx_set_format(via82xx_t *chip, viadev_t *viadev, - snd_pcm_substream_t *substream) +/* + * pointer callbacks + */ + +/* + * calculate the linear position at the given sg-buffer index and the rest count + */ +static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count) { - snd_pcm_runtime_t *runtime = substream->runtime; - unsigned long port = chip->port + viadev->reg_offset; + unsigned int size, res; - snd_via82xx_channel_reset(chip, viadev); + size = viadev->idx_table[idx].size; + res = viadev->idx_table[idx].offset + size - count; - outl((u32)viadev->table_addr, port + VIA_REG_OFFSET_TABLE_PTR); - switch (chip->chip_type) { - case TYPE_VIA686: - outb(VIA_REG_TYPE_AUTOSTART | - (runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA_REG_TYPE_16BIT : 0) | - (runtime->channels > 1 ? VIA_REG_TYPE_STEREO : 0) | - ((viadev->reg_offset & 0x10) == 0 ? VIA_REG_TYPE_INT_LSAMPLE : 0) | - VIA_REG_TYPE_INT_EOL | - VIA_REG_TYPE_INT_FLAG, port + VIA_REG_OFFSET_TYPE); - break; - case TYPE_VIA8233: - if (viadev->reg_offset == VIA_REG_MULTPLAY_STATUS) { - unsigned int slots; - int fmt = (runtime->format == SNDRV_PCM_FORMAT_S16_LE) ? VIA_REG_MULTPLAY_FMT_16BIT : VIA_REG_MULTPLAY_FMT_8BIT; - fmt |= runtime->channels << 4; - outb(fmt, port + VIA_REG_OFFSET_TYPE); - /* set sample number to slot 3, 4, 7, 8, 6, 9 */ - switch (runtime->channels) { - case 1: slots = (1<<0) | (1<<4); break; - case 2: slots = (1<<0) | (2<<4); break; - case 4: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12); break; - case 6: slots = (1<<0) | (2<<4) | (5<<8) | (6<<12) | (3<<16) | (4<<20); break; - default: slots = 0; break; - } - /* STOP index is never reached */ - outl(0xff000000 | slots, port + VIA_REG_OFFSET_STOP_IDX); + /* check the validity of the calculated position */ + if (size < count || (res < viadev->lastpos && (res >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2))) { +#ifdef POINTER_DEBUG + printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count); +#endif + /* count register returns full size when end of buffer is reached */ + if (size != count) { + snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n"); + res = viadev->lastpos; } else { - outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | - (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | - 0xff000000, /* STOP index is never reached */ - port + VIA_REG_OFFSET_STOP_IDX); + res = viadev->idx_table[idx].offset + size; + if (res < viadev->lastpos && (res >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2)) { + snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n"); + res = viadev->lastpos; + } } - break; } - return 0; + viadev->lastpos = res; /* remember the last positiion */ + if (res >= viadev->bufsize) + res -= viadev->bufsize; + return res; } /* - * Interrupt handler + * get the current pointer on via686 */ - -static inline void snd_via82xx_update(via82xx_t *chip, viadev_t *viadev) +static snd_pcm_uframes_t snd_via686_pcm_pointer(snd_pcm_substream_t *substream) { - outb(VIA_REG_STAT_FLAG | VIA_REG_STAT_EOL, VIAREG(chip, OFFSET_STATUS) + viadev->reg_offset); - if (viadev->substream && viadev->running) { - spin_unlock(&chip->reg_lock); - snd_pcm_period_elapsed(viadev->substream); - spin_lock(&chip->reg_lock); - } -} + via82xx_t *chip = snd_pcm_substream_chip(substream); + viadev_t *viadev = (viadev_t *)substream->runtime->private_data; + unsigned int idx, ptr, count, res; -static void snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - via82xx_t *chip = snd_magic_cast(via82xx_t, dev_id, return); - unsigned int status; + snd_assert(viadev->tbl_entries, return 0); + if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE)) + return 0; spin_lock(&chip->reg_lock); - if (chip->chip_type == TYPE_VIA686) { - /* check mpu401 interrupt */ - status = inl(VIAREG(chip, SGD_SHADOW)); - if ((status & 0x00000077) == 0) { - spin_unlock(&chip->reg_lock); - if (chip->rmidi != NULL) - snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs); - return; - } - } - /* check status for each stream */ - if (inb(chip->port + chip->playback.reg_offset) & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG)) - snd_via82xx_update(chip, &chip->playback); - if (inb(chip->port + chip->capture.reg_offset) & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG)) - snd_via82xx_update(chip, &chip->capture); + count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)) & 0xffffff; + /* The via686a does not have the current index register, + * so we need to calculate the index from CURR_PTR. + */ + ptr = inl(VIADEV_REG(viadev, OFFSET_CURR_PTR)); + if (ptr <= (unsigned int)viadev->table_addr) + idx = 0; + else /* CURR_PTR holds the address + 8 */ + idx = ((ptr - (unsigned int)viadev->table_addr) / 8 - 1) % viadev->tbl_entries; + res = calc_linear_pos(viadev, idx, count); spin_unlock(&chip->reg_lock); + + return bytes_to_frames(substream->runtime, res); } /* - * PCM part + * get the current pointer on via823x */ - -static int snd_via82xx_playback_trigger(snd_pcm_substream_t * substream, - int cmd) +static snd_pcm_uframes_t snd_via8233_pcm_pointer(snd_pcm_substream_t *substream) { via82xx_t *chip = snd_pcm_substream_chip(substream); + viadev_t *viadev = (viadev_t *)substream->runtime->private_data; + unsigned int idx, count, res; + + snd_assert(viadev->tbl_entries, return 0); + if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE)) + return 0; + spin_lock(&chip->reg_lock); + count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)); + idx = count >> 24; + if (idx >= viadev->tbl_entries) { +#ifdef POINTER_DEBUG + printk("fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries); +#endif + res = viadev->lastpos; + } else { + count &= 0xffffff; + res = calc_linear_pos(viadev, idx, count); + } + spin_unlock(&chip->reg_lock); - return snd_via82xx_trigger(chip, &chip->playback, cmd); + return bytes_to_frames(substream->runtime, res); } -static int snd_via82xx_capture_trigger(snd_pcm_substream_t * substream, - int cmd) -{ - via82xx_t *chip = snd_pcm_substream_chip(substream); - - return snd_via82xx_trigger(chip, &chip->capture, cmd); -} +/* + * hw_params callback: + * allocate the buffer and build up the buffer description table + */ static int snd_via82xx_hw_params(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * hw_params) { via82xx_t *chip = snd_pcm_substream_chip(substream); - viadev_t *viadev = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? &chip->playback : &chip->capture; + viadev_t *viadev = (viadev_t *)substream->runtime->private_data; int err; - err = snd_pcm_sgbuf_alloc(substream, params_buffer_bytes(hw_params)); + err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); if (err < 0) return err; err = build_via_table(viadev, substream, chip->pci, @@ -594,105 +767,206 @@ params_period_bytes(hw_params)); if (err < 0) return err; - return err; + + return 0; } +/* + * hw_free callback: + * clean up the buffer description table and release the buffer + */ static int snd_via82xx_hw_free(snd_pcm_substream_t * substream) { via82xx_t *chip = snd_pcm_substream_chip(substream); - viadev_t *viadev = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? &chip->playback : &chip->capture; + viadev_t *viadev = (viadev_t *)substream->runtime->private_data; clean_via_table(viadev, substream, chip->pci); - snd_pcm_sgbuf_free(substream); + snd_pcm_lib_free_pages(substream); return 0; } -static int snd_via82xx_playback_prepare(snd_pcm_substream_t * substream) + +/* + * set up the table pointer + */ +static void snd_via82xx_set_table_ptr(via82xx_t *chip, viadev_t *viadev) +{ + snd_via82xx_codec_ready(chip, 0); + outl((u32)viadev->table_addr, VIADEV_REG(viadev, OFFSET_TABLE_PTR)); + udelay(20); + snd_via82xx_codec_ready(chip, 0); +} + +/* + * prepare callback for playback and capture on via686 + */ +static void via686_setup_format(via82xx_t *chip, viadev_t *viadev, snd_pcm_runtime_t *runtime) +{ + snd_via82xx_channel_reset(chip, viadev); + /* this must be set after channel_reset */ + snd_via82xx_set_table_ptr(chip, viadev); + outb(VIA_REG_TYPE_AUTOSTART | + (runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA_REG_TYPE_16BIT : 0) | + (runtime->channels > 1 ? VIA_REG_TYPE_STEREO : 0) | + ((viadev->reg_offset & 0x10) == 0 ? VIA_REG_TYPE_INT_LSAMPLE : 0) | + VIA_REG_TYPE_INT_EOL | + VIA_REG_TYPE_INT_FLAG, VIADEV_REG(viadev, OFFSET_TYPE)); +} + +static int snd_via686_playback_prepare(snd_pcm_substream_t *substream) { via82xx_t *chip = snd_pcm_substream_chip(substream); + viadev_t *viadev = (viadev_t *)substream->runtime->private_data; snd_pcm_runtime_t *runtime = substream->runtime; snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate); - snd_ac97_set_rate(chip->ac97, AC97_PCM_SURR_DAC_RATE, runtime->rate); - snd_ac97_set_rate(chip->ac97, AC97_PCM_LFE_DAC_RATE, runtime->rate); - snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate); - if (chip->chip_type == TYPE_VIA8233 && - chip->playback.reg_offset != VIA_REG_MULTPLAY_STATUS) { - unsigned int tmp; - /* I don't understand this stuff but its from the documentation and this way it works */ - outb(0 , VIAREG(chip, PLAYBACK_VOLUME_L)); - outb(0 , VIAREG(chip, PLAYBACK_VOLUME_R)); - tmp = inl(VIAREG(chip, PLAYBACK_STOP_IDX)) & ~0xfffff; - outl(tmp | (0xffff * runtime->rate)/(48000/16), VIAREG(chip, PLAYBACK_STOP_IDX)); - } - return snd_via82xx_set_format(chip, &chip->playback, substream); + via686_setup_format(chip, viadev, runtime); + return 0; } -static int snd_via82xx_capture_prepare(snd_pcm_substream_t * substream) +static int snd_via686_capture_prepare(snd_pcm_substream_t *substream) { via82xx_t *chip = snd_pcm_substream_chip(substream); + viadev_t *viadev = (viadev_t *)substream->runtime->private_data; snd_pcm_runtime_t *runtime = substream->runtime; snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate); - if (chip->chip_type == TYPE_VIA8233) - outb(VIA_REG_CAPTURE_FIFO_ENABLE, VIAREG(chip, CAPTURE_FIFO)); - return snd_via82xx_set_format(chip, &chip->capture, substream); + via686_setup_format(chip, viadev, runtime); + return 0; } -static inline unsigned int snd_via82xx_cur_ptr(via82xx_t *chip, viadev_t *viadev) +/* + * lock the current rate + */ +static int via_lock_rate(struct via_rate_lock *rec, int rate) { - unsigned int val, ptr, count; - - snd_assert(viadev->tbl_entries, return 0); - if (!(inb(VIAREG(chip, OFFSET_STATUS) + viadev->reg_offset) & VIA_REG_STAT_ACTIVE)) - return 0; + int changed = 0; - count = inl(VIAREG(chip, OFFSET_CURR_COUNT) + viadev->reg_offset) & 0xffffff; - switch (chip->chip_type) { - case TYPE_VIA686: - /* The via686a does not have the current index register, - * so we need to calculate the index from CURR_PTR. - */ - ptr = inl(VIAREG(chip, OFFSET_CURR_PTR) + viadev->reg_offset); - if (ptr <= (unsigned int)viadev->table_addr) - val = 0; - else /* CURR_PTR holds the address + 8 */ - val = ((ptr - (unsigned int)viadev->table_addr) / 8 - 1) % viadev->tbl_entries; - break; - - case TYPE_VIA8233: - default: - /* ah, this register makes life easier for us here. */ - val = inb(VIAREG(chip, OFFSET_CURR_INDEX) + viadev->reg_offset) % viadev->tbl_entries; - break; + spin_lock(&rec->lock); + if (rec->rate) { + if (rec->rate != rate && rec->used > 1) { + spin_unlock(&rec->lock); + return -EINVAL; + } + } else { + rec->rate = rate; + changed = 1; } + spin_unlock(&rec->lock); + return changed; +} + +/* + * prepare callback for DSX playback on via823x + */ +static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream) +{ + via82xx_t *chip = snd_pcm_substream_chip(substream); + viadev_t *viadev = (viadev_t *)substream->runtime->private_data; + snd_pcm_runtime_t *runtime = substream->runtime; + int rate_changed; + u32 rbits; - /* convert to the linear position */ - return viadev->idx_table[val].offset + - viadev->idx_table[val].size - count; + if ((rate_changed = via_lock_rate(&chip->rates[0], runtime->rate)) < 0) + return rate_changed; + if (rate_changed) { + snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate); + snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate); + } + rbits = (0xfffff / 48000) * runtime->rate + ((0xfffff % 48000) * runtime->rate) / 48000; + snd_assert((rbits & ~0xfffff) == 0, return -EINVAL); + snd_via82xx_channel_reset(chip, viadev); + snd_via82xx_set_table_ptr(chip, viadev); + outb(chip->playback_volume[0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L)); + outb(chip->playback_volume[1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R)); + outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | /* format */ + (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | /* stereo */ + rbits | /* rate */ + 0xff000000, /* STOP index is never reached */ + VIADEV_REG(viadev, OFFSET_STOP_IDX)); + udelay(20); + snd_via82xx_codec_ready(chip, 0); + return 0; } -static snd_pcm_uframes_t snd_via82xx_playback_pointer(snd_pcm_substream_t * substream) +/* + * prepare callback for multi-channel playback on via823x + */ +static int snd_via8233_multi_prepare(snd_pcm_substream_t *substream) { via82xx_t *chip = snd_pcm_substream_chip(substream); - return bytes_to_frames(substream->runtime, snd_via82xx_cur_ptr(chip, &chip->playback)); + viadev_t *viadev = (viadev_t *)substream->runtime->private_data; + snd_pcm_runtime_t *runtime = substream->runtime; + unsigned int slots; + int fmt; + + if (via_lock_rate(&chip->rates[0], runtime->rate) < 0) + return -EINVAL; + snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate); + snd_ac97_set_rate(chip->ac97, AC97_PCM_SURR_DAC_RATE, runtime->rate); + snd_ac97_set_rate(chip->ac97, AC97_PCM_LFE_DAC_RATE, runtime->rate); + snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate); + snd_via82xx_channel_reset(chip, viadev); + snd_via82xx_set_table_ptr(chip, viadev); + + fmt = (runtime->format == SNDRV_PCM_FORMAT_S16_LE) ? VIA_REG_MULTPLAY_FMT_16BIT : VIA_REG_MULTPLAY_FMT_8BIT; + fmt |= runtime->channels << 4; + outb(fmt, VIADEV_REG(viadev, OFS_MULTPLAY_FORMAT)); + /* set sample number to slot 3, 4, 7, 8, 6, 9 */ + /* corresponding to FL, FR, RL, RR, C, LFE ?? */ + switch (runtime->channels) { + case 1: slots = (1<<0) | (1<<4); break; + case 2: slots = (1<<0) | (2<<4); break; + case 3: slots = (1<<0) | (2<<4) | (5<<8); break; + case 4: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12); break; + case 5: slots = (1<<0) | (2<<4) | (5<<8) | (3<<12) | (4<<16); break; + case 6: slots = (1<<0) | (2<<4) | (5<<8) | (6<<12) | (3<<16) | (4<<20); break; + default: slots = 0; break; + } + /* STOP index is never reached */ + outl(0xff000000 | slots, VIADEV_REG(viadev, OFFSET_STOP_IDX)); + udelay(20); + snd_via82xx_codec_ready(chip, 0); + return 0; } -static snd_pcm_uframes_t snd_via82xx_capture_pointer(snd_pcm_substream_t * substream) +/* + * prepare callback for capture on via823x + */ +static int snd_via8233_capture_prepare(snd_pcm_substream_t *substream) { via82xx_t *chip = snd_pcm_substream_chip(substream); - return bytes_to_frames(substream->runtime, snd_via82xx_cur_ptr(chip, &chip->capture)); + viadev_t *viadev = (viadev_t *)substream->runtime->private_data; + snd_pcm_runtime_t *runtime = substream->runtime; + + if (via_lock_rate(&chip->rates[1], runtime->rate) < 0) + return -EINVAL; + snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate); + snd_via82xx_channel_reset(chip, viadev); + snd_via82xx_set_table_ptr(chip, viadev); + outb(VIA_REG_CAPTURE_FIFO_ENABLE, VIADEV_REG(viadev, OFS_CAPTURE_FIFO)); + outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | + (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | + 0xff000000, /* STOP index is never reached */ + VIADEV_REG(viadev, OFFSET_STOP_IDX)); + udelay(20); + snd_via82xx_codec_ready(chip, 0); + return 0; } -static snd_pcm_hardware_t snd_via82xx_playback = + +/* + * pcm hardware definition, identical for both playback and capture + */ +static snd_pcm_hardware_t snd_via82xx_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE), .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = 0, - .rate_min = 8000, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, .rate_max = 48000, .channels_min = 1, .channels_max = 2, @@ -704,151 +978,315 @@ .fifo_size = 0, }; -static snd_pcm_hardware_t snd_via82xx_capture = -{ - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = 0, - .rate_min = 8000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = 128 * 1024, - .period_bytes_min = 32, - .period_bytes_max = 128 * 1024, - .periods_min = 2, - .periods_max = VIA_TABLE_SIZE / 2, - .fifo_size = 0, -}; -static unsigned int channels[] = { - 1, 2, 4, 6 -}; - -#define CHANNELS sizeof(channels) / sizeof(channels[0]) - -static snd_pcm_hw_constraint_list_t hw_constraints_channels = { - .count = CHANNELS, - .list = channels, - .mask = 0, -}; - -static int snd_via82xx_playback_open(snd_pcm_substream_t * substream) +/* + * open callback skeleton + */ +static int snd_via82xx_pcm_open(via82xx_t *chip, viadev_t *viadev, snd_pcm_substream_t * substream) { - via82xx_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; int err; + unsigned long flags; + struct via_rate_lock *ratep; + + runtime->hw = snd_via82xx_hw; + + /* set the hw rate condition */ + ratep = &chip->rates[viadev->direction]; + spin_lock_irqsave(&ratep->lock, flags); + ratep->used++; + if (! ratep->rate) { + int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC; + runtime->hw.rates = chip->ac97->rates[idx]; + if (runtime->hw.rates & SNDRV_PCM_RATE_8000) + runtime->hw.rate_min = 8000; + } else { + /* a fixed rate */ + runtime->hw.rates = SNDRV_PCM_RATE_KNOT; + runtime->hw.rate_max = runtime->hw.rate_min = ratep->rate; + } + spin_unlock_irqrestore(&ratep->lock, flags); - chip->playback.substream = substream; - runtime->hw = snd_via82xx_playback; - runtime->hw.rates = chip->ac97->rates[AC97_RATES_FRONT_DAC]; - if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000)) - runtime->hw.rate_min = 48000; - if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0) - return err; /* we may remove following constaint when we modify table entries in interrupt */ if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) return err; - if (chip->chip_type == TYPE_VIA8233) { - runtime->hw.channels_max = 6; - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels); - } + + runtime->private_data = viadev; + viadev->substream = substream; + return 0; } -static int snd_via82xx_capture_open(snd_pcm_substream_t * substream) + +/* + * open callback for playback on via686 and via823x DSX + */ +static int snd_via82xx_playback_open(snd_pcm_substream_t * substream) { via82xx_t *chip = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; + viadev_t *viadev = &chip->devs[chip->playback_devno + substream->number]; + + return snd_via82xx_pcm_open(chip, viadev, substream); +} + +/* + * open callback for playback on via823x multi-channel + */ +static int snd_via8233_multi_open(snd_pcm_substream_t * substream) +{ + via82xx_t *chip = snd_pcm_substream_chip(substream); + viadev_t *viadev = &chip->devs[chip->multi_devno]; int err; + /* channels constraint for VIA8233A + * 3 and 5 channels are not supported + */ + static unsigned int channels[] = { + 1, 2, 4, 6 + }; + static snd_pcm_hw_constraint_list_t hw_constraints_channels = { + .count = ARRAY_SIZE(channels), + .list = channels, + .mask = 0, + }; - chip->capture.substream = substream; - runtime->hw = snd_via82xx_capture; - runtime->hw.rates = chip->ac97->rates[AC97_RATES_ADC]; - if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000)) - runtime->hw.rate_min = 48000; - if ((err = snd_pcm_sgbuf_init(substream, chip->pci, 32)) < 0) - return err; - if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) + if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0) return err; + substream->runtime->hw.channels_max = 6; + if (chip->chip_type == TYPE_VIA8233A) + snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels); return 0; } -static int snd_via82xx_playback_close(snd_pcm_substream_t * substream) +/* + * open callback for capture on via686 and via823x + */ +static int snd_via82xx_capture_open(snd_pcm_substream_t * substream) { via82xx_t *chip = snd_pcm_substream_chip(substream); - chip->playback.substream = NULL; - snd_pcm_sgbuf_delete(substream); - return 0; + viadev_t *viadev = &chip->devs[chip->capture_devno + substream->pcm->device]; + + return snd_via82xx_pcm_open(chip, viadev, substream); } -static int snd_via82xx_capture_close(snd_pcm_substream_t * substream) +/* + * close callback + */ +static int snd_via82xx_pcm_close(snd_pcm_substream_t * substream) { via82xx_t *chip = snd_pcm_substream_chip(substream); - chip->capture.substream = NULL; - snd_pcm_sgbuf_delete(substream); + viadev_t *viadev = (viadev_t *)substream->runtime->private_data; + unsigned long flags; + struct via_rate_lock *ratep; + + /* release the rate lock */ + ratep = &chip->rates[viadev->direction]; + spin_lock_irqsave(&ratep->lock, flags); + ratep->used--; + if (! ratep->used) + ratep->rate = 0; + spin_unlock_irqrestore(&ratep->lock, flags); + + viadev->substream = NULL; return 0; } -static snd_pcm_ops_t snd_via82xx_playback_ops = { + +/* via686 playback callbacks */ +static snd_pcm_ops_t snd_via686_playback_ops = { .open = snd_via82xx_playback_open, - .close = snd_via82xx_playback_close, + .close = snd_via82xx_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_via82xx_hw_params, .hw_free = snd_via82xx_hw_free, - .prepare = snd_via82xx_playback_prepare, - .trigger = snd_via82xx_playback_trigger, - .pointer = snd_via82xx_playback_pointer, - .copy = snd_pcm_sgbuf_ops_copy_playback, - .silence = snd_pcm_sgbuf_ops_silence, + .prepare = snd_via686_playback_prepare, + .trigger = snd_via82xx_pcm_trigger, + .pointer = snd_via686_pcm_pointer, .page = snd_pcm_sgbuf_ops_page, }; -static snd_pcm_ops_t snd_via82xx_capture_ops = { +/* via686 capture callbacks */ +static snd_pcm_ops_t snd_via686_capture_ops = { .open = snd_via82xx_capture_open, - .close = snd_via82xx_capture_close, + .close = snd_via82xx_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_via82xx_hw_params, + .hw_free = snd_via82xx_hw_free, + .prepare = snd_via686_capture_prepare, + .trigger = snd_via82xx_pcm_trigger, + .pointer = snd_via686_pcm_pointer, + .page = snd_pcm_sgbuf_ops_page, +}; + +/* via823x DSX playback callbacks */ +static snd_pcm_ops_t snd_via8233_playback_ops = { + .open = snd_via82xx_playback_open, + .close = snd_via82xx_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_via82xx_hw_params, .hw_free = snd_via82xx_hw_free, - .prepare = snd_via82xx_capture_prepare, - .trigger = snd_via82xx_capture_trigger, - .pointer = snd_via82xx_capture_pointer, - .copy = snd_pcm_sgbuf_ops_copy_capture, - .silence = snd_pcm_sgbuf_ops_silence, + .prepare = snd_via8233_playback_prepare, + .trigger = snd_via82xx_pcm_trigger, + .pointer = snd_via8233_pcm_pointer, .page = snd_pcm_sgbuf_ops_page, }; -static void snd_via82xx_pcm_free(snd_pcm_t *pcm) +/* via823x multi-channel playback callbacks */ +static snd_pcm_ops_t snd_via8233_multi_ops = { + .open = snd_via8233_multi_open, + .close = snd_via82xx_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_via82xx_hw_params, + .hw_free = snd_via82xx_hw_free, + .prepare = snd_via8233_multi_prepare, + .trigger = snd_via82xx_pcm_trigger, + .pointer = snd_via8233_pcm_pointer, + .page = snd_pcm_sgbuf_ops_page, +}; + +/* via823x capture callbacks */ +static snd_pcm_ops_t snd_via8233_capture_ops = { + .open = snd_via82xx_capture_open, + .close = snd_via82xx_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_via82xx_hw_params, + .hw_free = snd_via82xx_hw_free, + .prepare = snd_via8233_capture_prepare, + .trigger = snd_via82xx_pcm_trigger, + .pointer = snd_via8233_pcm_pointer, + .page = snd_pcm_sgbuf_ops_page, +}; + + +static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction) +{ + chip->devs[idx].reg_offset = reg_offset; + chip->devs[idx].direction = direction; + chip->devs[idx].port = chip->port + reg_offset; +} + +/* + * create pcm instances for VIA8233, 8233C and 8235 (not 8233A) + */ +static int __devinit snd_via8233_pcm_new(via82xx_t *chip) { - via82xx_t *chip = snd_magic_cast(via82xx_t, pcm->private_data, return); - chip->pcm = NULL; + snd_pcm_t *pcm; + int i, err; + + chip->playback_devno = 0; /* x 4 */ + chip->multi_devno = 4; /* x 1 */ + chip->capture_devno = 5; /* x 2 */ + chip->num_devs = 7; + chip->intr_mask = 0x33033333; /* FLAG|EOL for rec0-1, mc, sdx0-3 */ + + /* PCM #0: 4 DSX playbacks and 1 capture */ + err = snd_pcm_new(chip->card, chip->card->shortname, 0, 4, 1, &pcm); + if (err < 0) + return err; + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops); + pcm->private_data = chip; + strcpy(pcm->name, chip->card->shortname); + /* set up playbacks */ + for (i = 0; i < 4; i++) + init_viadev(chip, i, 0x10 * i, 0); + /* capture */ + init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1); + + if ((err = snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci, pcm)) < 0) + return err; + + /* PCM #1: multi-channel playback and 2nd capture */ + err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 1, &pcm); + if (err < 0) + return err; + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_multi_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops); + pcm->private_data = chip; + strcpy(pcm->name, chip->card->shortname); + /* set up playback */ + init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0); + /* set up capture */ + init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 1); + + if ((err = snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci, pcm)) < 0) + return err; + + return 0; } -static int __devinit snd_via82xx_pcm(via82xx_t *chip, int device, snd_pcm_t ** rpcm) +/* + * create pcm instances for VIA8233A + */ +static int __devinit snd_via8233a_pcm_new(via82xx_t *chip) { snd_pcm_t *pcm; int err; - if (rpcm) - *rpcm = NULL; - err = snd_pcm_new(chip->card, chip->card->shortname, device, 1, 1, &pcm); + chip->multi_devno = 0; + chip->playback_devno = 1; + chip->capture_devno = 2; + chip->num_devs = 3; + chip->intr_mask = 0x03033000; /* FLAG|EOL for rec0, mc, sdx3 */ + + /* PCM #0: multi-channel playback and capture */ + err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm); if (err < 0) return err; + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_multi_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via8233_capture_ops); + pcm->private_data = chip; + strcpy(pcm->name, chip->card->shortname); + /* set up playback */ + init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0); + /* capture */ + init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via82xx_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via82xx_capture_ops); + if ((err = snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci, pcm)) < 0) + return err; + /* PCM #1: DXS3 playback (for spdif) */ + err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 0, &pcm); + if (err < 0) + return err; + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via8233_playback_ops); pcm->private_data = chip; - pcm->private_free = snd_via82xx_pcm_free; - pcm->info_flags = 0; strcpy(pcm->name, chip->card->shortname); - chip->pcm = pcm; + /* set up playback */ + init_viadev(chip, chip->playback_devno, 0x30, 0); + + if ((err = snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci, pcm)) < 0) + return err; + + return 0; +} + +/* + * create a pcm instance for via686a/b + */ +static int __devinit snd_via686_pcm_new(via82xx_t *chip) +{ + snd_pcm_t *pcm; + int err; + + chip->playback_devno = 0; + chip->capture_devno = 1; + chip->num_devs = 2; + chip->intr_mask = 0x77; /* FLAG | EOL for PB, CP, FM */ + + err = snd_pcm_new(chip->card, chip->card->shortname, 0, 1, 1, &pcm); + if (err < 0) + return err; + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops); + pcm->private_data = chip; + strcpy(pcm->name, chip->card->shortname); + init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0); + init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 1); + + if ((err = snd_pcm_lib_preallocate_sg_pages_for_all(chip->pci, pcm)) < 0) + return err; - if (rpcm) - *rpcm = NULL; return 0; } @@ -874,23 +1312,25 @@ static int snd_via8233_capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { via82xx_t *chip = snd_kcontrol_chip(kcontrol); - ucontrol->value.enumerated.item[0] = inb(VIAREG(chip, CAPTURE_CHANNEL)) & VIA_REG_CAPTURE_CHANNEL_MIC ? 1 : 0; + unsigned long port = chip->port + kcontrol->id.index ? (VIA_REG_CAPTURE_CHANNEL + 0x10) : VIA_REG_CAPTURE_CHANNEL; + ucontrol->value.enumerated.item[0] = inb(port) & VIA_REG_CAPTURE_CHANNEL_MIC ? 1 : 0; return 0; } static int snd_via8233_capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { via82xx_t *chip = snd_kcontrol_chip(kcontrol); + unsigned long port = chip->port + kcontrol->id.index ? (VIA_REG_CAPTURE_CHANNEL + 0x10) : VIA_REG_CAPTURE_CHANNEL; unsigned long flags; u8 val, oval; spin_lock_irqsave(&chip->reg_lock, flags); - oval = inb(VIAREG(chip, CAPTURE_CHANNEL)); + oval = inb(port); val = oval & ~VIA_REG_CAPTURE_CHANNEL_MIC; if (ucontrol->value.enumerated.item[0]) val |= VIA_REG_CAPTURE_CHANNEL_MIC; if (val != oval) - outb(val, VIAREG(chip, CAPTURE_CHANNEL)); + outb(val, port); spin_unlock_irqrestore(&chip->reg_lock, flags); return val != oval; } @@ -903,13 +1343,101 @@ .put = snd_via8233_capture_source_put, }; +static int snd_via8233_dxs3_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int snd_via8233_dxs3_spdif_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +{ + via82xx_t *chip = snd_kcontrol_chip(kcontrol); + u8 val; + + pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val); + ucontrol->value.integer.value[0] = (val & VIA8233_SPDIF_DX3) ? 1 : 0; + return 0; +} + +static int snd_via8233_dxs3_spdif_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +{ + via82xx_t *chip = snd_kcontrol_chip(kcontrol); + u8 val, oval; + + pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &oval); + val = oval & ~VIA8233_SPDIF_DX3; + if (ucontrol->value.integer.value[0]) + val |= VIA8233_SPDIF_DX3; + if (val != oval) { + pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, val); + return 1; + } + return 0; +} + +static snd_kcontrol_new_t snd_via8233_dxs3_spdif_control __devinitdata = { + .name = "IEC958 Output Switch", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_via8233_dxs3_spdif_info, + .get = snd_via8233_dxs3_spdif_get, + .put = snd_via8233_dxs3_spdif_put, +}; + +static int snd_via8233_dxs_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 0xff; + return 0; +} + +static int snd_via8233_dxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +{ + via82xx_t *chip = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = 0xff - chip->playback_volume[0]; + ucontrol->value.integer.value[1] = 0xff - chip->playback_volume[1]; + return 0; +} + +static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) +{ + via82xx_t *chip = snd_kcontrol_chip(kcontrol); + unsigned char val; + int change; + + val = 0xff - ucontrol->value.integer.value[0]; + change = val != chip->playback_volume[0]; + if (val) + chip->playback_volume[0] = val; + val = 0xff - ucontrol->value.integer.value[1]; + change |= val != chip->playback_volume[1]; + if (val) + chip->playback_volume[1] = val; + return change; +} + +static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = { + .name = "VIA DXS Playback Volume", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = snd_via8233_dxs_volume_info, + .get = snd_via8233_dxs_volume_get, + .put = snd_via8233_dxs_volume_put, +}; + +/* + */ + static void snd_via82xx_mixer_free_ac97(ac97_t *ac97) { via82xx_t *chip = snd_magic_cast(via82xx_t, ac97->private_data, return); chip->ac97 = NULL; } -static int __devinit snd_via82xx_mixer(via82xx_t *chip) +static int __devinit snd_via82xx_mixer_new(via82xx_t *chip) { ac97_t ac97; int err; @@ -923,6 +1451,12 @@ ac97.clock = chip->ac97_clock; if ((err = snd_ac97_mixer(chip->card, &ac97, &chip->ac97)) < 0) return err; + + if (chip->chip_type != TYPE_VIA686) { + /* use slot 10/11 */ + snd_ac97_update_bits(chip->ac97, AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4); + } + return 0; } @@ -944,8 +1478,8 @@ via82xx_t *chip = snd_kcontrol_chip(kcontrol); u16 val; - pci_read_config_word(chip->pci, 0x42, &val); - ucontrol->value.integer.value[0] = (val & 0x08) ? 1 : 0; + pci_read_config_word(chip->pci, VIA_FUNC_ENABLE, &val); + ucontrol->value.integer.value[0] = (val & VIA_FUNC_ENABLE_GAME) ? 1 : 0; return 0; } @@ -954,12 +1488,12 @@ via82xx_t *chip = snd_kcontrol_chip(kcontrol); u16 val, oval; - pci_read_config_word(chip->pci, 0x42, &oval); - val = oval & ~0x08; + pci_read_config_word(chip->pci, VIA_FUNC_ENABLE, &oval); + val = oval & ~VIA_FUNC_ENABLE_GAME; if (ucontrol->value.integer.value[0]) - val |= 0x08; + val |= VIA_FUNC_ENABLE_GAME; if (val != oval) { - pci_write_config_word(chip->pci, 0x42, val); + pci_write_config_word(chip->pci, VIA_FUNC_ENABLE, val); return 1; } return 0; @@ -977,6 +1511,107 @@ * */ +static int snd_via8233_init_misc(via82xx_t *chip, int dev) +{ + int i, err, caps; + unsigned char val; + + caps = chip->chip_type == TYPE_VIA8233A ? 1 : 2; + for (i = 0; i < caps; i++) { + snd_via8233_capture_source.index = i; + err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_capture_source, chip)); + if (err < 0) + return err; + } + err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs3_spdif_control, chip)); + if (err < 0) + return err; + err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip)); + if (err < 0) + return err; + + /* select spdif data slot 10/11 */ + pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val); + val = (val & ~VIA8233_SPDIF_SLOT_MASK) | VIA8233_SPDIF_SLOT_1011; + pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, val); + + return 0; +} + +static int snd_via686_init_misc(via82xx_t *chip, int dev) +{ + unsigned char legacy, legacy_cfg; + int rev_h = 0; + + legacy = chip->old_legacy; + legacy_cfg = chip->old_legacy_cfg; + legacy |= VIA_FUNC_MIDI_IRQMASK; /* FIXME: correct? (disable MIDI) */ + legacy &= ~VIA_FUNC_ENABLE_GAME; /* disable joystick */ + if (chip->revision >= VIA_REV_686_H) { + rev_h = 1; + if (check_region(pci_resource_start(chip->pci, 2), 4)) + legacy &= ~VIA_FUNC_MIDI_PNP; /* disable PCI I/O 2 */ + else + legacy |= VIA_FUNC_MIDI_PNP; /* enable PCI I/O 2 */ + } + pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy); + pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg); + if (rev_h) { + if (mpu_port[dev] >= 0x200) { /* force MIDI */ + pci_write_config_dword(chip->pci, 0x18, (mpu_port[dev] & 0xfffc) | 0x01); + } else if (legacy & VIA_FUNC_MIDI_PNP) { + mpu_port[dev] = pci_resource_start(chip->pci, 2); + if (mpu_port[dev] < 0x200) /* bad value */ + legacy &= ~VIA_FUNC_ENABLE_MIDI; /* disable MIDI */ + } + if (mpu_port[dev] >= 0x200) + legacy |= VIA_FUNC_ENABLE_MIDI; + else + legacy &= ~VIA_FUNC_ENABLE_MIDI; + } else { + switch (mpu_port[dev]) { /* force MIDI */ + case 0x300: + case 0x310: + case 0x320: + case 0x330: + legacy_cfg &= ~(3 << 2); + legacy_cfg |= (mpu_port[dev] & 0x0030) >> 2; + legacy |= VIA_FUNC_ENABLE_MIDI; + break; + default: /* no, use BIOS settings */ + if (legacy & VIA_FUNC_ENABLE_MIDI) + mpu_port[dev] = 0x300 + ((legacy_cfg & 0x000c) << 2); + break; + } + } + if (legacy & VIA_FUNC_ENABLE_MIDI) { + if (check_region(mpu_port[dev], 2)) { + printk(KERN_WARNING "unable to get MPU-401 port at 0x%lx, skipping\n", mpu_port[dev]); + legacy &= ~VIA_FUNC_ENABLE_MIDI; + } else if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A, + mpu_port[dev], 0, + chip->irq, 0, + &chip->rmidi) < 0) { + printk(KERN_WARNING "unable to initialize MPU-401 at 0x%lx, skipping\n", mpu_port[dev]); + legacy &= ~VIA_FUNC_ENABLE_MIDI; + } + } + pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy); + pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg); + if (legacy & VIA_FUNC_ENABLE_MIDI) { + legacy &= ~VIA_FUNC_MIDI_IRQMASK; /* enable MIDI interrupt */ + pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy); + } + + /* card switches */ + return snd_ctl_add(chip->card, snd_ctl_new1(&snd_via82xx_joystick_control, chip)); +} + + +/* + * + */ + static int __devinit snd_via82xx_chip_init(via82xx_t *chip) { ac97_t ac97; @@ -990,40 +1625,46 @@ #if 0 /* broken on K7M? */ if (chip->chip_type == TYPE_VIA686) /* disable all legacy ports */ - pci_write_config_byte(chip->pci, 0x42, 0); + pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, 0); #endif - pci_read_config_byte(chip->pci, 0x40, &pval); - if (! (pval & 0x01)) { /* codec not ready? */ + pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); + if (! (pval & VIA_ACLINK_C00_READY)) { /* codec not ready? */ /* deassert ACLink reset, force SYNC */ - pci_write_config_byte(chip->pci, 0x41, 0xe0); + pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, + VIA_ACLINK_CTRL_ENABLE | + VIA_ACLINK_CTRL_RESET | + VIA_ACLINK_CTRL_SYNC); udelay(100); +#if 1 /* FIXME: should we do full reset here for all chip models? */ + pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, 0x00); + udelay(100); +#else /* deassert ACLink reset, force SYNC (warm AC'97 reset) */ - pci_write_config_byte(chip->pci, 0x41, 0x60); + pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, + VIA_ACLINK_CTRL_RESET|VIA_ACLINK_CTRL_SYNC); udelay(2); - /* pci_write_config_byte(chip->pci, 0x41, 0x00); - udelay(100); - */ +#endif /* ACLink on, deassert ACLink reset, VSR, SGD data out */ /* note - FM data out has trouble with non VRA codecs !! */ - pci_write_config_byte(chip->pci, 0x41, 0xcc); + pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT); udelay(100); } /* Make sure VRA is enabled, in case we didn't do a * complete codec reset, above */ - pci_read_config_byte(chip->pci, 0x41, &pval); - if ((pval & 0xcc) != 0xcc) { + pci_read_config_byte(chip->pci, VIA_ACLINK_CTRL, &pval); + if ((pval & VIA_ACLINK_CTRL_INIT) != VIA_ACLINK_CTRL_INIT) { /* ACLink on, deassert ACLink reset, VSR, SGD data out */ /* note - FM data out has trouble with non VRA codecs !! */ - pci_write_config_byte(chip->pci, 0x41, 0xcc); + pci_write_config_byte(chip->pci, VIA_ACLINK_CTRL, VIA_ACLINK_CTRL_INIT); udelay(100); } /* wait until codec ready */ max_count = ((3 * HZ) / 4) + 1; do { - pci_read_config_byte(chip->pci, 0x40, &pval); - if (pval & 0x01) /* primary codec ready */ + pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); + if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ break; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); @@ -1060,25 +1701,23 @@ if (chip->chip_type == TYPE_VIA686) { /* route FM trap to IRQ, disable FM trap */ - pci_write_config_byte(chip->pci, 0x48, 0); + pci_write_config_byte(chip->pci, VIA_FM_NMI_CTRL, 0); /* disable all GPI interrupts */ - outl(0, chip->port + 0x8c); + outl(0, VIAREG(chip, GPI_INTR)); } - /* disable interrupts */ - snd_via82xx_channel_reset(chip, &chip->playback); - snd_via82xx_channel_reset(chip, &chip->capture); return 0; } static int snd_via82xx_free(via82xx_t *chip) { + unsigned int i; + if (chip->irq < 0) goto __end_hw; /* disable interrupts */ - snd_via82xx_channel_reset(chip, &chip->playback); - snd_via82xx_channel_reset(chip, &chip->capture); - /* --- */ + for (i = 0; i < chip->num_devs; i++) + snd_via82xx_channel_reset(chip, &chip->devs[i]); synchronize_irq(chip->irq); __end_hw: if (chip->res_port) { @@ -1088,8 +1727,8 @@ if (chip->irq >= 0) free_irq(chip->irq, (void *)chip); if (chip->chip_type == TYPE_VIA686) { - pci_write_config_byte(chip->pci, 0x42, chip->old_legacy); - pci_write_config_byte(chip->pci, 0x43, chip->old_legacy_cfg); + pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, chip->old_legacy); + pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, chip->old_legacy_cfg); } snd_magic_kfree(chip); return 0; @@ -1104,6 +1743,7 @@ static int __devinit snd_via82xx_create(snd_card_t * card, struct pci_dev *pci, int chip_type, + int revision, unsigned int ac97_clock, via82xx_t ** r_via) { @@ -1120,15 +1760,18 @@ return -ENOMEM; chip->chip_type = chip_type; + chip->revision = revision; spin_lock_init(&chip->reg_lock); spin_lock_init(&chip->ac97_lock); + spin_lock_init(&chip->rates[0].lock); + spin_lock_init(&chip->rates[1].lock); chip->card = card; chip->pci = pci; chip->irq = -1; - pci_read_config_byte(pci, 0x42, &chip->old_legacy); - pci_read_config_byte(pci, 0x43, &chip->old_legacy_cfg); + pci_read_config_byte(pci, VIA_FUNC_ENABLE, &chip->old_legacy); + pci_read_config_byte(pci, VIA_PNP_CONTROL, &chip->old_legacy_cfg); chip->port = pci_resource_start(pci, 0); if ((chip->res_port = request_region(chip->port, 256, card->driver)) == NULL) { @@ -1145,24 +1788,8 @@ chip->irq = pci->irq; if (ac97_clock >= 8000 && ac97_clock <= 48000) chip->ac97_clock = ac97_clock; - pci_read_config_byte(pci, PCI_REVISION_ID, &chip->revision); synchronize_irq(chip->irq); - /* initialize offsets */ - switch (chip->chip_type) { - case TYPE_VIA686: - chip->playback.reg_offset = VIA_REG_PLAYBACK_STATUS; - chip->capture.reg_offset = VIA_REG_CAPTURE_STATUS; - break; - case TYPE_VIA8233: - /* we use multi-channel playback mode, since this mode is supported - * by all VIA8233 models (and obviously suitable for our purpose). - */ - chip->playback.reg_offset = VIA_REG_MULTPLAY_STATUS; - chip->capture.reg_offset = VIA_REG_CAPTURE_8233_STATUS; - break; - } - if ((err = snd_via82xx_chip_init(chip)) < 0) { snd_via82xx_free(chip); return err; @@ -1182,14 +1809,28 @@ return 0; } +struct via823x_info { + int revision; + char *name; + int type; +}; +static struct via823x_info via823x_cards[] __devinitdata = { + { VIA_REV_PRE_8233, "VIA 8233-Pre", TYPE_VIA8233 }, + { VIA_REV_8233C, "VIA 8233C", TYPE_VIA8233 }, + { VIA_REV_8233, "VIA 8233", TYPE_VIA8233 }, + { VIA_REV_8233A, "VIA 8233A", TYPE_VIA8233A }, + { VIA_REV_8235, "VIA 8235", TYPE_VIA8233 }, +}; + static int __devinit snd_via82xx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { static int dev; snd_card_t *card; via82xx_t *chip; - int pcm_dev = 0; - int chip_type; + unsigned char revision; + int chip_type = 0, card_type; + unsigned int i; int err; if (dev >= SNDRV_CARDS) @@ -1203,124 +1844,59 @@ if (card == NULL) return -ENOMEM; - chip_type = pci_id->driver_data; - switch (chip_type) { - case TYPE_VIA686: + card_type = pci_id->driver_data; + pci_read_config_byte(pci, PCI_REVISION_ID, &revision); + switch (card_type) { + case TYPE_CARD_VIA686: strcpy(card->driver, "VIA686A"); - strcpy(card->shortname, "VIA 82C686A/B"); + sprintf(card->shortname, "VIA 82C686A/B rev%x", revision); + chip_type = TYPE_VIA686; break; - case TYPE_VIA8233: - strcpy(card->driver, "VIA8233"); - strcpy(card->shortname, "VIA 8233A/C"); + case TYPE_CARD_VIA8233: + chip_type = TYPE_VIA8233; + sprintf(card->shortname, "VIA 823x rev%x", revision); + for (i = 0; i < ARRAY_SIZE(via823x_cards); i++) { + if (revision == via823x_cards[i].revision) { + chip_type = via823x_cards[i].type; + strcpy(card->shortname, via823x_cards[i].name); + break; + } + } + if (chip_type == VIA_REV_8233A) + strcpy(card->driver, "VIA8233A"); + else + strcpy(card->driver, "VIA8233"); break; default: - snd_printk(KERN_ERR "invalid chip type %d\n", chip_type); - snd_card_free(card); - return -EINVAL; + snd_printk(KERN_ERR "invalid card type %d\n", card_type); + err = -EINVAL; + goto __error; } - if ((err = snd_via82xx_create(card, pci, chip_type, ac97_clock[dev], &chip)) < 0) { - snd_card_free(card); - return err; - } - - - if (snd_via82xx_mixer(chip) < 0) { - snd_card_free(card); - return err; - } - if (snd_via82xx_pcm(chip, pcm_dev++, NULL) < 0) { - snd_card_free(card); - return err; - } -#if 0 - if (snd_via82xx_pcm_fm(chip, pcm_dev++, NULL) < 0) { - snd_card_free(card); - return err; - } -#endif + if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0) + goto __error; - if (chip->chip_type == TYPE_VIA686) { - unsigned char legacy, legacy_cfg; - int rev_h = 0; - legacy = chip->old_legacy; - legacy_cfg = chip->old_legacy_cfg; - legacy |= 0x40; /* disable MIDI */ - legacy &= ~0x08; /* disable joystick */ - if (chip->revision >= 0x20) { - if (check_region(pci_resource_start(pci, 2), 4)) { - rev_h = 0; - legacy &= ~0x80; /* disable PCI I/O 2 */ - } else { - rev_h = 1; - legacy |= 0x80; /* enable PCI I/O 2 */ - } - } - pci_write_config_byte(pci, 0x42, legacy); - pci_write_config_byte(pci, 0x43, legacy_cfg); - if (rev_h && mpu_port[dev] >= 0x200) { /* force MIDI */ - legacy |= 0x02; /* enable MPU */ - pci_write_config_dword(pci, 0x18, (mpu_port[dev] & 0xfffc) | 0x01); - } else { - if (rev_h && (legacy & 0x02)) { - mpu_port[dev] = pci_resource_start(pci, 2); - if (mpu_port[dev] < 0x200) /* bad value */ - legacy &= ~0x02; /* disable MIDI */ - } else { - switch (mpu_port[dev]) { /* force MIDI */ - case 0x300: - case 0x310: - case 0x320: - case 0x330: - legacy_cfg &= ~(3 << 2); - legacy_cfg |= (mpu_port[dev] & 0x0030) >> 2; - legacy |= 0x02; - break; - default: /* no, use BIOS settings */ - if (legacy & 0x02) - mpu_port[dev] = 0x300 + ((legacy_cfg & 0x000c) << 2); - } - } - } - pci_write_config_byte(pci, 0x42, legacy); - pci_write_config_byte(pci, 0x43, legacy_cfg); - if (legacy & 0x02) { - if (check_region(mpu_port[dev], 2)) { - printk(KERN_WARNING "unable to get MPU-401 port at 0x%lx, skipping\n", mpu_port[dev]); - legacy &= ~0x02; - pci_write_config_byte(pci, 0x42, legacy); - goto __skip_mpu; - } - if (snd_mpu401_uart_new(card, 0, MPU401_HW_VIA686A, - mpu_port[dev], 0, - pci->irq, 0, - &chip->rmidi) < 0) { - printk(KERN_WARNING "unable to initialize MPU-401 at 0x%lx, skipping\n", mpu_port[dev]); - legacy &= ~0x02; - pci_write_config_byte(pci, 0x42, legacy); - goto __skip_mpu; - } - legacy &= ~0x40; /* enable MIDI interrupt */ - pci_write_config_byte(pci, 0x42, legacy); - __skip_mpu: - ; - } - - /* card switches */ - err = snd_ctl_add(card, snd_ctl_new1(&snd_via82xx_joystick_control, chip)); - if (err < 0) { - snd_card_free(card); - return err; - } + if ((err = snd_via82xx_mixer_new(chip)) < 0) + goto __error; + if (chip_type == TYPE_VIA686) { + if ((err = snd_via686_pcm_new(chip)) < 0 || + (err = snd_via686_init_misc(chip, dev)) < 0) + goto __error; } else { - /* VIA8233 */ - err = snd_ctl_add(card, snd_ctl_new1(&snd_via8233_capture_source, chip)); - if (err < 0) { - snd_card_free(card); - return err; + if (chip_type == VIA_REV_8233A) { + if ((err = snd_via8233a_pcm_new(chip)) < 0) + goto __error; + } else { + if ((err = snd_via8233_pcm_new(chip)) < 0) + goto __error; } + if ((err = snd_via8233_init_misc(chip, dev)) < 0) + goto __error; } + /* disable interrupts */ + for (i = 0; i < chip->num_devs; i++) + snd_via82xx_channel_reset(chip, &chip->devs[i]); sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname, chip->port, chip->irq); @@ -1332,6 +1908,10 @@ pci_set_drvdata(pci, card); dev++; return 0; + + __error: + snd_card_free(card); + return err; } static void __devexit snd_via82xx_remove(struct pci_dev *pci) @@ -1391,4 +1971,3 @@ __setup("snd-via82xx=", alsa_card_via82xx_setup); #endif /* ifndef MODULE */ - diff -Nru a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c --- a/sound/pci/ymfpci/ymfpci_main.c Sun Feb 9 21:13:35 2003 +++ b/sound/pci/ymfpci/ymfpci_main.c Sun Feb 9 21:13:35 2003 @@ -624,7 +624,7 @@ // ymfpci_t *chip = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; ymfpci_pcm_t *ypcm = snd_magic_cast(ymfpci_pcm_t, runtime->private_data, return -ENXIO); - int nvoice; + unsigned int nvoice; ypcm->period_size = runtime->period_size; ypcm->buffer_size = runtime->buffer_size; @@ -926,7 +926,7 @@ snd_ymfpci_readw(chip, YDSXGR_SPDIFOUTCTRL) | 2); ymfpci_open_extension(chip); chip->spdif_pcm_bits = chip->spdif_bits; - snd_ymfpci_writel(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits); + snd_ymfpci_writew(chip, YDSXGR_SPDIFOUTSTATUS, chip->spdif_pcm_bits); chip->spdif_opened++; spin_unlock_irqrestore(&chip->reg_lock, flags); @@ -1170,6 +1170,7 @@ { ymfpci_t *chip = snd_magic_cast(ymfpci_t, pcm->private_data, return); chip->pcm_spdif = NULL; + snd_pcm_lib_preallocate_free_for_all(pcm); } int __devinit snd_ymfpci_pcm_spdif(ymfpci_t *chip, int device, snd_pcm_t ** rpcm) @@ -1190,6 +1191,9 @@ pcm->info_flags = 0; strcpy(pcm->name, "YMFPCI - IEC958"); chip->pcm_spdif = pcm; + + snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 256*1024); + if (rpcm) *rpcm = pcm; return 0; @@ -1210,6 +1214,7 @@ { ymfpci_t *chip = snd_magic_cast(ymfpci_t, pcm->private_data, return); chip->pcm_4ch = NULL; + snd_pcm_lib_preallocate_free_for_all(pcm); } int __devinit snd_ymfpci_pcm_4ch(ymfpci_t *chip, int device, snd_pcm_t ** rpcm) @@ -1230,6 +1235,9 @@ pcm->info_flags = 0; strcpy(pcm->name, "YMFPCI - Rear PCM"); chip->pcm_4ch = pcm; + + snd_pcm_lib_preallocate_pci_pages_for_all(chip->pci, pcm, 64*1024, 256*1024); + if (rpcm) *rpcm = pcm; return 0; @@ -1306,8 +1314,8 @@ static snd_kcontrol_new_t snd_ymfpci_spdif_mask __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), .info = snd_ymfpci_spdif_mask_info, .get = snd_ymfpci_spdif_mask_get, }; @@ -1354,8 +1362,8 @@ static snd_kcontrol_new_t snd_ymfpci_spdif_stream __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), .info = snd_ymfpci_spdif_stream_info, .get = snd_ymfpci_spdif_stream_get, .put = snd_ymfpci_spdif_stream_put @@ -1654,7 +1662,8 @@ { ac97_t ac97; snd_kcontrol_t *kctl; - int err, idx; + unsigned int idx; + int err; memset(&ac97, 0, sizeof(ac97)); ac97.write = snd_ymfpci_codec_write; @@ -1766,16 +1775,16 @@ static int snd_ymfpci_joystick_addr_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { ymfpci_t *chip = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = chip->joystick_port; + ucontrol->value.enumerated.item[0] = chip->joystick_port; return 0; } static int snd_ymfpci_joystick_addr_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { ymfpci_t *chip = snd_kcontrol_chip(kcontrol); - if (ucontrol->value.integer.value[0] != chip->joystick_port) { - snd_assert(ucontrol->value.integer.value[0] >= 0 && ucontrol->value.integer.value[0] < 4, return -EINVAL); - chip->joystick_port = ucontrol->value.integer.value[0]; + if (ucontrol->value.enumerated.item[0] != chip->joystick_port) { + snd_assert(ucontrol->value.enumerated.item[0] >= 0 && ucontrol->value.enumerated.item[0] < 4, return -EINVAL); + chip->joystick_port = ucontrol->value.enumerated.item[0]; setup_joystick_base(chip); return 1; } @@ -1827,26 +1836,8 @@ { snd_info_entry_t *entry; - entry = snd_info_create_card_entry(card, "ymfpci", card->proc_root); - if (entry) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = chip; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 4096; - entry->c.text.read = snd_ymfpci_proc_read; - if (snd_info_register(entry) < 0) { - snd_info_unregister(entry); - entry = NULL; - } - } - chip->proc_entry = entry; - return 0; -} - -static int snd_ymfpci_proc_done(ymfpci_t *chip) -{ - if (chip->proc_entry) - snd_info_unregister((snd_info_entry_t *) chip->proc_entry); + if (! snd_card_proc_new(card, "ymfpci", &entry)) + snd_info_set_text_ops(entry, chip, snd_ymfpci_proc_read); return 0; } @@ -2037,7 +2028,6 @@ u16 ctrl; snd_assert(chip != NULL, return -EINVAL); - snd_ymfpci_proc_done(chip); if (chip->res_reg_area) { /* don't touch busy hardware */ snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); @@ -2125,11 +2115,10 @@ void snd_ymfpci_suspend(ymfpci_t *chip) { snd_card_t *card = chip->card; - int i; + unsigned int i; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D3hot) - goto __skip; + return; snd_pcm_suspend_all(chip->pcm); snd_pcm_suspend_all(chip->pcm2); snd_pcm_suspend_all(chip->pcm_spdif); @@ -2140,19 +2129,15 @@ snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); snd_ymfpci_disable_dsp(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - __skip: - snd_power_unlock(card); } void snd_ymfpci_resume(ymfpci_t *chip) { snd_card_t *card = chip->card; - int i; - - snd_power_lock(card); + unsigned int i; if (card->power_state == SNDRV_CTL_POWER_D0) - goto __skip; + return; pci_enable_device(chip->pci); pci_set_master(chip->pci); @@ -2174,8 +2159,6 @@ spin_unlock(&chip->reg_lock); } snd_power_change_state(card, SNDRV_CTL_POWER_D0); - __skip: - snd_power_unlock(card); } static int snd_ymfpci_set_power_state(snd_card_t *card, unsigned int power_state) diff -Nru a/sound/ppc/keywest.c b/sound/ppc/keywest.c --- a/sound/ppc/keywest.c Sun Feb 9 21:13:36 2003 +++ b/sound/ppc/keywest.c Sun Feb 9 21:13:36 2003 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff -Nru a/sound/ppc/pmac.c b/sound/ppc/pmac.c --- a/sound/ppc/pmac.c Sun Feb 9 21:13:37 2003 +++ b/sound/ppc/pmac.c Sun Feb 9 21:13:37 2003 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "pmac.h" #include @@ -695,6 +696,7 @@ } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* * beep stuff @@ -931,6 +933,8 @@ return 0; } +#endif /* beep stuff */ + static void snd_pmac_dbdma_reset(pmac_t *chip) { out_le32(&chip->playback.dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16); @@ -1460,9 +1464,8 @@ unsigned long flags; snd_card_t *card = chip->card; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D3hot) - goto __skip; + return; if (chip->suspend) chip->suspend(chip); @@ -1476,17 +1479,14 @@ disable_irq(chip->rx_irq); snd_pmac_sound_feature(chip, 0); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - __skip: - snd_power_unlock(card); } static void snd_pmac_resume(pmac_t *chip) { snd_card_t *card = chip->card; - snd_power_lock(card); if (card->power_state == SNDRV_CTL_POWER_D0) - goto __skip; + return; snd_pmac_sound_feature(chip, 1); if (chip->resume) @@ -1505,8 +1505,6 @@ enable_irq(chip->rx_irq); snd_power_change_state(card, SNDRV_CTL_POWER_D0); - __skip: - snd_power_unlock(card); } /* the chip is stored statically by snd_pmac_register_sleep_notifier diff -Nru a/sound/ppc/powermac.c b/sound/ppc/powermac.c --- a/sound/ppc/powermac.c Sun Feb 9 21:13:37 2003 +++ b/sound/ppc/powermac.c Sun Feb 9 21:13:37 2003 @@ -129,8 +129,10 @@ goto __error; chip->initialized = 1; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) if (enable_beep) snd_pmac_attach_beep(chip); +#endif if ((err = snd_card_register(card)) < 0) goto __error; @@ -151,7 +153,7 @@ static int __init alsa_card_pmac_init(void) { int err; - if ((err = snd_pmac_probe() < 0)) { + if ((err = snd_pmac_probe()) < 0) { #ifdef MODULE printk(KERN_ERR "no PMac soundchip found\n"); #endif diff -Nru a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c --- a/sound/ppc/tumbler.c Sun Feb 9 21:13:28 2003 +++ b/sound/ppc/tumbler.c Sun Feb 9 21:13:28 2003 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff -Nru a/sound/sound_firmware.c b/sound/sound_firmware.c --- a/sound/sound_firmware.c Sun Feb 9 21:13:28 2003 +++ b/sound/sound_firmware.c Sun Feb 9 21:13:28 2003 @@ -1,47 +1,46 @@ #include -#define __KERNEL_SYSCALLS__ #include #include #include #include -#include #include static int do_mod_firmware_load(const char *fn, char **fp) { - int fd; + struct file* filp; long l; char *dp; + loff_t pos; - fd = open(fn, 0, 0); - if (fd == -1) + filp = filp_open(fn, 0, 0); + if (IS_ERR(filp)) { printk(KERN_INFO "Unable to load '%s'.\n", fn); return 0; } - l = lseek(fd, 0L, 2); + l = filp->f_dentry->d_inode->i_size; if (l <= 0 || l > 131072) { printk(KERN_INFO "Invalid firmware '%s'\n", fn); - sys_close(fd); + filp_close(filp, current->files); return 0; } - lseek(fd, 0L, 0); dp = vmalloc(l); if (dp == NULL) { printk(KERN_INFO "Out of memory loading '%s'.\n", fn); - sys_close(fd); + filp_close(filp, current->files); return 0; } - if (read(fd, dp, l) != l) + pos = 0; + if (vfs_read(filp, dp, l, &pos) != l) { printk(KERN_INFO "Failed to read '%s'.\n", fn); vfree(dp); - sys_close(fd); + filp_close(filp, current->files); return 0; } - close(fd); + filp_close(filp, current->files); *fp = dp; return (int) l; } diff -Nru a/sound/synth/Makefile b/sound/synth/Makefile --- a/sound/synth/Makefile Sun Feb 9 21:13:28 2003 +++ b/sound/synth/Makefile Sun Feb 9 21:13:28 2003 @@ -3,8 +3,6 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := util_mem.o - snd-util-mem-objs := util_mem.o # Toplevel Module Dependency diff -Nru a/sound/synth/emux/Makefile b/sound/synth/emux/Makefile --- a/sound/synth/emux/Makefile Sun Feb 9 21:13:32 2003 +++ b/sound/synth/emux/Makefile Sun Feb 9 21:13:32 2003 @@ -3,11 +3,18 @@ # Copyright (c) 2001 by Jaroslav Kysela # -export-objs := emux.o +snd-emux-synth-objs := emux.o emux_synth.o emux_seq.o emux_nrpn.o \ + emux_effect.o emux_proc.o soundfont.o \ + $(if $(CONFIG_SND_SEQUENCER_OSS),emux_oss.o) -snd-emux-synth-y := emux.o emux_synth.o emux_seq.o emux_nrpn.o \ - emux_effect.o emux_proc.o soundfont.o -snd-emux-synth-$(CONFIG_SND_SEQUENCER_OSS) += emux_oss.o +# +# this function returns: +# "m" - CONFIG_SND_SEQUENCER is m +# - CONFIG_SND_SEQUENCER is undefined +# otherwise parameter #1 value +# +sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) -obj-$(CONFIG_SND_SBAWE) += snd-emux-synth.o -obj-$(CONFIG_SND_EMU10K1) += snd-emux-synth.o +# Toplevel Module Dependencies +obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-emux-synth.o +obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-emux-synth.o diff -Nru a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c --- a/sound/synth/emux/emux_oss.c Sun Feb 9 21:13:30 2003 +++ b/sound/synth/emux/emux_oss.c Sun Feb 9 21:13:30 2003 @@ -219,7 +219,7 @@ SF_CLIENT_NO(p->chset.port)); else if (format == SNDRV_OSS_SOUNDFONT_PATCH) { soundfont_patch_info_t patch; - if (count < sizeof(patch)) + if (count < (int)sizeof(patch)) rc = -EINVAL; if (copy_from_user(&patch, buf, sizeof(patch))) rc = -EFAULT; diff -Nru a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c --- a/sound/synth/emux/emux_seq.c Sun Feb 9 21:13:31 2003 +++ b/sound/synth/emux/emux_seq.c Sun Feb 9 21:13:31 2003 @@ -59,9 +59,6 @@ SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE) /* - */ - -/* * Initialise the EMUX Synth by creating a client and registering * a series of ports. * Each of the ports will contain the 16 midi channels. Applications @@ -179,7 +176,7 @@ } p->chset.port = snd_seq_event_port_attach(emu->client, callback, - cap, type, name); + cap, type, max_channels, name); return p; } @@ -292,11 +289,11 @@ void snd_emux_dec_count(snd_emux_t *emu) { - module_put(emu->ops.owner); + module_put(emu->card->module); emu->used--; if (emu->used <= 0) snd_emux_terminate_all(emu); - module_put(emu->card->module); + module_put(emu->ops.owner); } diff -Nru a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c --- a/sound/synth/emux/soundfont.c Sun Feb 9 21:13:34 2003 +++ b/sound/synth/emux/soundfont.c Sun Feb 9 21:13:34 2003 @@ -122,7 +122,7 @@ unsigned long flags; int rc; - if (count < sizeof(patch)) { + if (count < (long)sizeof(patch)) { snd_printk("patch record too small %ld\n", count); return -EINVAL; } @@ -406,7 +406,7 @@ soundfont_voice_map_t map; /* get the link info */ - if (count < sizeof(map)) + if (count < (int)sizeof(map)) return -EINVAL; if (copy_from_user(&map, data, sizeof(map))) return -EFAULT; @@ -509,7 +509,7 @@ if (is_special_type(sf->type)) return -EINVAL; - if (count < sizeof(hdr)) { + if (count < (long)sizeof(hdr)) { printk("Soundfont error: invalid patch zone length\n"); return -EINVAL; } @@ -524,7 +524,7 @@ return -EINVAL; } - if (count < sizeof(soundfont_voice_info_t)*hdr.nvoices) { + if (count < (long)sizeof(soundfont_voice_info_t)*hdr.nvoices) { printk("Soundfont Error: patch length(%ld) is smaller than nvoices(%d)\n", count, hdr.nvoices); return -EINVAL; @@ -926,7 +926,7 @@ int note, sample_id; int rc; - if (count < sizeof(patch)) { + if (count < (long)sizeof(patch)) { snd_printk("patch record too small %ld\n", count); return -EINVAL; } diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c --- a/sound/usb/usbaudio.c Sun Feb 9 21:13:34 2003 +++ b/sound/usb/usbaudio.c Sun Feb 9 21:13:34 2003 @@ -36,7 +36,7 @@ #include #include #include -#include +#include #define SNDRV_GET_ID #include @@ -89,6 +89,12 @@ /* + * debug the h/w constraints + */ +/* #define HW_CONST_DEBUG */ + + +/* * */ @@ -104,7 +110,7 @@ struct audioformat { struct list_head list; snd_pcm_format_t format; /* format type */ - int channels; /* # channels */ + unsigned int channels; /* # channels */ int iface; /* interface number */ unsigned char altsetting; /* corresponding alternate setting */ unsigned char altset_idx; /* array index of altenate setting */ @@ -112,9 +118,9 @@ unsigned char endpoint; /* endpoint */ unsigned char ep_attr; /* endpoint attributes */ unsigned int rates; /* rate bitmasks */ - int rate_min, rate_max; /* min/max rates */ - int nr_rates; /* number of rate table entries */ - int *rate_table; /* rate table */ + unsigned int rate_min, rate_max; /* min/max rates */ + unsigned int nr_rates; /* number of rate table entries */ + unsigned int *rate_table; /* rate table */ }; struct snd_urb_ctx { @@ -156,21 +162,21 @@ unsigned int running: 1; /* running status */ - int hwptr; /* free frame position in the buffer (only for playback) */ - int hwptr_done; /* processed frame position in the buffer */ - int transfer_sched; /* scheduled frames since last period (for playback) */ - int transfer_done; /* processed frames since last period update */ + unsigned int hwptr; /* free frame position in the buffer (only for playback) */ + unsigned int hwptr_done; /* processed frame position in the buffer */ + unsigned int transfer_sched; /* scheduled frames since last period (for playback) */ + unsigned int transfer_done; /* processed frames since last period update */ unsigned long active_mask; /* bitmask of active urbs */ unsigned long unlink_mask; /* bitmask of unlinked urbs */ - int nurbs; /* # urbs */ + unsigned int nurbs; /* # urbs */ snd_urb_ctx_t dataurb[MAX_URBS]; /* data urb table */ snd_urb_ctx_t syncurb[SYNC_URBS]; /* sync urb table */ char syncbuf[SYNC_URBS * NRPACKS * 3]; /* sync buffer; it's so small - let's get static */ char *tmpbuf; /* temporary buffer for playback */ u64 formats; /* format bitmasks (all or'ed) */ - int num_formats; /* number of supported audio formats (list) */ + unsigned int num_formats; /* number of supported audio formats (list) */ struct list_head fmt_list; /* format list */ spinlock_t lock; @@ -184,7 +190,6 @@ int pcm_index; snd_usb_substream_t substream[2]; struct list_head list; - snd_info_entry_t *proc_entry; }; #define chip_t snd_usb_stream_t @@ -309,7 +314,8 @@ { unsigned long flags; unsigned char *cp; - int stride, i, len, oldptr; + int i; + unsigned int stride, len, oldptr; stride = runtime->frame_bits >> 3; @@ -332,8 +338,8 @@ spin_unlock_irqrestore(&subs->lock, flags); /* copy a data chunk */ if (oldptr + len > runtime->buffer_size) { - int cnt = runtime->buffer_size - oldptr; - int blen = cnt * stride; + unsigned int cnt = runtime->buffer_size - oldptr; + unsigned int blen = cnt * stride; memcpy(runtime->dma_area + oldptr * stride, cp, blen); memcpy(runtime->dma_area, cp + blen, len * stride - blen); } else { @@ -384,7 +390,8 @@ snd_pcm_runtime_t *runtime, struct urb *urb) { - unsigned int f, i, found; + int i; + unsigned int f, found; unsigned char *cp = urb->transfer_buffer; unsigned long flags; @@ -424,7 +431,7 @@ struct urb *urb) { int i, stride, offs; - int counts; + unsigned int counts; unsigned long flags; snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; @@ -526,11 +533,7 @@ /* * complete callback from data urb */ -#ifndef OLD_USB static void snd_complete_urb(struct urb *urb, struct pt_regs *regs) -#else -static void snd_complete_urb(struct urb *urb) -#endif { snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; snd_usb_substream_t *subs = ctx->subs; @@ -542,7 +545,7 @@ return; if (! subs->running) /* can be stopped during retire callback */ return; - if ((err = subs->ops.prepare(subs, substream->runtime, urb) < 0) || + if ((err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 || (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err); snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); @@ -555,11 +558,7 @@ /* * complete callback from sync urb */ -#ifndef OLD_USB static void snd_complete_sync_urb(struct urb *urb, struct pt_regs *regs) -#else -static void snd_complete_sync_urb(struct urb *urb) -#endif { snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; snd_usb_substream_t *subs = ctx->subs; @@ -587,7 +586,8 @@ */ static int deactivate_urbs(snd_usb_substream_t *subs) { - int i, alive; + unsigned int i; + int alive; subs->running = 0; @@ -628,7 +628,8 @@ */ static int start_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime) { - int i, err; + unsigned int i; + int err; for (i = 0; i < subs->nurbs; i++) { snd_assert(subs->dataurb[i].urb, return -EINVAL); @@ -679,7 +680,8 @@ static int wait_clear_urbs(snd_usb_substream_t *subs) { int timeout = HZ; - int i, alive; + unsigned int i; + int alive; do { alive = 0; @@ -780,9 +782,9 @@ */ static int init_substream_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime) { - int maxsize, n, i; + unsigned int maxsize, n, i; int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; - int npacks[MAX_URBS], total_packs; + unsigned int npacks[MAX_URBS], total_packs; /* calculate the frequency in 10.14 format */ subs->freqn = subs->freqm = get_usb_rate(runtime->rate); @@ -881,7 +883,7 @@ u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS; u->urb->number_of_packets = u->packets; u->urb->context = u; - u->urb->complete = (usb_complete_t)snd_complete_urb; + u->urb->complete = snd_usb_complete_callback(snd_complete_urb); } if (subs->syncpipe) { @@ -903,7 +905,7 @@ u->urb->transfer_flags = URB_ISO_ASAP | UNLINK_FLAGS; u->urb->number_of_packets = u->packets; u->urb->context = u; - u->urb->complete = (usb_complete_t)snd_complete_sync_urb; + u->urb->complete = snd_usb_complete_callback(snd_complete_sync_urb); } } return 0; @@ -928,7 +930,7 @@ if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) return fp; else { - int i; + unsigned int i; for (i = 0; i < fp->nr_rates; i++) if (fp->rate_table[i] == runtime->rate) return fp; @@ -939,6 +941,70 @@ /* + * initialize the picth control and sample rate + */ +static int init_usb_pitch(struct usb_device *dev, int iface, + struct usb_host_interface *alts, + struct audioformat *fmt) +{ + unsigned int ep; + unsigned char data[1]; + int err; + + ep = get_endpoint(alts, 0)->bEndpointAddress; + /* if endpoint has pitch control, enable it */ + if (fmt->attributes & EP_CS_ATTR_PITCH_CONTROL) { + data[0] = 1; + if ((err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, + USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) { + snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n", + dev->devnum, iface, ep); + return err; + } + } + return 0; +} + +static int init_usb_sample_rate(struct usb_device *dev, int iface, + struct usb_host_interface *alts, + struct audioformat *fmt, int rate) +{ + unsigned int ep; + unsigned char data[3]; + int err; + + ep = get_endpoint(alts, 0)->bEndpointAddress; + /* if endpoint has sampling rate control, set it */ + if (fmt->attributes & EP_CS_ATTR_SAMPLE_RATE) { + int crate; + data[0] = rate; + data[1] = rate >> 8; + data[2] = rate >> 16; + if ((err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, + USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) { + snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep 0x%x\n", + dev->devnum, iface, fmt->altsetting, rate, ep); + return err; + } + if ((err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, + USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) { + snd_printk(KERN_ERR "%d:%d:%d: cannot get freq at ep 0x%x\n", + dev->devnum, iface, fmt->altsetting, ep); + return err; + } + crate = data[0] | (data[1] << 8) | (data[2] << 16); + if (crate != rate) { + snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate); + // runtime->rate = crate; + } + } + return 0; +} + +/* * find a matching format and set up the interface */ static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime) @@ -950,7 +1016,6 @@ struct usb_interface *iface; struct audioformat *fmt; unsigned int ep, attr; - unsigned char data[3]; int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; int err; @@ -1009,8 +1074,8 @@ return -EINVAL; } ep = get_endpoint(alts, 1)->bEndpointAddress; - if ((is_playback && ep != (get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) || - (! is_playback && ep != (get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN))) { + if ((is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) || + (! is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN))) { snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", dev->devnum, fmt->iface, fmt->altsetting); return -EINVAL; @@ -1023,44 +1088,11 @@ subs->syncinterval = get_endpoint(alts, 1)->bRefresh; } - ep = get_endpoint(alts, 0)->bEndpointAddress; - /* if endpoint has pitch control, enable it */ - if (fmt->attributes & EP_CS_ATTR_PITCH_CONTROL) { - data[0] = 1; - if ((err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, - USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, - PITCH_CONTROL << 8, ep, data, 1, HZ)) < 0) { - snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n", - dev->devnum, subs->interface, ep); - return err; - } - } - /* if endpoint has sampling rate control, set it */ - if (fmt->attributes & EP_CS_ATTR_SAMPLE_RATE) { - int crate; - data[0] = runtime->rate; - data[1] = runtime->rate >> 8; - data[2] = runtime->rate >> 16; - if ((err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, - USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, - SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) { - snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep 0x%x\n", - dev->devnum, subs->interface, fmt->altsetting, runtime->rate, ep); - return err; - } - if ((err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, - USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, - SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ)) < 0) { - snd_printk(KERN_ERR "%d:%d:%d: cannot get freq at ep 0x%x\n", - dev->devnum, subs->interface, fmt->altsetting, ep); - return err; - } - crate = data[0] | (data[1] << 8) | (data[2] << 16); - if (crate != runtime->rate) { - snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, runtime->rate); - // runtime->rate = crate; - } - } + if ((err = init_usb_pitch(dev, subs->interface, alts, fmt)) < 0 || + (err = init_usb_sample_rate(dev, subs->interface, alts, fmt, + runtime->rate)) < 0) + return err; + /* always fill max packet size */ if (fmt->attributes & EP_CS_ATTR_FILL_MAX) subs->fill_max = 1; @@ -1140,12 +1172,239 @@ }; /* + * h/w constraints + */ + +#ifdef HW_CONST_DEBUG +#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args) +#else +#define hwc_debug(fmt, args...) /**/ +#endif + +static int hw_check_valid_format(snd_pcm_hw_params_t *params, struct audioformat *fp) +{ + snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + snd_interval_t *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + snd_mask_t *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + + /* check the format */ + if (! snd_mask_test(fmts, fp->format)) { + printk(KERN_DEBUG " > check: no supported format %d\n", fp->format); + return 0; + } + /* check the channels */ + if (fp->channels < ct->min || fp->channels > ct->max) { + hwc_debug(" > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max); + return 0; + } + /* check the rate is within the range */ + if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) { + hwc_debug(" > check: rate_min %d > max %d\n", fp->rate_min, it->max); + return 0; + } + if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) { + hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min); + return 0; + } + return 1; +} + +static int hw_rule_rate(snd_pcm_hw_params_t *params, + snd_pcm_hw_rule_t *rule) +{ + snd_usb_substream_t *subs = rule->private; + struct list_head *p; + snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + unsigned int rmin, rmax; + int changed; + + hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max); + changed = 0; + rmin = rmax = 0; + list_for_each(p, &subs->fmt_list) { + struct audioformat *fp; + fp = list_entry(p, struct audioformat, list); + if (! hw_check_valid_format(params, fp)) + continue; + if (changed++) { + if (rmin > fp->rate_min) + rmin = fp->rate_min; + if (rmax < fp->rate_max) + rmax = fp->rate_max; + } else { + rmin = fp->rate_min; + rmax = fp->rate_max; + } + } + + if (! changed) { + hwc_debug(" --> get empty\n"); + it->empty = 1; + return -EINVAL; + } + + changed = 0; + if (it->min < rmin) { + it->min = rmin; + it->openmin = 0; + changed = 1; + } + if (it->max > rmax) { + it->max = rmax; + it->openmax = 0; + changed = 1; + } + if (snd_interval_checkempty(it)) { + it->empty = 1; + return -EINVAL; + } + hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed); + return changed; +} + + +static int hw_rule_channels(snd_pcm_hw_params_t *params, + snd_pcm_hw_rule_t *rule) +{ + snd_usb_substream_t *subs = rule->private; + struct list_head *p; + snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + unsigned int rmin, rmax; + int changed; + + hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max); + changed = 0; + rmin = rmax = 0; + list_for_each(p, &subs->fmt_list) { + struct audioformat *fp; + fp = list_entry(p, struct audioformat, list); + if (! hw_check_valid_format(params, fp)) + continue; + if (changed++) { + if (rmin > fp->channels) + rmin = fp->channels; + if (rmax < fp->channels) + rmax = fp->channels; + } else { + rmin = fp->channels; + rmax = fp->channels; + } + } + + if (! changed) { + hwc_debug(" --> get empty\n"); + it->empty = 1; + return -EINVAL; + } + + changed = 0; + if (it->min < rmin) { + it->min = rmin; + it->openmin = 0; + changed = 1; + } + if (it->max > rmax) { + it->max = rmax; + it->openmax = 0; + changed = 1; + } + if (snd_interval_checkempty(it)) { + it->empty = 1; + return -EINVAL; + } + hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed); + return changed; +} + +static int hw_rule_format(snd_pcm_hw_params_t *params, + snd_pcm_hw_rule_t *rule) +{ + snd_usb_substream_t *subs = rule->private; + struct list_head *p; + snd_mask_t *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + u64 fbits; + u32 oldbits[2]; + int changed; + + hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]); + fbits = 0; + list_for_each(p, &subs->fmt_list) { + struct audioformat *fp; + fp = list_entry(p, struct audioformat, list); + if (! hw_check_valid_format(params, fp)) + continue; + fbits |= (1UL << fp->format); + } + + oldbits[0] = fmt->bits[0]; + oldbits[1] = fmt->bits[1]; + fmt->bits[0] &= (u32)fbits; + fmt->bits[1] &= (u32)(fbits >> 32); + if (! fmt->bits[0] && ! fmt->bits[1]) { + hwc_debug(" --> get empty\n"); + return -EINVAL; + } + changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]); + hwc_debug(" --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed); + return changed; +} + +/* + * check whether the registered audio formats need special hw-constraints + */ +static int check_hw_params_convention(snd_usb_substream_t *subs) +{ + int i; + u32 channels[64]; + u32 rates[64]; + u32 cmaster, rmaster; + struct list_head *p; + + memset(channels, 0, sizeof(channels)); + memset(rates, 0, sizeof(rates)); + + list_for_each(p, &subs->fmt_list) { + struct audioformat *f; + f = list_entry(p, struct audioformat, list); + /* unconventional channels? */ + if (f->channels > 32) + return 1; + /* combination of continuous rates and fixed rates? */ + if (rates[f->format] & SNDRV_PCM_RATE_CONTINUOUS) { + if (f->rates != rates[f->format]) + return 1; + } + if (f->rates & SNDRV_PCM_RATE_CONTINUOUS) { + if (rates[f->format] && rates[f->format] != f->rates) + return 1; + } + channels[f->format] |= (1 << f->channels); + rates[f->format] |= f->rates; + } + /* check whether channels and rates match for all formats */ + cmaster = rmaster = 0; + for (i = 0; i < 64; i++) { + if (cmaster != channels[i] && cmaster && channels[i]) + return 1; + if (rmaster != rates[i] && rmaster && rates[i]) + return 1; + if (channels[i]) + cmaster = channels[i]; + if (rates[i]) + rmaster = rates[i]; + } + return 0; +} + + +/* * set up the runtime hardware information. */ -static void setup_hw_info(snd_pcm_runtime_t *runtime, snd_usb_substream_t *subs) +static int setup_hw_info(snd_pcm_runtime_t *runtime, snd_usb_substream_t *subs) { struct list_head *p; + int err; runtime->hw.formats = subs->formats; @@ -1174,9 +1433,28 @@ 1000 * MIN_PACKS_URB, /*(NRPACKS * MAX_URBS) * 1000*/ UINT_MAX); - /* FIXME: we need more constraints to restrict the format type, - * channels and rates according to the audioformat list! - */ + if (check_hw_params_convention(subs)) { + hwc_debug("setting extra hw constraints...\n"); + if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + hw_rule_rate, subs, + SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_HW_PARAM_CHANNELS, + -1)) < 0) + return err; + if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + hw_rule_channels, subs, + SNDRV_PCM_HW_PARAM_FORMAT, + SNDRV_PCM_HW_PARAM_RATE, + -1)) < 0) + return err; + if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, + hw_rule_format, subs, + SNDRV_PCM_HW_PARAM_RATE, + SNDRV_PCM_HW_PARAM_CHANNELS, + -1)) < 0) + return err; + } + return 0; } static int snd_usb_pcm_open(snd_pcm_substream_t *substream, int direction, @@ -1191,8 +1469,7 @@ runtime->hw = *hw; runtime->private_data = subs; subs->pcm_substream = substream; - setup_hw_info(runtime, subs); - return 0; + return setup_hw_info(runtime, subs); } static int snd_usb_pcm_close(snd_pcm_substream_t *substream, int direction) @@ -1325,11 +1602,7 @@ * entry point for linux usb interface */ -#ifdef OLD_USB -static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id); -static void usb_audio_disconnect(struct usb_device *dev, void *ptr); -#else +#ifndef OLD_USB static int usb_audio_probe(struct usb_interface *intf, const struct usb_device_id *id); static void usb_audio_disconnect(struct usb_interface *intf); @@ -1381,7 +1654,7 @@ snd_iprintf(buffer, " Rates: %d - %d (continous)\n", fp->rate_min, fp->rate_max); } else { - int i; + unsigned int i; snd_iprintf(buffer, " Rates: "); for (i = 0; i < fp->nr_rates; i++) { if (i > 0) @@ -1396,7 +1669,7 @@ static void proc_dump_substream_status(snd_usb_substream_t *subs, snd_info_buffer_t *buffer) { if (subs->running) { - int i; + unsigned int i; snd_iprintf(buffer, " Status: Running\n"); snd_iprintf(buffer, " Interface = %d\n", subs->interface); snd_iprintf(buffer, " Altset = %d\n", subs->format); @@ -1438,18 +1711,8 @@ snd_card_t *card = stream->chip->card; sprintf(name, "stream%d", stream->pcm_index); - if ((entry = snd_info_create_card_entry(card, name, card->proc_root)) != NULL) { - entry->content = SNDRV_INFO_CONTENT_TEXT; - entry->private_data = stream; - entry->mode = S_IFREG | S_IRUGO | S_IWUSR; - entry->c.text.read_size = 4096; - entry->c.text.read = proc_pcm_format_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - } - stream->proc_entry = entry; + if (! snd_card_proc_new(card, name, &entry)) + snd_info_set_text_ops(entry, stream, proc_pcm_format_read); } @@ -1504,10 +1767,6 @@ */ static void snd_usb_audio_stream_free(snd_usb_stream_t *stream) { - if (stream->proc_entry) { - snd_info_unregister(stream->proc_entry); - stream->proc_entry = NULL; - } free_substream(&stream->substream[0]); free_substream(&stream->substream[1]); list_del(&stream->list); @@ -1793,7 +2052,7 @@ */ int r, idx, c; /* this table corresponds to the SNDRV_PCM_RATE_XXX bit */ - static int conv_rates[] = { + static unsigned int conv_rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000 }; @@ -1807,7 +2066,7 @@ fp->nr_rates = nr_rates; fp->rate_min = fp->rate_max = combine_triple(&fmt[8]); for (r = 0, idx = 8; r < nr_rates; r++, idx += 3) { - int rate = fp->rate_table[r] = combine_triple(&fmt[idx]); + unsigned int rate = fp->rate_table[r] = combine_triple(&fmt[idx]); if (rate < fp->rate_min) fp->rate_min = rate; else if (rate > fp->rate_max) @@ -1820,7 +2079,7 @@ } #if 0 // FIXME - we need to define constraint if (c >= 13) - fp->rates |= SNDRV_PCM_KNOT; /* unconventional rate */ + fp->rates |= SNDRV_PCM_RATE_KNOT; /* unconventional rate */ #endif } @@ -1840,6 +2099,10 @@ kfree(fp); return err; } + /* try to set the interface... */ + usb_set_interface(chip->dev, iface_no, i); + init_usb_pitch(chip->dev, iface_no, alts, fp); + init_usb_sample_rate(chip->dev, iface_no, alts, fp, fp->rate_max); } return 0; } @@ -1893,7 +2156,7 @@ snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j); continue; } - usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1); + usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); continue; } if (altsd->bInterfaceClass != USB_CLASS_AUDIO || @@ -1902,84 +2165,73 @@ /* skip non-supported classes */ continue; } - parse_audio_endpoints(chip, buffer, buflen, j); - usb_set_interface(dev, j, 0); /* reset the current interface */ - usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1); + if (! parse_audio_endpoints(chip, buffer, buflen, j)) { + usb_set_interface(dev, j, 0); /* reset the current interface */ + usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); + } } return 0; } -static int snd_usb_roland_ua100_hack_intf(snd_usb_audio_t *chip, int ifnum) +/* + * create a stream for an endpoint/altsetting without proper descriptors + */ +static int create_fixed_stream_quirk(snd_usb_audio_t *chip, + struct usb_interface *iface, + const snd_usb_audio_quirk_t *quirk) { struct audioformat *fp; - int err; + struct usb_host_interface *alts; + int stream, err; fp = kmalloc(sizeof(*fp), GFP_KERNEL); if (! fp) { snd_printk(KERN_ERR "cannot malloc\n"); return -ENOMEM; } - memset(fp, 0, sizeof(*fp)); - fp->format = SNDRV_PCM_FORMAT_S16_LE; - fp->channels = ifnum == 0 ? 4 : 2; - fp->iface = ifnum; - fp->altsetting = 1; - fp->altset_idx = 1; - fp->attributes = ifnum == 0 ? 0 : EP_CS_ATTR_FILL_MAX; - fp->endpoint = ifnum == 0 ? 0x01 : 0x81; - fp->ep_attr = ifnum == 0 ? 0x09 : 0x05; - fp->rates = SNDRV_PCM_RATE_CONTINUOUS; - fp->rate_min = fp->rate_max = 44100; - - err = add_audio_endpoint(chip, ifnum == 0 ? SNDRV_PCM_STREAM_PLAYBACK - : SNDRV_PCM_STREAM_CAPTURE, fp); + memcpy(fp, quirk->data, sizeof(*fp)); + stream = (fp->endpoint & USB_DIR_IN) + ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; + err = add_audio_endpoint(chip, stream, fp); if (err < 0) { kfree(fp); return err; } - usb_set_interface(chip->dev, ifnum, 0); + alts = &iface->altsetting[fp->altset_idx]; + usb_set_interface(chip->dev, fp->iface, 0); + init_usb_pitch(chip->dev, fp->iface, alts, fp); + init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max); return 0; } -static int snd_usb_roland_ua100_hack(snd_usb_audio_t *chip) +static int snd_usb_create_quirk(snd_usb_audio_t *chip, + struct usb_interface *iface, + const snd_usb_audio_quirk_t *quirk); + +/* + * handle the quirks for the contained interfaces + */ +static int create_composite_quirk(snd_usb_audio_t *chip, + struct usb_interface *iface, + const snd_usb_audio_quirk_t *quirk) { - static const snd_usb_midi_endpoint_info_t ep_quirk = { - .epnum = -1, - .out_cables = 0x0007, - .in_cables = 0x0007 - }; - static const snd_usb_audio_quirk_t midi_quirk = { - .vendor_name = "Roland", - .product_name = "UA-100", - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = &ep_quirk - }; - struct usb_host_config *cfg = chip->dev->actconfig; - struct usb_interface *iface; + struct usb_host_config *config = chip->dev->actconfig; + int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber; int err; - if (get_cfg_desc(cfg)->bNumInterfaces != 3) { - snd_printdd(KERN_ERR "invalid UA-100 descriptor\n"); - return -ENXIO; - } - /* if 0: output */ - if ((err = snd_usb_roland_ua100_hack_intf(chip, 0)) < 0) - return err; - /* if 1: input */ - iface = &cfg->interface[1]; - if (! usb_interface_claimed(iface)) { - if ((err = snd_usb_roland_ua100_hack_intf(chip, 1)) < 0) - return err; - usb_driver_claim_interface(&usb_audio_driver, iface, (void*)-1); - } - /* if 2: MIDI */ - iface = &cfg->interface[2]; - if (! usb_interface_claimed(iface)) { - if ((err = snd_usb_create_midi_interface(chip, iface, &midi_quirk)) < 0) + for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) { + if (quirk->ifnum >= get_cfg_desc(config)->bNumInterfaces) + continue; + iface = &config->interface[quirk->ifnum]; + if (quirk->ifnum != probed_ifnum && + usb_interface_claimed(iface)) + continue; + err = snd_usb_create_quirk(chip, iface, quirk); + if (err < 0) return err; - usb_driver_claim_interface(&usb_audio_driver, iface, (void*)-1); + if (quirk->ifnum != probed_ifnum) + usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); } return 0; } @@ -1993,8 +2245,10 @@ case QUIRK_MIDI_YAMAHA: case QUIRK_MIDI_MIDIMAN: return snd_usb_create_midi_interface(chip, iface, quirk); - case QUIRK_ROLAND_UA100: - return snd_usb_roland_ua100_hack(chip); + case QUIRK_COMPOSITE: + return create_composite_quirk(chip, iface, quirk); + case QUIRK_AUDIO_FIXED_ENDPOINT: + return create_fixed_stream_quirk(chip, iface, quirk); default: snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); return -ENXIO; @@ -2046,6 +2300,7 @@ chip->dev = dev; chip->card = card; INIT_LIST_HEAD(&chip->pcm_list); + INIT_LIST_HEAD(&chip->midi_list); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { snd_usb_audio_free(chip); @@ -2097,6 +2352,13 @@ strncpy(card->longname + len, quirk->product_name, sizeof(card->longname) - len - 1); card->longname[sizeof(card->longname) - 1] = '\0'; } + /* add device path to longname */ + len = strlen(card->longname); + if (sizeof(card->longname) - len > 10) { + strcpy(card->longname + len, " at "); + len += 4; + usb_make_path(dev, card->longname + len, sizeof(card->longname) - len); + } *rchip = chip; return 0; @@ -2265,7 +2527,7 @@ snd_card_t *card; struct list_head *p; - if (ptr == (void *)-1) + if (ptr == (void *)-1L) return; chip = snd_magic_cast(snd_usb_audio_t, ptr, return); @@ -2288,6 +2550,10 @@ release_substream_urbs(subs); } } + /* release the midi resources */ + list_for_each(p, &chip->midi_list) { + snd_usbmidi_disconnect(p); + } up(®ister_mutex); snd_card_free_in_thread(card); } else { @@ -2295,25 +2561,7 @@ } } - -#ifdef OLD_USB - -/* - * 2.4 USB kernel API - */ -static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) -{ - return snd_usb_audio_probe(dev, usb_ifnum_to_if(dev, ifnum), id); -} - -static void usb_audio_disconnect(struct usb_device *dev, void *ptr) -{ - snd_usb_audio_disconnect(dev, ptr); -} - -#else - +#ifndef OLD_USB /* * new 2.5 USB kernel API */ @@ -2323,7 +2571,7 @@ void *chip; chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id); if (chip) { - usb_set_intfdata(intf, chip); + dev_set_drvdata(&intf->dev, chip); return 0; } else return -EIO; @@ -2332,7 +2580,7 @@ static void usb_audio_disconnect(struct usb_interface *intf) { snd_usb_audio_disconnect(interface_to_usbdev(intf), - usb_get_intfdata(intf)); + dev_get_drvdata(&intf->dev)); } #endif diff -Nru a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h --- a/sound/usb/usbaudio.h Sun Feb 9 21:13:33 2003 +++ b/sound/usb/usbaudio.h Sun Feb 9 21:13:33 2003 @@ -139,6 +139,7 @@ struct list_head pcm_list; /* list of pcm streams */ int pcm_devs; + struct list_head midi_list; /* list of midi interfaces */ int next_midi_device; }; @@ -150,7 +151,8 @@ #define QUIRK_MIDI_FIXED_ENDPOINT 0 #define QUIRK_MIDI_YAMAHA 1 #define QUIRK_MIDI_MIDIMAN 2 -#define QUIRK_ROLAND_UA100 3 +#define QUIRK_COMPOSITE 3 +#define QUIRK_AUDIO_FIXED_ENDPOINT 4 typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t; typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t; @@ -165,7 +167,7 @@ /* data for QUIRK_MIDI_FIXED_ENDPOINT */ struct snd_usb_midi_endpoint_info { - int16_t epnum; /* ep number, -1 autodetect */ + int8_t out_ep, in_ep; /* ep number, 0 autodetect */ uint16_t out_cables; /* bitmask */ uint16_t in_cables; /* bitmask */ }; @@ -175,7 +177,10 @@ /* for QUIRK_MIDI_MIDIMAN, data points to a snd_usb_midi_endpoint_info * structure (out_cables and in_cables only) */ -/* for QUIRK_ROLAND_UA100, data is NULL */ +/* for QUIRK_COMPOSITE, data points to an array of snd_usb_audio_quirk + * structures, terminated with .ifnum = -1 */ + +/* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */ /* */ @@ -192,6 +197,7 @@ int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif, unsigned char *buffer, int buflen); int snd_usb_create_midi_interface(snd_usb_audio_t *chip, struct usb_interface *iface, const snd_usb_audio_quirk_t *quirk); +void snd_usbmidi_disconnect(struct list_head *p); /* * retrieve usb_interface descriptor from the host interface @@ -206,6 +212,10 @@ #ifndef usb_pipe_needs_resubmit #define usb_pipe_needs_resubmit(pipe) 1 +#endif + +#ifndef snd_usb_complete_callback +#define snd_usb_complete_callback(x) (x) #endif #endif /* __USBAUDIO_H */ diff -Nru a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c --- a/sound/usb/usbmidi.c Sun Feb 9 21:13:35 2003 +++ b/sound/usb/usbmidi.c Sun Feb 9 21:13:35 2003 @@ -77,6 +77,7 @@ struct usb_interface *iface; const snd_usb_audio_quirk_t *quirk; snd_rawmidi_t* rmidi; + struct list_head list; struct snd_usb_midi_endpoint { snd_usb_midi_out_endpoint_t *out; @@ -172,11 +173,7 @@ /* * Processes the data read from the device. */ -#ifndef OLD_USB static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs) -#else -static void snd_usbmidi_in_urb_complete(struct urb* urb) -#endif { snd_usb_midi_in_endpoint_t* ep = snd_magic_cast(snd_usb_midi_in_endpoint_t, urb->context, return); @@ -201,11 +198,7 @@ /* * Converts the data read from a Midiman device to standard USB MIDI packets. */ -#ifndef OLD_USB static void snd_usbmidi_in_midiman_complete(struct urb* urb, struct pt_regs *regs) -#else -static void snd_usbmidi_in_midiman_complete(struct urb* urb) -#endif { if (urb->status == 0) { uint8_t* buffer = (uint8_t*)urb->transfer_buffer; @@ -231,18 +224,10 @@ } } } -#ifndef OLD_USB snd_usbmidi_in_urb_complete(urb, regs); -#else - snd_usbmidi_in_urb_complete(urb); -#endif } -#ifndef OLD_USB static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs) -#else -static void snd_usbmidi_out_urb_complete(struct urb* urb) -#endif { snd_usb_midi_out_endpoint_t* ep = snd_magic_cast(snd_usb_midi_out_endpoint_t, urb->context, return); @@ -410,7 +395,7 @@ unsigned long flags; spin_lock_irqsave(&ep->buffer_lock, flags); - if (urb->status == -EINPROGRESS) { + if (urb->status == -EINPROGRESS || ep->umidi->chip->shutdown) { spin_unlock_irqrestore(&ep->buffer_lock, flags); return; } @@ -467,10 +452,8 @@ usbmidi_out_port_t* port = (usbmidi_out_port_t*)substream->runtime->private_data; port->active = up; - if (up) { - if (! port->ep->umidi->chip->shutdown) /* to be sure... */ - tasklet_hi_schedule(&port->ep->tasklet); - } + if (up) + tasklet_hi_schedule(&port->ep->tasklet); } static int snd_usbmidi_input_open(snd_rawmidi_substream_t* substream) @@ -506,11 +489,8 @@ static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep) { if (ep->urb) { - if (ep->urb->transfer_buffer) { - if (! ep->umidi->chip->shutdown) /* to be sure */ - usb_unlink_urb(ep->urb); + if (ep->urb->transfer_buffer) kfree(ep->urb->transfer_buffer); - } usb_free_urb(ep->urb); } snd_magic_kfree(ep); @@ -595,9 +575,9 @@ return -ENOMEM; } if (int_epd) - pipe = usb_rcvintpipe(umidi->chip->dev, ep_info->epnum); + pipe = usb_rcvintpipe(umidi->chip->dev, ep_info->in_ep); else - pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->epnum); + pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep); length = usb_maxpacket(umidi->chip->dev, pipe, 0); buffer = kmalloc(length, GFP_KERNEL); if (!buffer) { @@ -606,11 +586,11 @@ } if (int_epd) usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, - (usb_complete_t)snd_usbmidi_in_urb_complete, + snd_usb_complete_callback(snd_usbmidi_in_urb_complete), ep, int_epd->bInterval); else usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, - (usb_complete_t)snd_usbmidi_in_urb_complete, + snd_usb_complete_callback(snd_usbmidi_in_urb_complete), ep); rep->in = ep; @@ -635,11 +615,8 @@ if (ep->tasklet.func) tasklet_kill(&ep->tasklet); if (ep->urb) { - if (ep->urb->transfer_buffer) { - if (! ep->umidi->chip->shutdown) /* to be sure */ - usb_unlink_urb(ep->urb); + if (ep->urb->transfer_buffer) kfree(ep->urb->transfer_buffer); - } usb_free_urb(ep->urb); } snd_magic_kfree(ep); @@ -668,7 +645,7 @@ snd_usbmidi_out_endpoint_delete(ep); return -ENOMEM; } - pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->epnum); + pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1) & ~3; buffer = kmalloc(ep->max_transfer, GFP_KERNEL); if (!buffer) { @@ -677,7 +654,7 @@ } usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, ep->max_transfer, - (usb_complete_t)snd_usbmidi_out_urb_complete, ep); + snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep); spin_lock_init(&ep->buffer_lock); tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep); @@ -709,6 +686,24 @@ snd_magic_kfree(umidi); } +/* + * Unlinks all URBs (must be done before the usb_device is deleted). + */ +void snd_usbmidi_disconnect(struct list_head* p) +{ + snd_usb_midi_t* umidi; + int i; + + umidi = list_entry(p, snd_usb_midi_t, list); + for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { + snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i]; + if (ep->out && ep->out->urb) + usb_unlink_urb(ep->out->urb); + if (ep->in && ep->in->urb) + usb_unlink_urb(ep->in->urb); + } +} + static void snd_usbmidi_rawmidi_free(snd_rawmidi_t* rmidi) { snd_usb_midi_t* umidi = snd_magic_cast(snd_usb_midi_t, rmidi->private_data, return); @@ -753,8 +748,6 @@ int out_ports = 0, in_ports = 0; for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { - if (!endpoints[i].epnum) - continue; if (endpoints[i].out_cables) { err = snd_usbmidi_out_endpoint_create(umidi, &endpoints[i], &umidi->endpoints[i]); @@ -828,50 +821,64 @@ ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT || ms_ep->bDescriptorSubtype != MS_GENERAL) continue; - if (endpoints[epidx].epnum != 0 && - endpoints[epidx].epnum != (ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) { - ++epidx; - if (epidx >= MIDI_MAX_ENDPOINTS) { - printk(KERN_WARNING "snd-usb-midi: too many endpoints\n"); - break; + if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { + if (endpoints[epidx].out_ep) { + if (++epidx >= MIDI_MAX_ENDPOINTS) { + printk(KERN_WARNING "snd-usb-midi: too many endpoints\n"); + break; + } } - } - endpoints[epidx].epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - if (ep->bEndpointAddress & USB_DIR_IN) { - endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; - } else { + endpoints[epidx].out_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; + printk(KERN_INFO "snd-usb-midi: EP %02X: %d jack(s)\n", + ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack); + } else { + if (endpoints[epidx].in_ep) { + if (++epidx >= MIDI_MAX_ENDPOINTS) { + printk(KERN_WARNING "snd-usb-midi: too many endpoints\n"); + break; + } + } + endpoints[epidx].in_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; + printk(KERN_INFO "snd-usb-midi: EP %02X: %d jack(s)\n", + ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack); } - printk(KERN_INFO "snd-usb-midi: detected %d %s jack(s) on endpoint %d\n", - ms_ep->bNumEmbMIDIJack, - ep->bEndpointAddress & USB_DIR_IN ? "input" : "output", - endpoints[epidx].epnum); } return 0; } /* - * If the first endpoint isn't specified, use the first endpoint in the + * If the endpoints aren't specified, use the first bulk endpoints in the * first alternate setting of the interface. */ static int snd_usbmidi_detect_endpoint(snd_usb_midi_t* umidi, - snd_usb_midi_endpoint_info_t* endpoint) + snd_usb_midi_endpoint_info_t* endpoint) { struct usb_interface* intf; struct usb_host_interface *hostif; struct usb_interface_descriptor* intfd; struct usb_endpoint_descriptor* epd; + int i; + + intf = umidi->iface; + if (!intf || intf->num_altsetting < 1) + return -ENOENT; + hostif = intf->altsetting; + intfd = get_iface_desc(hostif); + if (intfd->bNumEndpoints < 1) + return -ENOENT; - if (endpoint->epnum == -1) { - intf = umidi->iface; - if (!intf || intf->num_altsetting < 1) - return -ENOENT; - hostif = intf->altsetting; - intfd = get_iface_desc(hostif); - if (intfd->bNumEndpoints < 1) - return -ENOENT; - epd = get_endpoint(hostif, 0); - endpoint->epnum = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + for (i = 0; i < intfd->bNumEndpoints; ++i) { + epd = get_endpoint(hostif, i); + if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) + continue; + if (!endpoint->out_ep && endpoint->out_cables && + (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) + endpoint->out_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + if (!endpoint->in_ep && endpoint->in_cables && + (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) + endpoint->in_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; } return 0; } @@ -908,7 +915,6 @@ if (!endpoint->in_cables && !endpoint->out_cables) return -ENOENT; - endpoint->epnum = -1; return snd_usbmidi_detect_endpoint(umidi, endpoint); } @@ -956,21 +962,21 @@ } } - ep_info.epnum = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; ep_info.out_cables = endpoint->out_cables & 0x5555; err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); if (err < 0) return err; - ep_info.epnum = get_endpoint(hostif, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_info.in_ep = get_endpoint(hostif, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; ep_info.in_cables = endpoint->in_cables; err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); if (err < 0) return err; - umidi->endpoints[0].in->urb->complete = (usb_complete_t)snd_usbmidi_in_midiman_complete; + umidi->endpoints[0].in->urb->complete = snd_usb_complete_callback(snd_usbmidi_in_midiman_complete); if (endpoint->out_cables > 0x0001) { - ep_info.epnum = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_info.out_ep = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; ep_info.out_cables = endpoint->out_cables & 0xaaaa; err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[1]); if (err < 0) @@ -999,7 +1005,7 @@ out_ports, in_ports, &rmidi); if (err < 0) return err; - strcpy(rmidi->name, umidi->chip->card->longname); + strcpy(rmidi->name, umidi->chip->card->shortname); rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; @@ -1083,6 +1089,8 @@ snd_usbmidi_free(umidi); return err; } + + list_add(&umidi->list, &umidi->chip->midi_list); for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) if (umidi->endpoints[i].in) diff -Nru a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c --- a/sound/usb/usbmixer.c Sun Feb 9 21:13:30 2003 +++ b/sound/usb/usbmixer.c Sun Feb 9 21:13:30 2003 @@ -751,7 +751,8 @@ unsigned int ctl_mask, int control, usb_audio_term_t *iterm, int unitid) { - int len = 0, mapped_name = 0; + unsigned int len = 0; + int mapped_name = 0; int nameid = desc[desc[0] - 1]; snd_kcontrol_t *kctl; usb_mixer_elem_info_t *cval; @@ -927,9 +928,9 @@ int in_ch, int unitid) { usb_mixer_elem_info_t *cval; - int num_ins = desc[4]; - int num_outs = desc[5 + num_ins]; - int i, len; + unsigned int num_ins = desc[4]; + unsigned int num_outs = desc[5 + num_ins]; + unsigned int i, len; snd_kcontrol_t *kctl; usb_audio_term_t iterm; @@ -1240,7 +1241,7 @@ uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = cval->max; - if (uinfo->value.enumerated.item >= cval->max) + if ((int)uinfo->value.enumerated.item >= cval->max) uinfo->value.enumerated.item = cval->max - 1; strcpy(uinfo->value.enumerated.name, itemlist[uinfo->value.enumerated.item]); return 0; @@ -1325,8 +1326,9 @@ */ static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned char *desc) { - int num_ins = desc[4]; - int i, err, nameid, len; + unsigned int num_ins = desc[4]; + unsigned int i, nameid, len; + int err; usb_mixer_elem_info_t *cval; snd_kcontrol_t *kctl; char **namelist; diff -Nru a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h --- a/sound/usb/usbquirks.h Sun Feb 9 21:13:31 2003 +++ b/sound/usb/usbquirks.h Sun Feb 9 21:13:31 2003 @@ -162,6 +162,15 @@ } }, { + USB_DEVICE(0x0499, 0x1011), + .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { + .vendor_name = "Yamaha", + .product_name = "P-250", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_MIDI_YAMAHA + } +}, +{ USB_DEVICE(0x0499, 0x1012), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "Yamaha", @@ -233,8 +242,55 @@ .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "Roland", .product_name = "UA-100", - .ifnum = 0, - .type = QUIRK_ROLAND_UA100 + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = & (const snd_usb_audio_quirk_t[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = & (const struct audioformat) { + .format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 4, + .iface = 0, + .altsetting = 1, + .altset_idx = 1, + .attributes = 0, + .endpoint = 0x01, + .ep_attr = 0x09, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 44100, + .rate_max = 44100, + } + }, + { + .ifnum = 1, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = & (const struct audioformat) { + .format = SNDRV_PCM_FORMAT_S16_LE, + .channels = 2, + .iface = 1, + .altsetting = 1, + .altset_idx = 1, + .attributes = EP_CS_ATTR_FILL_MAX, + .endpoint = 0x81, + .ep_attr = 0x05, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 44100, + .rate_max = 44100, + } + }, + { + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0007, + .in_cables = 0x0007 + } + }, + { + .ifnum = -1 + } + } } }, { @@ -245,7 +301,6 @@ .ifnum = 2, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x000f, .in_cables = 0x000f } @@ -259,7 +314,6 @@ .ifnum = 2, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x003f, .in_cables = 0x003f } @@ -273,7 +327,6 @@ .ifnum = 2, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x0003, .in_cables = 0x0003 } @@ -287,7 +340,6 @@ .ifnum = 2, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x0003, .in_cables = 0x0003 } @@ -301,7 +353,6 @@ .ifnum = 2, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x0013, .in_cables = 0x0013 } @@ -315,7 +366,6 @@ .ifnum = 2, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x0001, .in_cables = 0x0001 } @@ -329,7 +379,6 @@ .ifnum = 2, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x0001, .in_cables = 0x0001 } @@ -343,23 +392,65 @@ .ifnum = 2, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x0013, .in_cables = 0x0013 } } }, { + /* thanks to Emiliano Grilli for helping researching this data */ USB_DEVICE(0x0582, 0x000c), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "Roland", .product_name = "SC-D70", - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, - .out_cables = 0x0007, - .in_cables = 0x0007 + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = & (const snd_usb_audio_quirk_t[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = & (const struct audioformat) { + .format = SNDRV_PCM_FORMAT_S24_3LE, + .channels = 2, + .iface = 0, + .altsetting = 1, + .altset_idx = 1, + .attributes = 0, + .endpoint = 0x01, + .ep_attr = 0x01, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 44100, + .rate_max = 44100, + } + }, + { + .ifnum = 1, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = & (const struct audioformat) { + .format = SNDRV_PCM_FORMAT_S24_3LE, + .channels = 2, + .iface = 1, + .altsetting = 1, + .altset_idx = 1, + .attributes = 0, + .endpoint = 0x81, + .ep_attr = 0x01, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 44100, + .rate_max = 44100, + } + }, + { + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0007, + .in_cables = 0x0007 + } + }, + { + .ifnum = -1 + } } } }, @@ -371,7 +462,6 @@ .ifnum = 0, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x0001, .in_cables = 0x0001 } @@ -385,7 +475,6 @@ .ifnum = 0, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x01ff, .in_cables = 0x01ff } @@ -399,7 +488,6 @@ .ifnum = 2, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x000f, .in_cables = 0x000f } @@ -413,7 +501,6 @@ .ifnum = 0, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x003f, .in_cables = 0x003f } @@ -427,7 +514,6 @@ .ifnum = 3, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x0001, .in_cables = 0x0001 } @@ -441,7 +527,6 @@ .ifnum = 0, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x0003, .in_cables = 0x0007 } @@ -455,7 +540,6 @@ .ifnum = 0, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x000f, .in_cables = 0x000f } @@ -469,13 +553,25 @@ .ifnum = 3, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x0003, .in_cables = 0x0003 } } }, { + USB_DEVICE(0x0582, 0x002d), + .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { + .vendor_name = "Roland", + .product_name = "XV-2020", + .ifnum = 0, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const snd_usb_midi_endpoint_info_t) { + .out_cables = 0x0001, + .in_cables = 0x0001 + } + } +}, +{ USB_DEVICE(0x0582, 0x0033), .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { .vendor_name = "EDIROL", @@ -483,7 +579,6 @@ .ifnum = 0, .type = QUIRK_MIDI_FIXED_ENDPOINT, .data = & (const snd_usb_midi_endpoint_info_t) { - .epnum = -1, .out_cables = 0x0003, .in_cables = 0x0007 }